-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/common/sock/poll/sock_post.i
        -:    0:Graph:sock.gcno
        -:    0:Data:sock.gcda
        -:    0:Runs:4381
        -:    0:Programs:1376
        -:    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:/* FIXME: Provide an overview for the functions in this file */
        -:    9:
        -:   10:#undef FUNCNAME 
        -:   11:#define FUNCNAME MPIDU_Sock_post_connect_ifaddr
        -:   12:#undef FCNAME
        -:   13:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:   14:/* 
        -:   15: This routine connects to a particular address (in byte form; for ipv4, 
        -:   16: the address is four bytes, typically the value of h_addr_list[0] in 
        -:   17: struct hostent.  By avoiding a character name for an interface (we *never*
        -:   18: connect to a host; we are *always* connecting to a particular interface 
        -:   19: on a host), we avoid problems with DNS services, including lack of properly
        -:   20: configured services and scalability problems.  As this routine uses 
        -:   21: a four-byte field, it is currently restricted to ipv4.  This routine should
        -:   22: evolve to support ipv4 and ipv6 addresses.
        -:   23:
        -:   24: This routine was constructed from MPIDU_Sock_post_connect by removing the 
        -:   25: poorly placed use of gethostname within the middle of that routine and
        -:   26: simply using the ifaddr field that is passed to this routine.  
        -:   27: MPIDU_Sock_post_connect simply uses the hostname field to get the canonical
        -:   28: IP address.  The original routine and its API was retained to allow backwards
        -:   29: compatibility until it is determined that we can always use explicit addrs 
        -:   30: needed in setting up the socket instead of character strings.
        -:   31: */
        -:   32:int MPIDU_Sock_post_connect_ifaddr( struct MPIDU_Sock_set * sock_set, 
        -:   33:				    void * user_ptr, 
        -:   34:				    MPIDU_Sock_ifaddr_t *ifaddr, int port,
        -:   35:				    struct MPIDU_Sock ** sockp)
     8038:   36:{
     8038:   37:    struct MPIDU_Sock * sock = NULL;
        -:   38:    struct pollfd * pollfd;
        -:   39:    struct pollinfo * pollinfo;
     8038:   40:    int fd = -1;
        -:   41:    struct sockaddr_in addr;
        -:   42:    long flags;
        -:   43:    int nodelay;
        -:   44:    int rc;
     8038:   45:    int mpi_errno = MPI_SUCCESS;
        -:   46:    MPIDI_STATE_DECL(MPID_STATE_MPIDU_SOCK_POST_CONNECT_IFADDR);
        -:   47:
        -:   48:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_SOCK_POST_CONNECT_IFADDR);
        -:   49:
        -:   50:    MPIDU_SOCKI_VERIFY_INIT(mpi_errno, fn_exit);
        -:   51:
        -:   52:    /*
        -:   53:     * Create a non-blocking socket with Nagle's algorithm disabled
        -:   54:     */
     8038:   55:    fd = socket(PF_INET, SOCK_STREAM, 0);
     8038:   56:    if (fd == -1) {
        -:   57:	/* FIXME: It would be better to include a special formatting
        -:   58:	   clue for system error messages (e.g., %dSE; in the recommended
        -:   59:	   revision for error reporting (that is, value (errno) is an int, 
        -:   60:	   but should be interpreted as an System Error string) */
    #####:   61:	MPIU_ERR_SETANDJUMP2(mpi_errno,MPIDU_SOCK_ERR_FAIL,
        -:   62:			     "**sock|poll|socket", 
        -:   63:		    "**sock|poll|socket %d %s", errno, MPIU_Strerror(errno));
        -:   64:    }
        -:   65:
     8038:   66:    flags = fcntl(fd, F_GETFL, 0);
     8038:   67:    if (flags == -1) {
    #####:   68:	MPIU_ERR_SETANDJUMP2(mpi_errno,MPIDU_SOCK_ERR_FAIL,
        -:   69:			     "**sock|poll|nonblock", 
        -:   70:                    "**sock|poll|nonblock %d %s", errno, MPIU_Strerror(errno));
        -:   71:    }
     8038:   72:    rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
     8038:   73:    if (rc == -1) {
    #####:   74:	MPIU_ERR_SETANDJUMP2( mpi_errno, MPIDU_SOCK_ERR_FAIL,
        -:   75:			      "**sock|poll|nonblock", 
        -:   76:			      "**sock|poll|nonblock %d %s",
        -:   77:			      errno, MPIU_Strerror(errno));
        -:   78:    }
        -:   79:
     8038:   80:    nodelay = 1;
     8038:   81:    rc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay));
     8038:   82:    if (rc != 0) {
    #####:   83:	MPIU_ERR_SETANDJUMP2(mpi_errno,MPIDU_SOCK_ERR_FAIL,
        -:   84:			     "**sock|poll|nodelay", 
        -:   85:			     "**sock|poll|nodelay %d %s", 
        -:   86:			     errno, MPIU_Strerror(errno));
        -:   87:    }
        -:   88:
        -:   89:    /*
        -:   90:     * Allocate and initialize sock and poll structures
        -:   91:     *
        -:   92:     * NOTE: pollfd->fd is initialized to -1.  It is only set to the true fd 
        -:   93:     * value when an operation is posted on the sock.  This
        -:   94:     * (hopefully) eliminates a little overhead in the OS and avoids 
        -:   95:     * repetitive POLLHUP events when the connection is closed by
        -:   96:     * the remote process.
        -:   97:     */
     8038:   98:    mpi_errno = MPIDU_Socki_sock_alloc(sock_set, &sock);
     8038:   99:    if (mpi_errno != MPI_SUCCESS) {
    #####:  100:	MPIU_ERR_SETANDJUMP(mpi_errno,MPIDU_SOCK_ERR_NOMEM,
        -:  101:			    "**sock|sockalloc");
        -:  102:    }
        -:  103:
     8038:  104:    pollfd = MPIDU_Socki_sock_get_pollfd(sock);
     8038:  105:    pollinfo = MPIDU_Socki_sock_get_pollinfo(sock);
        -:  106:    
     8038:  107:    pollinfo->fd = fd;
     8038:  108:    pollinfo->user_ptr = user_ptr;
     8038:  109:    pollinfo->type = MPIDU_SOCKI_TYPE_COMMUNICATION;
     8038:  110:    pollinfo->state = MPIDU_SOCKI_STATE_CONNECTED_RW;
     8038:  111:    pollinfo->os_errno = 0;
        -:  112:
     8038:  113:    memset(&addr, 0, sizeof(addr));
     8038:  114:    addr.sin_family = AF_INET;
     8038:  115:    memcpy(&addr.sin_addr.s_addr, ifaddr->ifaddr, 
        -:  116:	   sizeof(addr.sin_addr.s_addr));
     8038:  117:    addr.sin_port = htons( (unsigned short)port);
        -:  118:
        -:  119:    /*
        -:  120:     * Set and verify the socket buffer size
        -:  121:     */
     8038:  122:    mpi_errno = MPIDU_Sock_SetSockBufferSize( fd, 1 );
     8038:  123:    if (mpi_errno) { MPIU_ERR_POP(mpi_errno); }
        -:  124:    
        -:  125:    /*
        -:  126:     * Attempt to establish the connection
        -:  127:     */
        -:  128:    MPIU_DBG_STMT(CH3_CONNECT,TYPICAL,{
        -:  129:	char addrString[64];
        -:  130:	MPIDU_Sock_AddrToStr( ifaddr, addrString, sizeof(addrString) );
        -:  131:	MPIU_DBG_MSG_FMT(CH3_CONNECT,TYPICAL,(MPIU_DBG_FDEST,
        -:  132:			      "Connecting to %s:%d\n", addrString, port )); 
        -:  133:	})
        -:  134:
        -:  135:    do
        -:  136:    {
     8038:  137:        rc = connect(fd, (struct sockaddr *) &addr, sizeof(addr));
        -:  138:    }
     8038:  139:    while (rc == -1 && errno == EINTR);
        -:  140:    
     8038:  141:    if (rc == 0)
        -:  142:    {
        -:  143:	/* connection succeeded */
        -:  144:	MPIU_DBG_MSG_P(CH3_CONNECT,TYPICAL,"Setting state to SOCKI_STATE_CONNECTED_RW for sock %p",sock);
    #####:  145:	pollinfo->state = MPIDU_SOCKI_STATE_CONNECTED_RW;
    #####:  146:	MPIDU_SOCKI_EVENT_ENQUEUE(pollinfo, MPIDU_SOCK_OP_CONNECT, 0, user_ptr, MPI_SUCCESS, mpi_errno, fn_fail);
        -:  147:    }
        -:  148:    /* --BEGIN ERROR HANDLING-- */
     8038:  149:    else if (errno == EINPROGRESS)
        -:  150:    {
        -:  151:	/* connection pending */
        -:  152:	MPIU_DBG_MSG_P(CH3_CONNECT,TYPICAL,"Setting state to SOCKI_STATE_CONNECTING for sock %p",sock);
     8038:  153:	pollinfo->state = MPIDU_SOCKI_STATE_CONNECTING;
     8038:  154:	MPIDU_SOCKI_POLLFD_OP_SET(pollfd, pollinfo, POLLOUT);
        -:  155:    }
        -:  156:    else
        -:  157:    {
        -:  158:	MPIU_DBG_MSG_P(CH3_CONNECT,TYPICAL,"Setting state to SOCKI_STATE_DISCONNECTED (failure in connect) for sock %p",sock);
    #####:  159:	pollinfo->os_errno = errno;
    #####:  160:	pollinfo->state = MPIDU_SOCKI_STATE_DISCONNECTED;
        -:  161:
    #####:  162:	if (errno == ECONNREFUSED)
        -:  163:	{
    #####:  164:	    MPIDU_SOCKI_EVENT_ENQUEUE(pollinfo, MPIDU_SOCK_OP_CONNECT, 0, user_ptr, MPIR_Err_create_code(
        -:  165:		MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_CONN_FAILED,
        -:  166:		"**sock|connrefused", "**sock|poll|connrefused %d %d %s",
        -:  167:		pollinfo->sock_set->id, pollinfo->sock_id, ""), mpi_errno, fn_fail);
        -:  168:	}
        -:  169:	else
        -:  170:	{
    #####:  171:	    MPIDU_SOCKI_EVENT_ENQUEUE(pollinfo, MPIDU_SOCK_OP_CONNECT, 0, user_ptr, MPIR_Err_create_code(
        -:  172:		MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_CONN_FAILED,
        -:  173:		"**sock|oserror", "**sock|poll|oserror %d %d %d %s", pollinfo->sock_set->id, pollinfo->sock_id, errno,
        -:  174:		MPIU_Strerror(errno)), mpi_errno, fn_fail);
        -:  175:	}
        -:  176:    }
        -:  177:    /* --END ERROR HANDLING-- */
        -:  178:
     8038:  179:    *sockp = sock;
        -:  180:
     8038:  181:  fn_exit:
        -:  182:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_SOCK_POST_CONNECT_IFADDR);
     8038:  183:    return mpi_errno;
        -:  184:
        -:  185:    /* --BEGIN ERROR HANDLING-- */
    #####:  186:  fn_fail:
    #####:  187:    if (fd != -1)
        -:  188:    { 
    #####:  189:	close(fd);
        -:  190:    }
        -:  191:
    #####:  192:    if (sock != NULL)
        -:  193:    {
    #####:  194:	MPIDU_Socki_sock_free(sock);
        -:  195:    }
        -:  196:
        -:  197:    goto fn_exit;
        -:  198:    /* --END ERROR HANDLING-- */
        -:  199:}
        -:  200:
        -:  201:/* FIXME: What does this routine do?  Why does it take a host description
        -:  202:   instead of an interface name or address? */
        -:  203:#undef FUNCNAME
        -:  204:#define FUNCNAME MPIDU_Sock_post_connect
        -:  205:#undef FCNAME
        -:  206:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  207:int MPIDU_Sock_post_connect(struct MPIDU_Sock_set * sock_set, void * user_ptr, 
        -:  208:			    char * host_description, int port,
        -:  209:			    struct MPIDU_Sock ** sockp)
      668:  210:{
      668:  211:    int mpi_errno = MPI_SUCCESS;
        -:  212:    MPIDU_Sock_ifaddr_t ifaddr;
        -:  213:    struct hostent * hostent;
        -:  214:
        -:  215:    /*
        -:  216:     * Convert hostname to IP address
        -:  217:     *
        -:  218:     * FIXME: this should handle failures caused by a backed up listener queue
        -:  219:     * at the remote process.  It should also use a
        -:  220:     * specific interface if one is specified by the user.
        -:  221:     */
        -:  222:    /* FIXME: strtok may change the contents of host_description.  Shouldn't
        -:  223:       the host description be a const char [] and not modified by this 
        -:  224:       routine? */
      668:  225:    strtok(host_description, " ");
        -:  226:    /* FIXME: For ipv6, we should use getaddrinfo */
      668:  227:    hostent = gethostbyname(host_description);
        -:  228:    /* --BEGIN ERROR HANDLING-- */
      668:  229:    if (hostent == NULL || hostent->h_addrtype != AF_INET) {
        -:  230:	/* FIXME: Set error */
        -:  231:	goto fn_exit;
        -:  232:    }
        -:  233:    /* --END ERROR HANDLING-- */
        -:  234:    /* These are correct for IPv4 */
      668:  235:    memcpy( ifaddr.ifaddr, (unsigned char *)hostent->h_addr_list[0], 4 );
      668:  236:    ifaddr.len  = 4;
      668:  237:    ifaddr.type = AF_INET;
      668:  238:    mpi_errno = MPIDU_Sock_post_connect_ifaddr( sock_set, user_ptr, 
        -:  239:						&ifaddr, port, sockp );
      668:  240: fn_exit:
      668:  241:    return mpi_errno;
        -:  242:}
        -:  243:/* end MPIDU_Sock_post_connect() */
        -:  244:
        -:  245:
        -:  246:#undef FUNCNAME
        -:  247:#define FUNCNAME MPIDU_Sock_listen
        -:  248:#undef FCNAME
        -:  249:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  250:#ifndef USHRT_MAX
        -:  251:#define USHRT_MAX 65535   /* 2^16-1 */
        -:  252:#endif
        -:  253:int MPIDU_Sock_listen(struct MPIDU_Sock_set * sock_set, void * user_ptr, 
        -:  254:		      int * port, struct MPIDU_Sock ** sockp)
     4381:  255:{
        -:  256:    struct MPIDU_Sock * sock;
        -:  257:    struct pollfd * pollfd;
        -:  258:    struct pollinfo * pollinfo;
     4381:  259:    int fd = -1;
        -:  260:    long flags;
        -:  261:    int optval;
        -:  262:    struct sockaddr_in addr;
        -:  263:    socklen_t addr_len;
        -:  264:    int rc;
     4381:  265:    int mpi_errno = MPI_SUCCESS;
        -:  266:    MPIDI_STATE_DECL(MPID_STATE_MPIDU_SOCK_LISTEN);
        -:  267:
        -:  268:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_SOCK_LISTEN);
        -:  269:
        -:  270:    MPIDU_SOCKI_VERIFY_INIT(mpi_errno, fn_exit);
        -:  271:    /* --BEGIN ERROR HANDLING-- */
     4381:  272:    if (*port < 0 || *port > USHRT_MAX)
        -:  273:    {
    #####:  274:	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_BAD_PORT,
        -:  275:					 "**sock|badport", "**sock|badport %d", *port);
    #####:  276:	goto fn_exit;
        -:  277:    }
        -:  278:    /* --END ERROR HANDLING-- */
        -:  279:
        -:  280:    /*
        -:  281:     * Create a non-blocking socket for the listener
        -:  282:     */
     4381:  283:    fd = socket(PF_INET, SOCK_STREAM, 0);
        -:  284:    /* --BEGIN ERROR HANDLING-- */
     4381:  285:    if (fd == -1)
        -:  286:    {
    #####:  287:	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_FAIL,
        -:  288:					 "**sock|poll|socket", "**sock|poll|socket %d %s", errno, MPIU_Strerror(errno));
    #####:  289:	goto fn_fail;
        -:  290:    }
        -:  291:    /* --END ERROR HANDLING-- */
        -:  292:
        -:  293:    /* set SO_REUSEADDR to a prevent a fixed service port from being bound to during subsequent invocations */
     4381:  294:    if (*port != 0)
        -:  295:    {
    #####:  296:	optval = 1;
    #####:  297:	rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int));
        -:  298:	/* --BEGIN ERROR HANDLING-- */
    #####:  299:	if (rc == -1)
        -:  300:	{
    #####:  301:	    mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_FAIL,
        -:  302:					     "**sock|poll|reuseaddr", "**sock|poll|reuseaddr %d %s", errno, MPIU_Strerror(errno));
    #####:  303:	    goto fn_fail;
        -:  304:	}
        -:  305:	/* --END ERROR HANDLING-- */
        -:  306:    }
        -:  307:
        -:  308:    /* make the socket non-blocking so that accept() will return immediately if no new connection is available */
     4381:  309:    flags = fcntl(fd, F_GETFL, 0);
        -:  310:    /* --BEGIN ERROR HANDLING-- */
     4381:  311:    if (flags == -1)
        -:  312:    {
    #####:  313:	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_FAIL,
        -:  314:					 "**sock|poll|nonblock", "**sock|poll|nonblock %d %s", errno, MPIU_Strerror(errno));
    #####:  315:	goto fn_fail;
        -:  316:    }
        -:  317:    /* --END ERROR HANDLING-- */
     4381:  318:    rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
        -:  319:    /* --BEGIN ERROR HANDLING-- */
     4381:  320:    if (rc == -1)
        -:  321:    {
    #####:  322:	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_FAIL,
        -:  323:					 "**sock|poll|nonblock", "**sock|poll|nonblock %d %s", errno, MPIU_Strerror(errno));
    #####:  324:	goto fn_fail;
        -:  325:    }
        -:  326:    /* --END ERROR HANDLING-- */
        -:  327:
        -:  328:    /*
        -:  329:     * Bind the socket to all interfaces and the specified port.  The port specified by the calling routine may be 0, indicating
        -:  330:     * that the operating system can select an available port in the ephemeral port range.
        -:  331:     */
     4381:  332:    if (*port == 0) {
        -:  333:	int portnum, low_port, high_port;
        -:  334:	/* see if we actually want to find values within a range */
        -:  335:	
     4381:  336:	low_port = high_port = 0;
        -:  337:	/* Get range here.  These leave low_port, high_port unchanged
        -:  338:	   if the env variable is not set */
        -:  339:	/* FIXME: Use the parameter interface and document this */
     4381:  340:	MPIU_GetEnvRange( "MPICH_PORT_RANGE", &low_port, &high_port );
        -:  341:
     4381:  342:	for (portnum=low_port; portnum<=high_port; portnum++) {
     4381:  343:	    memset( (void *)&addr, 0, sizeof(addr) );
     4381:  344:	    addr.sin_family      = AF_INET;
     4381:  345:	    addr.sin_addr.s_addr = htonl(INADDR_ANY);
     4381:  346:	    addr.sin_port	 = htons( (unsigned short)portnum );
        -:  347:	    
     4381:  348:	    rc = bind(fd, (struct sockaddr *) &addr, sizeof(addr));
     4381:  349:	    if (rc < 0) {
    #####:  350:		if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) {
    #####:  351:		    close(fd);
    #####:  352:		    break;
        -:  353:		}
        -:  354:	    }
        -:  355:	    else 
     4381:  356:		break;
        -:  357:	}
        -:  358:    }
        -:  359:    else {
    #####:  360:	memset(&addr, 0, sizeof(addr));
    #####:  361:	addr.sin_family      = AF_INET;
    #####:  362:	addr.sin_addr.s_addr = htonl(INADDR_ANY);
    #####:  363:	addr.sin_port        = htons((unsigned short) *port);
    #####:  364:	rc = bind(fd, (struct sockaddr *) &addr, sizeof(addr));
        -:  365:    }
        -:  366:    /* --BEGIN ERROR HANDLING-- */
     4381:  367:    if (rc == -1)
        -:  368:    {
    #####:  369:	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_FAIL,
        -:  370:					 "**sock|poll|bind", "**sock|poll|bind %d %d %s", *port, errno, MPIU_Strerror(errno));
    #####:  371:	goto fn_fail;
        -:  372:    }
        -:  373:    /* --END ERROR HANDLING-- */
        -:  374:
        -:  375:    /*
        -:  376:     * Set and verify the socket buffer size
        -:  377:     */
     4381:  378:    mpi_errno = MPIDU_Sock_SetSockBufferSize( fd, 1 );
     4381:  379:    if (mpi_errno) { MPIU_ERR_POP( mpi_errno ); }
        -:  380:    
        -:  381:    /*
        -:  382:     * Start listening for incoming connections...
        -:  383:     */
     4381:  384:    rc = listen(fd, SOMAXCONN);
        -:  385:    /* --BEGIN ERROR HANDLING-- */
     4381:  386:    if (rc == -1)
        -:  387:    {
    #####:  388:	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_FAIL,
        -:  389:					 "**sock|poll|listen", "**sock|poll|listen %d %s", errno, MPIU_Strerror(errno));
    #####:  390:	goto fn_fail;
        -:  391:    }
        -:  392:    /* --END ERROR HANDLING-- */
        -:  393:
        -:  394:    /*
        -:  395:     * Get listener port.  Techincally we don't need to do this if a port was 
        -:  396:     * specified by the calling routine; but it adds an extra error check.
        -:  397:     */
     4381:  398:    addr_len = sizeof(addr);
     4381:  399:    rc = getsockname(fd, (struct sockaddr *) &addr, &addr_len);
        -:  400:    /* --BEGIN ERROR HANDLING-- */
     4381:  401:    if (rc == -1)
        -:  402:    {
    #####:  403:	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_FAIL,
        -:  404:					 "**sock|getport", "**sock|poll|getport %d %s", errno, MPIU_Strerror(errno));
    #####:  405:	goto fn_fail;
        -:  406:    }
        -:  407:    /* --END ERROR HANDLING-- */
     4381:  408:    *port = (unsigned int) ntohs(addr.sin_port);
        -:  409:
        -:  410:    /*
        -:  411:     * Allocate and initialize sock and poll structures.  If another thread is
        -:  412:     * blocking in poll(), that thread must be woke up
        -:  413:     * long enough to pick up the addition of the listener socket.
        -:  414:     */
     4381:  415:    mpi_errno = MPIDU_Socki_sock_alloc(sock_set, &sock);
        -:  416:    /* --BEGIN ERROR HANDLING-- */
     4381:  417:    if (mpi_errno != MPI_SUCCESS)
        -:  418:    {
    #####:  419:	mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_NOMEM,
        -:  420:					 "**sock|sockalloc", NULL);
    #####:  421:	goto fn_fail;
        -:  422:    }
        -:  423:    /* --END ERROR HANDLING-- */
        -:  424:
     4381:  425:    pollfd = MPIDU_Socki_sock_get_pollfd(sock);
     4381:  426:    pollinfo = MPIDU_Socki_sock_get_pollinfo(sock);
        -:  427:    
     4381:  428:    pollinfo->fd = fd;
     4381:  429:    pollinfo->user_ptr = user_ptr;
     4381:  430:    pollinfo->type = MPIDU_SOCKI_TYPE_LISTENER;
     4381:  431:    pollinfo->state = MPIDU_SOCKI_STATE_CONNECTED_RO;
        -:  432:
     4381:  433:    MPIDU_SOCKI_POLLFD_OP_SET(pollfd, pollinfo, POLLIN);
        -:  434:
     4381:  435:    *sockp = sock;
        -:  436:
     4381:  437:  fn_exit:
        -:  438:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_SOCK_LISTEN);
     4381:  439:    return mpi_errno;
        -:  440:
        -:  441:    /* --BEGIN ERROR HANDLING-- */
    #####:  442:  fn_fail:
    #####:  443:    if (fd != -1)
        -:  444:    { 
    #####:  445:	close(fd);
        -:  446:    }
        -:  447:
        -:  448:    goto fn_exit;
        -:  449:    /* --END ERROR HANDLING-- */
        -:  450:}
        -:  451:/* end MPIDU_Sock_listen() */
        -:  452:
        -:  453:
        -:  454:/* FIXME: What does this function do? */
        -:  455:#undef FUNCNAME
        -:  456:#define FUNCNAME MPIDU_Sock_post_read
        -:  457:#undef FCNAME
        -:  458:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  459:int MPIDU_Sock_post_read(struct MPIDU_Sock * sock, void * buf, MPIU_Size_t minlen, MPIU_Size_t maxlen,
        -:  460:			 MPIDU_Sock_progress_update_func_t fn)
 16078410:  461:{
        -:  462:    struct pollfd * pollfd;
        -:  463:    struct pollinfo * pollinfo;
 16078410:  464:    int mpi_errno = MPI_SUCCESS;
        -:  465:    MPIDI_STATE_DECL(MPID_STATE_MPIDU_SOCK_POST_READ);
        -:  466:
        -:  467:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_SOCK_POST_READ);
        -:  468:
        -:  469:    MPIDU_SOCKI_VERIFY_INIT(mpi_errno, fn_exit);
        -:  470:    MPIDU_SOCKI_VALIDATE_SOCK(sock, mpi_errno, fn_exit);
        -:  471:
 16078410:  472:    pollfd = MPIDU_Socki_sock_get_pollfd(sock);
 16078410:  473:    pollinfo = MPIDU_Socki_sock_get_pollinfo(sock);
        -:  474:
        -:  475:    MPIDU_SOCKI_VALIDATE_FD(pollinfo, mpi_errno, fn_exit);
        -:  476:    MPIDU_SOCKI_VERIFY_CONNECTED_READABLE(pollinfo, mpi_errno, fn_exit);
        -:  477:    MPIDU_SOCKI_VERIFY_NO_POSTED_READ(pollfd, pollinfo, mpi_errno, fn_exit);
        -:  478:
        -:  479:    /* --BEGIN ERROR HANDLING-- */
 16078410:  480:    if (minlen < 1 || minlen > maxlen)
        -:  481:    {
    #####:  482:	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_BAD_LEN,
        -:  483:					 "**sock|badlen", "**sock|badlen %d %d %d %d",
        -:  484:					 pollinfo->sock_set->id, pollinfo->sock_id, minlen, maxlen);
    #####:  485:	goto fn_exit;
        -:  486:    }
        -:  487:    /* --END ERROR HANDLING-- */
        -:  488:
 16078410:  489:    pollinfo->read.buf.ptr = buf;
 16078410:  490:    pollinfo->read.buf.min = minlen;
 16078410:  491:    pollinfo->read.buf.max = maxlen;
 16078410:  492:    pollinfo->read_iov_flag = FALSE;
 16078410:  493:    pollinfo->read_nb = 0;
 16078410:  494:    pollinfo->read_progress_update_fn = fn;
        -:  495:    
 16078410:  496:    MPIDU_SOCKI_POLLFD_OP_SET(pollfd, pollinfo, POLLIN);
        -:  497:
 16078410:  498:  fn_exit:
        -:  499:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_SOCK_POST_READ);
 16078410:  500:    return mpi_errno;
        -:  501:}
        -:  502:/* end MPIDU_Sock_post_read() */
        -:  503:
        -:  504:
        -:  505:#undef FUNCNAME
        -:  506:#define FUNCNAME MPIDU_Sock_post_readv
        -:  507:#undef FCNAME
        -:  508:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  509:int MPIDU_Sock_post_readv(struct MPIDU_Sock * sock, MPID_IOV * iov, int iov_n, MPIDU_Sock_progress_update_func_t fn)
    44799:  510:{
        -:  511:    struct pollfd * pollfd;
        -:  512:    struct pollinfo * pollinfo;
    44799:  513:    int mpi_errno = MPI_SUCCESS;
        -:  514:    MPIDI_STATE_DECL(MPID_STATE_MPIDU_SOCK_POST_READV);
        -:  515:
        -:  516:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_SOCK_POST_READV);
        -:  517:
        -:  518:    MPIDU_SOCKI_VERIFY_INIT(mpi_errno, fn_exit);
        -:  519:    MPIDU_SOCKI_VALIDATE_SOCK(sock, mpi_errno, fn_exit);
        -:  520:
    44799:  521:    pollfd = MPIDU_Socki_sock_get_pollfd(sock);
    44799:  522:    pollinfo = MPIDU_Socki_sock_get_pollinfo(sock);
        -:  523:
        -:  524:    MPIDU_SOCKI_VALIDATE_FD(pollinfo, mpi_errno, fn_exit);
        -:  525:    MPIDU_SOCKI_VERIFY_CONNECTED_READABLE(pollinfo, mpi_errno, fn_exit);
        -:  526:    MPIDU_SOCKI_VERIFY_NO_POSTED_READ(pollfd, pollinfo, mpi_errno, fn_exit);
        -:  527:
        -:  528:    /* --BEGIN ERROR HANDLING-- */
    44799:  529:    if (iov_n < 1 || iov_n > MPID_IOV_LIMIT)
        -:  530:    {
    #####:  531:	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_BAD_LEN,
        -:  532:					 "**sock|badiovn", "**sock|badiovn %d %d %d",
        -:  533:					 pollinfo->sock_set->id, pollinfo->sock_id, iov_n);
    #####:  534:	goto fn_exit;
        -:  535:    }
        -:  536:    /* --END ERROR HANDLING-- */
        -:  537:
    44799:  538:    pollinfo->read.iov.ptr = iov;
    44799:  539:    pollinfo->read.iov.count = iov_n;
    44799:  540:    pollinfo->read.iov.offset = 0;
    44799:  541:    pollinfo->read_iov_flag = TRUE;
    44799:  542:    pollinfo->read_nb = 0;
    44799:  543:    pollinfo->read_progress_update_fn = fn;
        -:  544:
    44799:  545:    MPIDU_SOCKI_POLLFD_OP_SET(pollfd, pollinfo, POLLIN);
        -:  546:
    44799:  547:  fn_exit:
        -:  548:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_SOCK_POST_READV);
    44799:  549:    return mpi_errno;
        -:  550:}
        -:  551:/* end MPIDU_Sock_post_readv() */
        -:  552:
        -:  553:
        -:  554:#undef FUNCNAME
        -:  555:#define FUNCNAME MPIDU_Sock_post_write
        -:  556:#undef FCNAME
        -:  557:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  558:int MPIDU_Sock_post_write(struct MPIDU_Sock * sock, void * buf, MPIU_Size_t minlen, MPIU_Size_t maxlen,
        -:  559:			  MPIDU_Sock_progress_update_func_t fn)
     8731:  560:{
        -:  561:    struct pollfd * pollfd;
        -:  562:    struct pollinfo * pollinfo;
     8731:  563:    int mpi_errno = MPI_SUCCESS;
        -:  564:    MPIDI_STATE_DECL(MPID_STATE_MPIDU_SOCK_POST_WRITE);
        -:  565:
        -:  566:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_SOCK_POST_WRITE);
        -:  567:    
        -:  568:    MPIDU_SOCKI_VERIFY_INIT(mpi_errno, fn_exit);
        -:  569:    MPIDU_SOCKI_VALIDATE_SOCK(sock, mpi_errno, fn_exit);
        -:  570:
     8731:  571:    pollfd = MPIDU_Socki_sock_get_pollfd(sock);
     8731:  572:    pollinfo = MPIDU_Socki_sock_get_pollinfo(sock);
        -:  573:
        -:  574:    MPIDU_SOCKI_VALIDATE_FD(pollinfo, mpi_errno, fn_exit);
        -:  575:    MPIDU_SOCKI_VERIFY_CONNECTED_WRITABLE(pollinfo, mpi_errno, fn_exit);
        -:  576:    MPIDU_SOCKI_VERIFY_NO_POSTED_WRITE(pollfd, pollinfo, mpi_errno, fn_exit);
        -:  577:
        -:  578:    /* --BEGIN ERROR HANDLING-- */
     8731:  579:    if (minlen < 1 || minlen > maxlen)
        -:  580:    {
    #####:  581:	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_BAD_LEN,
        -:  582:					 "**sock|badlen", "**sock|badlen %d %d %d %d",
        -:  583:					 pollinfo->sock_set->id, pollinfo->sock_id, minlen, maxlen);
    #####:  584:	goto fn_exit;
        -:  585:    }
        -:  586:    /* --END ERROR HANDLING-- */
        -:  587:
     8731:  588:    pollinfo->write.buf.ptr = buf;
     8731:  589:    pollinfo->write.buf.min = minlen;
     8731:  590:    pollinfo->write.buf.max = maxlen;
     8731:  591:    pollinfo->write_iov_flag = FALSE;
     8731:  592:    pollinfo->write_nb = 0;
     8731:  593:    pollinfo->write_progress_update_fn = fn;
        -:  594:
     8731:  595:    MPIDU_SOCKI_POLLFD_OP_SET(pollfd, pollinfo, POLLOUT);
        -:  596:
     8731:  597:  fn_exit:
        -:  598:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_SOCK_POST_WRITE);
     8731:  599:    return mpi_errno;
        -:  600:}
        -:  601:/* end MPIDU_Sock_post_write() */
        -:  602:
        -:  603:
        -:  604:#undef FUNCNAME
        -:  605:#define FUNCNAME MPIDU_Sock_post_writev
        -:  606:#undef FCNAME
        -:  607:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  608:int MPIDU_Sock_post_writev(struct MPIDU_Sock * sock, MPID_IOV * iov, int iov_n, MPIDU_Sock_progress_update_func_t fn)
    46734:  609:{
        -:  610:    struct pollfd * pollfd;
        -:  611:    struct pollinfo * pollinfo;
    46734:  612:    int mpi_errno = MPI_SUCCESS;
        -:  613:    MPIDI_STATE_DECL(MPID_STATE_MPIDU_SOCK_POST_WRITEV);
        -:  614:
        -:  615:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_SOCK_POST_WRITEV);
        -:  616:    
        -:  617:    MPIDU_SOCKI_VERIFY_INIT(mpi_errno, fn_exit);
        -:  618:    MPIDU_SOCKI_VALIDATE_SOCK(sock, mpi_errno, fn_exit);
        -:  619:
    46734:  620:    pollfd = MPIDU_Socki_sock_get_pollfd(sock);
    46734:  621:    pollinfo = MPIDU_Socki_sock_get_pollinfo(sock);
        -:  622:
        -:  623:    MPIDU_SOCKI_VALIDATE_FD(pollinfo, mpi_errno, fn_exit);
        -:  624:    MPIDU_SOCKI_VERIFY_CONNECTED_WRITABLE(pollinfo, mpi_errno, fn_exit);
        -:  625:    MPIDU_SOCKI_VERIFY_NO_POSTED_WRITE(pollfd, pollinfo, mpi_errno, fn_exit);
        -:  626:
        -:  627:    /* --BEGIN ERROR HANDLING-- */
    46734:  628:    if (iov_n < 1 || iov_n > MPID_IOV_LIMIT)
        -:  629:    {
    #####:  630:	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_BAD_LEN,
        -:  631:					 "**sock|badiovn", "**sock|badiovn %d %d %d",
        -:  632:					 pollinfo->sock_set->id, pollinfo->sock_id, iov_n);
    #####:  633:	goto fn_exit;
        -:  634:    }
        -:  635:    /* --END ERROR HANDLING-- */
        -:  636:
    46734:  637:    pollinfo->write.iov.ptr = iov;
    46734:  638:    pollinfo->write.iov.count = iov_n;
    46734:  639:    pollinfo->write.iov.offset = 0;
    46734:  640:    pollinfo->write_iov_flag = TRUE;
    46734:  641:    pollinfo->write_nb = 0;
    46734:  642:    pollinfo->write_progress_update_fn = fn;
        -:  643:
    46734:  644:    MPIDU_SOCKI_POLLFD_OP_SET(pollfd, pollinfo, POLLOUT);
        -:  645:
    46734:  646:  fn_exit:
        -:  647:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_SOCK_POST_WRITEV);
    46734:  648:    return mpi_errno;
        -:  649:}
        -:  650:/* end MPIDU_Sock_post_writev() */
        -:  651:
        -:  652:
        -:  653:#undef FUNCNAME
        -:  654:#define FUNCNAME MPIDU_Sock_post_close
        -:  655:#undef FCNAME
        -:  656:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  657:int MPIDU_Sock_post_close(struct MPIDU_Sock * sock)
    20446:  658:{
        -:  659:    struct pollfd * pollfd;
        -:  660:    struct pollinfo * pollinfo;
        -:  661:    
    20446:  662:    int mpi_errno = MPI_SUCCESS;
        -:  663:    MPIDI_STATE_DECL(MPID_STATE_MPIDU_SOCK_POST_CLOSE);
        -:  664:
        -:  665:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_SOCK_POST_CLOSE);
        -:  666:
        -:  667:    MPIDU_SOCKI_VERIFY_INIT(mpi_errno, fn_exit);
        -:  668:    MPIDU_SOCKI_VALIDATE_SOCK(sock, mpi_errno, fn_exit);
        -:  669:
    20446:  670:    pollfd = MPIDU_Socki_sock_get_pollfd(sock);
    20446:  671:    pollinfo = MPIDU_Socki_sock_get_pollinfo(sock);
        -:  672:
        -:  673:    MPIDU_SOCKI_VALIDATE_FD(pollinfo, mpi_errno, fn_exit);
        -:  674:
        -:  675:    /* --BEGIN ERROR HANDLING-- */
    20446:  676:    if (pollinfo->state == MPIDU_SOCKI_STATE_CLOSING)
        -:  677:    {
    #####:  678:	mpi_errno = MPIR_Err_create_code(
        -:  679:	    mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_BAD_SOCK, "**sock|closing_already",
        -:  680:	    "**sock|closing_already %d %d", pollinfo->sock_set->id, pollinfo->sock_id);
    #####:  681:	goto fn_exit;
        -:  682:    }
        -:  683:    /* --END ERROR HANDLING-- */
        -:  684:
    20446:  685:    if (pollinfo->type == MPIDU_SOCKI_TYPE_COMMUNICATION)
        -:  686:    {
    16072:  687:	if (MPIDU_SOCKI_POLLFD_OP_ISSET(pollfd, pollinfo, POLLIN | POLLOUT))
        -:  688:	{
        -:  689:	    /* --BEGIN ERROR HANDLING-- */
        -:  690:	    int event_mpi_errno;
        -:  691:	    
    #####:  692:	    event_mpi_errno = MPIR_Err_create_code(
        -:  693:		MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_SOCK_CLOSED, "**sock|close_cancel",
        -:  694:		"**sock|close_cancel %d %d", pollinfo->sock_set->id, pollinfo->sock_id);
        -:  695:	    
    #####:  696:	    if (MPIDU_SOCKI_POLLFD_OP_ISSET(pollfd, pollinfo, POLLIN))
        -:  697:	    {
    #####:  698:		MPIDU_SOCKI_EVENT_ENQUEUE(pollinfo, MPIDU_SOCK_OP_READ, pollinfo->read_nb, pollinfo->user_ptr,
        -:  699:					  MPI_SUCCESS, mpi_errno, fn_exit);
        -:  700:	    }
        -:  701:
    #####:  702:	    if (MPIDU_SOCKI_POLLFD_OP_ISSET(pollfd, pollinfo, POLLOUT))
        -:  703:	    {
    #####:  704:		MPIDU_SOCKI_EVENT_ENQUEUE(pollinfo, MPIDU_SOCK_OP_WRITE, pollinfo->write_nb, pollinfo->user_ptr,
        -:  705:					  MPI_SUCCESS, mpi_errno, fn_exit);
        -:  706:	    }
        -:  707:	
    #####:  708:	    MPIDU_SOCKI_POLLFD_OP_CLEAR(pollfd, pollinfo, POLLIN | POLLOUT);
        -:  709:	    /* --END ERROR HANDLING-- */
        -:  710:	}
        -:  711:    }
        -:  712:    else /* if (pollinfo->type == MPIDU_SOCKI_TYPE_LISTENER) */
        -:  713:    {
        -:  714:	/*
        -:  715:	 * The event queue may contain an accept event which means that 
        -:  716:	 * MPIDU_Sock_accept() may be legally called after
        -:  717:	 * MPIDU_Sock_post_close().  However, MPIDU_Sock_accept() must be 
        -:  718:	 * called before the close event is return by
        -:  719:	 * MPIDU_Sock_wait().
        -:  720:	 */
     4374:  721:	MPIDU_SOCKI_POLLFD_OP_CLEAR(pollfd, pollinfo, POLLIN);
        -:  722:    }
        -:  723:    
    20446:  724:    MPIDU_SOCKI_EVENT_ENQUEUE(pollinfo, MPIDU_SOCK_OP_CLOSE, 0, pollinfo->user_ptr, MPI_SUCCESS, mpi_errno, fn_exit);
    20446:  725:    pollinfo->state = MPIDU_SOCKI_STATE_CLOSING;
        -:  726:
    20446:  727:  fn_exit:
        -:  728:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_SOCK_POST_CLOSE);
    20446:  729:    return mpi_errno;
        -:  730:}
        -:  731:
        -:  732: