/*@ MPI_Comm_join - Create a communicator by joining two processes connected by a socket. Input Parameter: . fd - socket file descriptor Output Parameter: . intercomm - new intercommunicator (handle) Notes: The socket must be quiescent before 'MPI_COMM_JOIN' is called and after 'MPI_COMM_JOIN' returns. More specifically, on entry to 'MPI_COMM_JOIN', a read on the socket will not read any data that was written to the socket before the remote process called 'MPI_COMM_JOIN'. .N ThreadSafe .N Fortran .N Errors .N MPI_SUCCESS .N MPI_ERR_ARG @*/ int MPI_Comm_join(int fd, MPI_Comm *intercomm) { static const char FCNAME[] = "MPI_Comm_join"; int mpi_errno = MPI_SUCCESS, err; MPID_Comm *intercomm_ptr; char *local_port, *remote_port; MPIU_CHKLMEM_DECL(2); MPID_MPI_STATE_DECL(MPID_STATE_MPI_COMM_JOIN); MPIR_ERRTEST_INITIALIZED_ORDIE(); MPIU_THREAD_CS_ENTER(ALLFUNC,); MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_COMM_JOIN); /* ... body of routine ... */ MPIU_CHKLMEM_MALLOC(local_port, char *, MPI_MAX_PORT_NAME, mpi_errno, "local port name"); MPIU_CHKLMEM_MALLOC(remote_port, char *, MPI_MAX_PORT_NAME, mpi_errno, "remote port name"); mpi_errno = MPIR_Open_port_impl(NULL, local_port); MPIU_ERR_CHKANDJUMP((mpi_errno != MPI_SUCCESS), mpi_errno, MPI_ERR_OTHER, "**openportfailed"); err = MPIR_fd_send(fd, local_port, MPI_MAX_PORT_NAME); MPIU_ERR_CHKANDJUMP1((err != 0), mpi_errno, MPI_ERR_INTERN, "**join_send", "**join_send %d", err); err = MPIR_fd_recv(fd, remote_port, MPI_MAX_PORT_NAME); MPIU_ERR_CHKANDJUMP1((err != 0), mpi_errno, MPI_ERR_INTERN, "**join_recv", "**join_recv %d", err); MPIU_ERR_CHKANDJUMP2((strcmp(local_port, remote_port) == 0), mpi_errno, MPI_ERR_INTERN, "**join_portname", "**join_portname %s %s", local_port, remote_port); if (strcmp(local_port, remote_port) < 0) { MPID_Comm *comm_self_ptr; MPID_Comm_get_ptr( MPI_COMM_SELF, comm_self_ptr ); mpi_errno = MPIR_Comm_accept_impl(local_port, NULL, 0, comm_self_ptr, &intercomm_ptr); if (mpi_errno) MPIU_ERR_POP(mpi_errno); } else { MPID_Comm *comm_self_ptr; MPID_Comm_get_ptr( MPI_COMM_SELF, comm_self_ptr ); mpi_errno = MPIR_Comm_connect_impl(remote_port, NULL, 0, comm_self_ptr, &intercomm_ptr); if (mpi_errno) MPIU_ERR_POP(mpi_errno); } mpi_errno = MPIR_Close_port_impl(local_port); if (mpi_errno) MPIU_ERR_POP(mpi_errno); MPIU_OBJ_PUBLISH_HANDLE(*intercomm, intercomm_ptr->handle); /* ... end of body of routine ... */ fn_exit: MPIU_CHKLMEM_FREEALL(); MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_COMM_JOIN); MPIU_THREAD_CS_EXIT(ALLFUNC,); return mpi_errno; fn_fail: /* --BEGIN ERROR HANDLING-- */ # ifdef HAVE_ERROR_CHECKING { mpi_errno = MPIR_Err_create_code( mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_comm_join", "**mpi_comm_join %d %p", fd, intercomm); } # endif mpi_errno = MPIR_Err_return_comm( NULL, FCNAME, mpi_errno ); goto fn_exit; /* --END ERROR HANDLING-- */ }
/*@ MPI_Open_port - Establish an address that can be used to establish connections between groups of MPI processes Input Parameters: . info - implementation-specific information on how to establish a port for 'MPI_Comm_accept' (handle) Output Parameters: . port_name - newly established port (string) Notes: MPI copies a system-supplied port name into 'port_name'. 'port_name' identifies the newly opened port and can be used by a client to contact the server. The maximum size string that may be supplied by the system is 'MPI_MAX_PORT_NAME'. Reserved Info Key Values: + ip_port - Value contains IP port number at which to establish a port. - ip_address - Value contains IP address at which to establish a port. If the address is not a valid IP address of the host on which the 'MPI_OPEN_PORT' call is made, the results are undefined. .N ThreadSafe .N Fortran .N Errors .N MPI_SUCCESS @*/ int MPI_Open_port(MPI_Info info, char *port_name) { int mpi_errno = MPI_SUCCESS; MPIR_Info *info_ptr = NULL; MPIR_FUNC_TERSE_STATE_DECL(MPID_STATE_MPI_OPEN_PORT); MPIR_ERRTEST_INITIALIZED_ORDIE(); MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); MPIR_FUNC_TERSE_ENTER(MPID_STATE_MPI_OPEN_PORT); /* Validate parameters, especially handles needing to be converted */ #ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS; { /* Note that a NULL info is allowed */ MPIR_ERRTEST_INFO_OR_NULL(info, mpi_errno); } MPID_END_ERROR_CHECKS; } #endif /* Convert MPI object handles to object pointers */ MPIR_Info_get_ptr(info, info_ptr); /* Validate parameters and objects (post conversion) */ #ifdef HAVE_ERROR_CHECKING { MPID_BEGIN_ERROR_CHECKS; { /* FIXME: If info_ptr is non-null, we should validate it */ MPIR_ERRTEST_ARGNULL(port_name, "port_name", mpi_errno); } MPID_END_ERROR_CHECKS; } #endif /* HAVE_ERROR_CHECKING */ /* ... body of routine ... */ mpi_errno = MPIR_Open_port_impl(info_ptr, port_name); if (mpi_errno != MPI_SUCCESS) goto fn_fail; /* ... end of body of routine ... */ fn_exit: MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPI_OPEN_PORT); MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); return mpi_errno; fn_fail: /* --BEGIN ERROR HANDLING-- */ #ifdef HAVE_ERROR_CHECKING { mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_open_port", "**mpi_open_port %I %p", info, port_name); } #endif mpi_errno = MPIR_Err_return_comm(NULL, FCNAME, mpi_errno); goto fn_exit; /* --END ERROR HANDLING-- */ }