#include <stdio.h>
#include <mpi.h>


int main(int argc, char **argv)
{
  MPI_Init(&argc, &argv);

  int rank, size;
  MPI_Comm_size(MPI_COMM_WORLD, &size);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

  MPI_Win win;
  int *baseptr;
  MPI_Win_allocate(2*size*sizeof(int), sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &baseptr, &win);

  MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);


  MPI_Win_lock_all(0, win);

  int val1, val2, flag = 0, ret;
  MPI_Request req[2];
  MPI_Rget(&val1, 1, MPI_INT, 0, 0, 1, MPI_INT, win, &req[0]);
  MPI_Rget(&val2, 1, MPI_INT, 0, 1, 1, MPI_INT, win, &req[1]);

  while(1) {
    MPI_Status stat[2];
    if ((ret = MPI_Testall(2, req, &flag, stat)) != MPI_SUCCESS) {
      char buf[MPI_MAX_ERROR_STRING];
      int len = MPI_MAX_ERROR_STRING;
      MPI_Error_string(ret, buf, &len);
      printf("[%d] MPI_Testall failed: \n\t%s (%d)\n", rank, buf, ret);
      len = MPI_MAX_ERROR_STRING;
      MPI_Error_string(stat[0].MPI_ERROR, buf, &len);
      printf("[%d]\tRequest error: %s (%d)\n", rank, buf, stat[0].MPI_ERROR);
      len = MPI_MAX_ERROR_STRING;
      MPI_Error_string(stat[1].MPI_ERROR, buf, &len);
      printf("[%d]\tRequest error: %s (%d)\n", rank, buf, stat[1].MPI_ERROR);
      MPI_Abort(MPI_COMM_WORLD, ret);
    }

    if (flag) break;
  }

  printf("[%d] Done waiting.\n", rank);


  MPI_Barrier(MPI_COMM_WORLD);
  MPI_Win_unlock_all(win);
  MPI_Win_free(&win);
  MPI_Finalize();

}

