-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/spawn/comm_join.c
        -:    0:Graph:comm_join.gcno
        -:    0:Data:comm_join.gcda
        -:    0:Runs:511
        -:    0:Programs:137
        -:    1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
        -:    2:/*
        -:    3: *
        -:    4: *  (C) 2001 by Argonne National Laboratory.
        -:    5: *      See COPYRIGHT in top-level directory.
        -:    6: */
        -:    7:
        -:    8:#include "mpiimpl.h"
        -:    9:
        -:   10:/* -- Begin Profiling Symbol Block for routine MPI_Comm_join */
        -:   11:#if defined(HAVE_PRAGMA_WEAK)
        -:   12:#pragma weak MPI_Comm_join = PMPI_Comm_join
        -:   13:#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
        -:   14:#pragma _HP_SECONDARY_DEF PMPI_Comm_join  MPI_Comm_join
        -:   15:#elif defined(HAVE_PRAGMA_CRI_DUP)
        -:   16:#pragma _CRI duplicate MPI_Comm_join as PMPI_Comm_join
        -:   17:#endif
        -:   18:/* -- End Profiling Symbol Block */
        -:   19:
        -:   20:/* Prototypes for local functions */
        -:   21:PMPI_LOCAL int MPIR_fd_send(int, void *, int);
        -:   22:PMPI_LOCAL int MPIR_fd_recv(int, void *, int);
        -:   23:
        -:   24:/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
        -:   25:   the MPI routines */
        -:   26:#ifndef MPICH_MPI_FROM_PMPI
        -:   27:#undef MPI_Comm_join
        -:   28:#define MPI_Comm_join PMPI_Comm_join
        -:   29:
        -:   30:#ifdef HAVE_ERRNO_H
        -:   31:#include <errno.h> /* needed for read/write error codes */
        -:   32:#endif
        -:   33:
        -:   34:#ifdef HAVE_WINDOWS_H
        -:   35:#define SOCKET_EINTR	    WSAEINTR
        -:   36:#else
        -:   37:#ifdef HAVE_SYS_SOCKET_H
        -:   38:#include <sys/socket.h>
        -:   39:#endif
        -:   40:#define SOCKET_EINTR	    EINTR
        -:   41:#endif
        -:   42:
        -:   43:PMPI_LOCAL int MPIR_fd_send(int fd, void *buffer, int length)
        2:   44:{
        -:   45:    int result, num_bytes;
        -:   46:
        6:   47:    while (length)
        -:   48:    {
        2:   49:	num_bytes = send(fd, buffer, length, 0);
        -:   50:	/* --BEGIN ERROR HANDLING-- */
        2:   51:	if (num_bytes == -1)
        -:   52:	{
        -:   53:#ifdef HAVE_WINDOWS_H
        -:   54:	    result = WSAGetLastError();
        -:   55:#else
    #####:   56:	    result = errno;
        -:   57:#endif
    #####:   58:	    if (result == SOCKET_EINTR)
    #####:   59:                continue;
        -:   60:            else
    #####:   61:                return result;
        -:   62:	}
        -:   63:	/* --END ERROR HANDLING-- */
        -:   64:        else {
        2:   65:            length -= num_bytes;
        2:   66:            buffer = (char*)buffer + num_bytes;
        -:   67:        }
        -:   68:    }
        2:   69:    return 0;
        -:   70:}
        -:   71:
        -:   72:PMPI_LOCAL int MPIR_fd_recv(int fd, void *buffer, int length)
        2:   73:{
        -:   74:    int result, num_bytes;
        -:   75:
        6:   76:    while (length)
        -:   77:    {
        2:   78:	num_bytes = recv(fd, buffer, length, 0);
        -:   79:	/* --BEGIN ERROR HANDLING-- */
        2:   80:	if (num_bytes == -1)
        -:   81:	{
        -:   82:#ifdef HAVE_WINDOWS_H
        -:   83:	    result = WSAGetLastError();
        -:   84:#else
    #####:   85:	    result = errno;
        -:   86:#endif
    #####:   87:	    if (result == SOCKET_EINTR)
    #####:   88:                continue;
        -:   89:	    else
    #####:   90:                return result;
        -:   91:	}
        -:   92:	/* --END ERROR HANDLING-- */
        -:   93:        else {
        2:   94:            length -= num_bytes;
        2:   95:            buffer = (char*)buffer + num_bytes;
        -:   96:        }
        -:   97:    }
        2:   98:    return 0;
        -:   99:}
        -:  100:
        -:  101:#endif
        -:  102:
        -:  103:#undef FUNCNAME
        -:  104:#define FUNCNAME MPI_Comm_join
        -:  105:
        -:  106:/*@
        -:  107:   MPI_Comm_join - Create a communicator by joining two processes connected by 
        -:  108:     a socket.
        -:  109:
        -:  110:   Input Parameter:
        -:  111:. fd - socket file descriptor 
        -:  112:
        -:  113:   Output Parameter:
        -:  114:. intercomm - new intercommunicator (handle) 
        -:  115:
        -:  116: Notes:
        -:  117:  The socket must be quiescent before 'MPI_COMM_JOIN' is called and after 
        -:  118:  'MPI_COMM_JOIN' returns. More specifically, on entry to 'MPI_COMM_JOIN', a 
        -:  119:  read on the socket will not read any data that was written to the socket 
        -:  120:  before the remote process called 'MPI_COMM_JOIN'.
        -:  121:
        -:  122:.N ThreadSafe
        -:  123:
        -:  124:.N Fortran
        -:  125:
        -:  126:.N Errors
        -:  127:.N MPI_SUCCESS
        -:  128:.N MPI_ERR_ARG
        -:  129:@*/
        -:  130:int MPI_Comm_join(int fd, MPI_Comm *intercomm)
        2:  131:{
        -:  132:    static const char FCNAME[] = "MPI_Comm_join";
        2:  133:    int mpi_errno = MPI_SUCCESS, err;
        -:  134:    char *local_port, *remote_port;
        2:  135:    MPIU_THREADPRIV_DECL;
        2:  136:    MPIU_CHKLMEM_DECL(2);
        -:  137:    MPID_MPI_STATE_DECL(MPID_STATE_MPI_COMM_JOIN);
        -:  138:
        2:  139:    MPIR_ERRTEST_INITIALIZED_ORDIE();
        -:  140:    
        2:  141:    MPIU_THREAD_CS_ENTER(ALLFUNC,);
        -:  142:    MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_COMM_JOIN);
        -:  143:
        -:  144:    /* ... body of routine ...  */
        -:  145:
        2:  146:    MPIU_THREADPRIV_GET;
        -:  147:    /* Set the nest incr here so that we can jump to fn_fail and 
        -:  148:       call nest_decr without worry */
        2:  149:    MPIR_Nest_incr();
        -:  150:    
        2:  151:    MPIU_CHKLMEM_MALLOC(local_port, char *, MPI_MAX_PORT_NAME, mpi_errno, "local port name");
        4:  152:    MPIU_CHKLMEM_MALLOC(remote_port, char *, MPI_MAX_PORT_NAME, mpi_errno, "remote port name");
        -:  153:    
        2:  154:    mpi_errno = NMPI_Open_port(MPI_INFO_NULL, local_port);
        2:  155:    MPIU_ERR_CHKANDJUMP((mpi_errno != MPI_SUCCESS), mpi_errno, MPI_ERR_OTHER, "**openportfailed");
        -:  156:
        2:  157:    err = MPIR_fd_send(fd, local_port, MPI_MAX_PORT_NAME);
        2:  158:    MPIU_ERR_CHKANDJUMP1((err != 0), mpi_errno, MPI_ERR_INTERN, "**join_send", "**join_send %d", err);
        -:  159:
        2:  160:    err = MPIR_fd_recv(fd, remote_port, MPI_MAX_PORT_NAME);
        2:  161:    MPIU_ERR_CHKANDJUMP1((err != 0), mpi_errno, MPI_ERR_INTERN, "**join_recv", "**join_recv %d", err);
        -:  162:
        2:  163:    MPIU_ERR_CHKANDJUMP2((strcmp(local_port, remote_port) == 0), mpi_errno, MPI_ERR_INTERN, "**join_portname",
        -:  164:			 "**join_portname %s %s", local_port, remote_port);
        -:  165:
        2:  166:    if (strcmp(local_port, remote_port) < 0) {
        1:  167:        mpi_errno = NMPI_Comm_accept(local_port, MPI_INFO_NULL, 0, 
        -:  168:                                     MPI_COMM_SELF, intercomm);
        -:  169:    }
        -:  170:    else {
        1:  171:        mpi_errno = NMPI_Comm_connect(remote_port, MPI_INFO_NULL, 0, 
        -:  172:                                     MPI_COMM_SELF, intercomm);
        -:  173:    }
        2:  174:    if (mpi_errno != MPI_SUCCESS) goto fn_fail;
        -:  175:
        2:  176:    mpi_errno = NMPI_Close_port(local_port);
        2:  177:    if (mpi_errno != MPI_SUCCESS) goto fn_fail;
        -:  178:
        2:  179:    MPIR_Nest_decr();
        -:  180:    /* ... end of body of routine ... */
        -:  181:
        -:  182:  fn_exit:
        4:  183:    MPIU_CHKLMEM_FREEALL();
        -:  184:    MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_COMM_JOIN);
        2:  185:    MPIU_THREAD_CS_EXIT(ALLFUNC,);
        2:  186:    return mpi_errno;
        -:  187:
    #####:  188:  fn_fail:
    #####:  189:    MPIR_Nest_decr();
        -:  190:    /* --BEGIN ERROR HANDLING-- */
        -:  191:#   ifdef HAVE_ERROR_CHECKING
        -:  192:    {
    #####:  193:	mpi_errno = MPIR_Err_create_code(
        -:  194:	    mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**mpi_comm_join",
        -:  195:	    "**mpi_comm_join %d %p", fd, intercomm);
        -:  196:    }
        -:  197:#   endif
    #####:  198:    mpi_errno = MPIR_Err_return_comm( NULL, FCNAME, mpi_errno );
    #####:  199:    goto fn_exit;
        -:  200:    /* --END ERROR HANDLING-- */
        -:  201:}