-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/common/sock/poll/sock_immed.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:
        -:    9:/* FIXME: Why is this the _immed file (what does immed stand for?) */
        -:   10:
        -:   11:/* FIXME: What do any of these routines do?  What are the arguments?
        -:   12:   Special conditions (see the FIXME on len = SSIZE_MAX)?  preconditions?
        -:   13:   postconditions? */
        -:   14:
        -:   15:/* FIXME: What does this function do?  What are its arguments?
        -:   16:   It appears to execute a nonblocking accept call */
        -:   17:#undef FUNCNAME
        -:   18:#define FUNCNAME MPIDU_Sock_accept
        -:   19:#undef FCNAME
        -:   20:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:   21:int MPIDU_Sock_accept(struct MPIDU_Sock * listener, 
        -:   22:		      struct MPIDU_Sock_set * sock_set, void * user_ptr,
        -:   23:		      struct MPIDU_Sock ** sockp)
     8040:   24:{
        -:   25:    struct MPIDU_Sock * sock;
        -:   26:    struct pollfd * pollfd;
        -:   27:    struct pollinfo * pollinfo;
     8040:   28:    int fd = -1;
        -:   29:    struct sockaddr_in addr;
        -:   30:    socklen_t addr_len;
        -:   31:    long flags;
        -:   32:    int nodelay;
        -:   33:    int rc;
     8040:   34:    int mpi_errno = MPI_SUCCESS;
        -:   35:    MPIDI_STATE_DECL(MPID_STATE_MPIDU_SOCK_ACCEPT);
        -:   36:
        -:   37:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_SOCK_ACCEPT);
        -:   38:
        -:   39:    MPIDU_SOCKI_VERIFY_INIT(mpi_errno, fn_exit);
        -:   40:    MPIDU_SOCKI_VALIDATE_SOCK(listener, mpi_errno, fn_exit);
        -:   41:    MPIDU_SOCKI_VALIDATE_SOCK_SET(sock_set, mpi_errno, fn_exit);
        -:   42:
     8040:   43:    pollfd = MPIDU_Socki_sock_get_pollfd(listener);
     8040:   44:    pollinfo = MPIDU_Socki_sock_get_pollinfo(listener);
        -:   45:
        -:   46:    /* --BEGIN ERROR HANDLING-- */
     8040:   47:    if (pollinfo->type != MPIDU_SOCKI_TYPE_LISTENER)
        -:   48:    {
    #####:   49:	mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, 
        -:   50:		 FCNAME, __LINE__, MPIDU_SOCK_ERR_BAD_SOCK,
        -:   51:		 "**sock|listener_bad_sock", "**sock|listener_bad_sock %d %d",
        -:   52:		 pollinfo->sock_set->id, pollinfo->sock_id);
    #####:   53:	goto fn_exit;
        -:   54:    }
        -:   55:    
     8040:   56:    if (pollinfo->state != MPIDU_SOCKI_STATE_CONNECTED_RO && 
        -:   57:	pollinfo->state != MPIDU_SOCKI_STATE_CLOSING)
        -:   58:    {
    #####:   59:	mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, 
        -:   60:		FCNAME, __LINE__, MPIDU_SOCK_ERR_BAD_SOCK,
        -:   61:	     "**sock|listener_bad_state", "**sock|listener_bad_state %d %d %d",
        -:   62:		pollinfo->sock_set->id, pollinfo->sock_id, pollinfo->state);
    #####:   63:	goto fn_exit;
        -:   64:    }
        -:   65:    /* --END ERROR HANDLING-- */
        -:   66:
        -:   67:    /*
        -:   68:     * Get a socket for the new connection from the operating system.  
        -:   69:     * Make the socket nonblocking, and disable Nagle's
        -:   70:     * alogorithm (to minimize latency of small messages).
        -:   71:     */
     8040:   72:    addr_len = sizeof(struct sockaddr_in);
        -:   73:    /* FIXME: Either use the syscall macro or correctly wrap this in a
        -:   74:       test for EINTR */
     8040:   75:    fd = accept(pollinfo->fd, (struct sockaddr *) &addr, &addr_len);
        -:   76:
     8040:   77:    if (pollinfo->state != MPIDU_SOCKI_STATE_CLOSING)
        -:   78:    {
        -:   79:	/*
        -:   80:	 * Unless the listener sock is being closed, add it back into the 
        -:   81:	 * poll list so that new connections will be detected.
        -:   82:	 */
     8040:   83:	MPIDU_SOCKI_POLLFD_OP_SET(pollfd, pollinfo, POLLIN);
        -:   84:    }
        -:   85:
        -:   86:    /* --BEGIN ERROR HANDLING-- */
     8040:   87:    if (fd == -1)
        -:   88:    {
    #####:   89:	if (errno == EAGAIN || errno == EWOULDBLOCK)
        -:   90:	{
    #####:   91:	    mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, 
        -:   92:			     FCNAME, __LINE__, MPIDU_SOCK_ERR_NO_NEW_SOCK,
        -:   93:			     "**sock|nosock", NULL);
        -:   94:	}
    #####:   95:	else if (errno == ENOBUFS || errno == ENOMEM)
        -:   96:	{
    #####:   97:	    mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, 
        -:   98:				FCNAME, __LINE__, MPIDU_SOCK_ERR_NOMEM,
        -:   99:				"**sock|osnomem", NULL);
        -:  100:	}
    #####:  101:	else if (errno == EBADF || errno == ENOTSOCK || errno == EOPNOTSUPP)
        -:  102:	{
    #####:  103:	    mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, 
        -:  104:                           FCNAME, __LINE__, MPIDU_SOCK_ERR_BAD_SOCK,
        -:  105:			  "**sock|badhandle", "**sock|poll|badhandle %d %d %d",
        -:  106:			  pollinfo->sock_set->id, pollinfo->sock_id, 
        -:  107:			  pollinfo->fd);
        -:  108:	}
        -:  109:	else
        -:  110:	{
    #####:  111:	    mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
        -:  112:                           FCNAME, __LINE__, MPIDU_SOCK_ERR_NO_NEW_SOCK,
        -:  113:			   "**sock|poll|accept", "**sock|poll|accept %d %s", 
        -:  114:			   errno, MPIU_Strerror(errno));
        -:  115:	}
        -:  116:	
        -:  117:	goto fn_fail;
        -:  118:    }
        -:  119:    /* --END ERROR HANDLING-- */
        -:  120:
     8040:  121:    flags = fcntl(fd, F_GETFL, 0);
        -:  122:    /* FIXME: There should be a simpler macro for reporting errno messages */
        -:  123:    /* --BEGIN ERROR HANDLING-- */
     8040:  124:    if (flags == -1)
        -:  125:    {
    #####:  126:	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, 
        -:  127:			 FCNAME, __LINE__, MPIDU_SOCK_ERR_FAIL,
        -:  128:			 "**sock|poll|nonblock", "**sock|poll|nonblock %d %s", 
        -:  129:			 errno, MPIU_Strerror(errno));
    #####:  130:	goto fn_fail;
        -:  131:    }
        -:  132:    /* --END ERROR HANDLING-- */
     8040:  133:    rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
        -:  134:    /* --BEGIN ERROR HANDLING-- */
     8040:  135:    if (rc == -1)
        -:  136:    {
    #####:  137:	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, 
        -:  138:			 FCNAME, __LINE__, MPIDU_SOCK_ERR_FAIL,
        -:  139:			 "**sock|poll|nonblock", "**sock|poll|nonblock %d %s",
        -:  140:			 errno, MPIU_Strerror(errno));
    #####:  141:	goto fn_fail;
        -:  142:    }
        -:  143:    /* --END ERROR HANDLING-- */
        -:  144:
     8040:  145:    nodelay = 1;
     8040:  146:    rc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay));
        -:  147:    /* --BEGIN ERROR HANDLING-- */
     8040:  148:    if (rc != 0)
        -:  149:    {
    #####:  150:	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, 
        -:  151:			 FCNAME, __LINE__, MPIDU_SOCK_ERR_FAIL,
        -:  152:			 "**sock|poll|nodelay", "**sock|poll|nodelay %d %s", 
        -:  153:                         errno, MPIU_Strerror(errno));
    #####:  154:	goto fn_fail;
        -:  155:    }
        -:  156:    /* --END ERROR HANDLING-- */
        -:  157:
        -:  158:    /*
        -:  159:     * Verify that the socket buffer size is correct
        -:  160:     */
        -:  161:    /* FIXME: Who sets the socket buffer size?  Why isn't the test
        -:  162:       made at that time? */
        -:  163:#if 1
     8040:  164:    mpi_errno = MPIDU_Sock_SetSockBufferSize( fd, 1 );
     8040:  165:    if (mpi_errno) { MPIU_ERR_POP(mpi_errno); }
        -:  166:#else
        -:  167:    if (MPIDU_Socki_socket_bufsz > 0)
        -:  168:    {
        -:  169:	int bufsz;
        -:  170:	socklen_t bufsz_len;
        -:  171:
        -:  172:	bufsz_len = sizeof(bufsz);
        -:  173:	rc = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &bufsz, &bufsz_len);
        -:  174:	/* FIXME: There's normally no need to check that the socket buffer
        -:  175:	   size was set to the requested size.  This should only be part of
        -:  176:	   some more verbose diagnostic output, not a general action */
        -:  177:	/* --BEGIN ERROR HANDLING-- */
        -:  178:	if (rc == 0)
        -:  179:	{
        -:  180:	    if (bufsz < MPIDU_Socki_socket_bufsz * 0.9 || 
        -:  181:		bufsz < MPIDU_Socki_socket_bufsz * 1.0)
        -:  182:	    {
        -:  183:		MPIU_Msg_printf("WARNING: send socket buffer size differs from requested size (requested=%d, actual=%d)\n",
        -:  184:				MPIDU_Socki_socket_bufsz, bufsz);
        -:  185:	    }
        -:  186:	}
        -:  187:	/* --END ERROR HANDLING-- */
        -:  188:
        -:  189:    	bufsz_len = sizeof(bufsz);
        -:  190:	rc = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &bufsz, &bufsz_len);
        -:  191:	/* FIXME: There's normally no need to check that the socket buffer
        -:  192:	   size was set to the requested size.  This should only be part of
        -:  193:	   some more verbose diagnostic output, not a general action */
        -:  194:	/* FIXME: Cut and paste code is a disaster waiting to happen. 
        -:  195:	   Particularly in any non-performance critical section,
        -:  196:	   create a separate routine instead of using cut and paste. */
        -:  197:	/* --BEGIN ERROR HANDLING-- */
        -:  198:	if (rc == 0)
        -:  199:	{
        -:  200:	    if (bufsz < MPIDU_Socki_socket_bufsz * 0.9 || 
        -:  201:		bufsz < MPIDU_Socki_socket_bufsz * 1.0)
        -:  202:	    {
        -:  203:		MPIU_Msg_printf("WARNING: receive socket buffer size differs from requested size (requested=%d, actual=%d)\n",
        -:  204:				MPIDU_Socki_socket_bufsz, bufsz);
        -:  205:	    }
        -:  206:	}
        -:  207:	/* --END ERROR HANDLING-- */
        -:  208:    }
        -:  209:#endif    
        -:  210:    /*
        -:  211:     * Allocate and initialize sock and poll structures.
        -:  212:     *
        -:  213:     * NOTE: pollfd->fd is initialized to -1.  It is only set to the true fd 
        -:  214:     * value when an operation is posted on the sock.  This
        -:  215:     * (hopefully) eliminates a little overhead in the OS and avoids 
        -:  216:     * repetitive POLLHUP events when the connection is closed by
        -:  217:     * the remote process.
        -:  218:     */
     8040:  219:    mpi_errno = MPIDU_Socki_sock_alloc(sock_set, &sock);
        -:  220:    /* --BEGIN ERROR HANDLING-- */
     8040:  221:    if (mpi_errno != MPI_SUCCESS)
        -:  222:    {
    #####:  223:	mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPIDU_SOCK_ERR_NOMEM,
        -:  224:					 "**sock|sockalloc", NULL);
    #####:  225:	goto fn_fail;
        -:  226:    }
        -:  227:    /* --END ERROR HANDLING-- */
        -:  228:    
     8040:  229:    pollfd = MPIDU_Socki_sock_get_pollfd(sock);
     8040:  230:    pollinfo = MPIDU_Socki_sock_get_pollinfo(sock);
        -:  231:
     8040:  232:    pollinfo->fd = fd;
     8040:  233:    pollinfo->user_ptr = user_ptr;
     8040:  234:    pollinfo->type = MPIDU_SOCKI_TYPE_COMMUNICATION;
     8040:  235:    pollinfo->state = MPIDU_SOCKI_STATE_CONNECTED_RW;
     8040:  236:    pollinfo->os_errno = 0;
        -:  237:    
     8040:  238:    *sockp = sock;
        -:  239:
     8040:  240:  fn_exit:
        -:  241:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_SOCK_ACCEPT);
     8040:  242:    return mpi_errno;
        -:  243:
        -:  244:    /* --BEGIN ERROR HANDLING-- */
    #####:  245:  fn_fail:
    #####:  246:    if (fd != -1)
        -:  247:    {
    #####:  248:	close(fd);
        -:  249:    }
        -:  250:
        -:  251:    goto fn_exit;
        -:  252:    /* --END ERROR HANDLING-- */
        -:  253:}
        -:  254:/* end MPIDU_Sock_accept() */
        -:  255:
        -:  256:
        -:  257:#undef FUNCNAME
        -:  258:#define FUNCNAME MPIDU_Sock_read
        -:  259:#undef FCNAME
        -:  260:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  261:int MPIDU_Sock_read(MPIDU_Sock_t sock, void * buf, MPIU_Size_t len, 
        -:  262:		    MPIU_Size_t * num_read)
    #####:  263:{
        -:  264:    struct pollfd * pollfd;
        -:  265:    struct pollinfo * pollinfo;
        -:  266:    size_t nb;
    #####:  267:    int mpi_errno = MPI_SUCCESS;
        -:  268:    MPIDI_STATE_DECL(MPID_STATE_READ);
        -:  269:    MPIDI_STATE_DECL(MPID_STATE_MPIDU_SOCK_READ);
        -:  270:
        -:  271:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_SOCK_READ);
        -:  272:
        -:  273:    MPIDU_SOCKI_VERIFY_INIT(mpi_errno, fn_exit);
        -:  274:    MPIDU_SOCKI_VALIDATE_SOCK(sock, mpi_errno, fn_exit);
        -:  275:
    #####:  276:    pollfd = MPIDU_Socki_sock_get_pollfd(sock);
    #####:  277:    pollinfo = MPIDU_Socki_sock_get_pollinfo(sock);
        -:  278:
        -:  279:    MPIDU_SOCKI_VALIDATE_FD(pollinfo, mpi_errno, fn_exit);
        -:  280:    MPIDU_SOCKI_VERIFY_CONNECTED_READABLE(pollinfo, mpi_errno, fn_exit);
        -:  281:    MPIDU_SOCKI_VERIFY_NO_POSTED_READ(pollfd, pollinfo, mpi_errno, fn_exit);
        -:  282:    
        -:  283:    /* FIXME: multiple passes should be made if 
        -:  284:       len > SSIZE_MAX and nb == SSIZE_MAX */
        -:  285:    /* FIXME: This is a scary test/assignment.  It needs an explanation 
        -:  286:       (presumably that this routine will be called again if len is 
        -:  287:       shortened.  However, in that case, the description of the routine 
        -:  288:       (which is also missing!!!!) needs to be very clear about this
        -:  289:       requirement.  */
    #####:  290:    if (len > SSIZE_MAX)
        -:  291:    {
    #####:  292:	len = SSIZE_MAX;
        -:  293:    }
        -:  294:    
        -:  295:    do
        -:  296:    {
        -:  297:	MPIDI_FUNC_ENTER(MPID_STATE_READ);
    #####:  298:	nb = read(pollinfo->fd, buf, len);
        -:  299:	MPIDI_FUNC_EXIT(MPID_STATE_READ);
        -:  300:    }
    #####:  301:    while (nb == -1 && errno == EINTR);
        -:  302:
    #####:  303:    if (nb > 0)
        -:  304:    {
    #####:  305:	*num_read = (MPIU_Size_t) nb;
        -:  306:    }
        -:  307:    /* --BEGIN ERROR HANDLING-- */
    #####:  308:    else if (nb == 0)
        -:  309:    {
    #####:  310:	*num_read = 0;
        -:  311:	
    #####:  312:	mpi_errno = MPIR_Err_create_code(
        -:  313:	    MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, 
        -:  314:	    MPIDU_SOCK_ERR_CONN_CLOSED,
        -:  315:	    "**sock|connclosed", "**sock|connclosed %d %d", 
        -:  316:	    pollinfo->sock_set->id, pollinfo->sock_id);
        -:  317:	
    #####:  318:	if (MPIDU_SOCKI_POLLFD_OP_ISSET(pollfd, pollinfo, POLLOUT))
        -:  319:	{ 
        -:  320:	    /* A write is posted on this connection.  Enqueue an event for
        -:  321:	       the write indicating the connection is closed. */
    #####:  322:	    MPIDU_SOCKI_EVENT_ENQUEUE(pollinfo, MPIDU_SOCK_OP_WRITE,
        -:  323:				      pollinfo->write_nb, pollinfo->user_ptr,
        -:  324:				      mpi_errno, mpi_errno, fn_exit);
    #####:  325:	    MPIDU_SOCKI_POLLFD_OP_CLEAR(pollfd, pollinfo, POLLOUT);
        -:  326:	}
        -:  327:	
    #####:  328:	pollinfo->state = MPIDU_SOCKI_STATE_DISCONNECTED;
        -:  329:    }
    #####:  330:    else if (errno == EAGAIN || errno == EWOULDBLOCK)
        -:  331:    {
    #####:  332:	*num_read = 0;
        -:  333:    }
        -:  334:    else
        -:  335:    {
        -:  336:	int disconnected;
        -:  337:	
    #####:  338:	*num_read = 0;
        -:  339:	
    #####:  340:	mpi_errno = MPIDU_Socki_os_to_mpi_errno(pollinfo, errno, 
        -:  341:					    FCNAME, __LINE__, &disconnected);
    #####:  342:	if (MPIR_Err_is_fatal(mpi_errno))
        -:  343:	{
        -:  344:	    /*
        -:  345:	     * A serious error occurred.  There is no guarantee that the 
        -:  346:	     * data structures are still intact.  Therefore, we avoid
        -:  347:	     * modifying them.
        -:  348:	     */
    #####:  349:	    goto fn_exit;
        -:  350:	}
        -:  351:
    #####:  352:	if (disconnected)
        -:  353:	{
    #####:  354:	    if (MPIDU_SOCKI_POLLFD_OP_ISSET(pollfd, pollinfo, POLLOUT))
        -:  355:	    { 
        -:  356:		/* A write is posted on this connection.  Enqueue an event 
        -:  357:		   for the write indicating the connection is closed. */
    #####:  358:		MPIDU_SOCKI_EVENT_ENQUEUE(pollinfo, MPIDU_SOCK_OP_WRITE, 
        -:  359:					pollinfo->write_nb, pollinfo->user_ptr,
        -:  360:					mpi_errno, mpi_errno, fn_exit);
    #####:  361:		MPIDU_SOCKI_POLLFD_OP_CLEAR(pollfd, pollinfo, POLLOUT);
        -:  362:	    }
        -:  363:	    
    #####:  364:	    pollinfo->state = MPIDU_SOCKI_STATE_DISCONNECTED;
        -:  365:	}
        -:  366:    }
        -:  367:    /* --END ERROR HANDLING-- */
        -:  368:
    #####:  369:  fn_exit:
        -:  370:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_SOCK_READ);
    #####:  371:    return mpi_errno;
        -:  372:}
        -:  373:/* end MPIDU_Sock_read() */
        -:  374:
        -:  375:
        -:  376:#undef FUNCNAME
        -:  377:#define FUNCNAME MPIDU_Sock_readv
        -:  378:#undef FCNAME
        -:  379:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  380:int MPIDU_Sock_readv(MPIDU_Sock_t sock, MPID_IOV * iov, int iov_n, 
        -:  381:		     MPIU_Size_t * num_read)
 10087490:  382:{
        -:  383:    struct pollfd * pollfd;
        -:  384:    struct pollinfo * pollinfo;
        -:  385:    ssize_t nb;
 10087490:  386:    int mpi_errno = MPI_SUCCESS;
        -:  387:    MPIDI_STATE_DECL(MPID_STATE_READV);
        -:  388:    MPIDI_STATE_DECL(MPID_STATE_MPIDU_SOCK_READV);
        -:  389:
        -:  390:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_SOCK_READV);
        -:  391:    
        -:  392:    MPIDU_SOCKI_VERIFY_INIT(mpi_errno, fn_exit);
        -:  393:    MPIDU_SOCKI_VALIDATE_SOCK(sock, mpi_errno, fn_exit);
        -:  394:
 10087490:  395:    pollfd = MPIDU_Socki_sock_get_pollfd(sock);
 10087490:  396:    pollinfo = MPIDU_Socki_sock_get_pollinfo(sock);
        -:  397:
        -:  398:    MPIDU_SOCKI_VALIDATE_FD(pollinfo, mpi_errno, fn_exit);
        -:  399:    MPIDU_SOCKI_VERIFY_CONNECTED_READABLE(pollinfo, mpi_errno, fn_exit);
        -:  400:    MPIDU_SOCKI_VERIFY_NO_POSTED_READ(pollfd, pollinfo, mpi_errno, fn_exit);
        -:  401:
        -:  402:    /*
        -:  403:     * FIXME: The IEEE 1003.1 standard says that if the sum of the iov_len 
        -:  404:     * fields exceeds SSIZE_MAX, an errno of EINVAL will be
        -:  405:     * returned.  How do we handle this?  Can we place an equivalent 
        -:  406:     * limitation in the Sock interface?
        -:  407:     */
        -:  408:    do
        -:  409:    {
        -:  410:	MPIDI_FUNC_ENTER(MPID_STATE_READV);
 10087490:  411:	nb = readv(pollinfo->fd, iov, iov_n);
        -:  412:	MPIDI_FUNC_EXIT(MPID_STATE_READV);
        -:  413:    }
 10087490:  414:    while (nb == -1 && errno == EINTR);
        -:  415:
 10087490:  416:    if (nb > 0)
        -:  417:    {
 10087490:  418:	*num_read = (MPIU_Size_t) nb;
        -:  419:    }
        -:  420:    /* --BEGIN ERROR HANDLING-- */
    #####:  421:    else if (nb == 0)
        -:  422:    {
    #####:  423:	*num_read = 0;
        -:  424:	
    #####:  425:	mpi_errno = MPIR_Err_create_code(
        -:  426:	    MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, 
        -:  427:	    MPIDU_SOCK_ERR_CONN_CLOSED,
        -:  428:	    "**sock|connclosed", "**sock|connclosed %d %d", 
        -:  429:	    pollinfo->sock_set->id, pollinfo->sock_id);
        -:  430:	
    #####:  431:	if (MPIDU_SOCKI_POLLFD_OP_ISSET(pollfd, pollinfo, POLLOUT))
        -:  432:	{ 
        -:  433:	    
        -:  434:	    /* A write is posted on this connection.  Enqueue an event 
        -:  435:	       for the write indicating the connection is closed. */
    #####:  436:	    MPIDU_SOCKI_EVENT_ENQUEUE(pollinfo, MPIDU_SOCK_OP_WRITE, 
        -:  437:				      pollinfo->write_nb, pollinfo->user_ptr,
        -:  438:				      mpi_errno, mpi_errno, fn_exit);
    #####:  439:	    MPIDU_SOCKI_POLLFD_OP_CLEAR(pollfd, pollinfo, POLLOUT);
        -:  440:	}
        -:  441:	
    #####:  442:	pollinfo->state = MPIDU_SOCKI_STATE_DISCONNECTED;
        -:  443:    }
    #####:  444:    else if (errno == EAGAIN || errno == EWOULDBLOCK)
        -:  445:    {
    #####:  446:	*num_read = 0;
        -:  447:    }
        -:  448:    else
        -:  449:    {
        -:  450:	int disconnected;
        -:  451:	
    #####:  452:	*num_read = 0;
        -:  453:	
    #####:  454:	mpi_errno = MPIDU_Socki_os_to_mpi_errno(pollinfo, errno, FCNAME,
        -:  455:						__LINE__, &disconnected);
    #####:  456:	if (MPIR_Err_is_fatal(mpi_errno))
        -:  457:	{
        -:  458:	    /*
        -:  459:	     * A serious error occurred.  There is no guarantee that the 
        -:  460:	     * data structures are still intact.  Therefore, we avoid
        -:  461:	     * modifying them.
        -:  462:	     */
    #####:  463:	    goto fn_exit;
        -:  464:	}
        -:  465:
    #####:  466:	if (disconnected)
        -:  467:	{
    #####:  468:	    if (MPIDU_SOCKI_POLLFD_OP_ISSET(pollfd, pollinfo, POLLOUT))
        -:  469:	    { 
        -:  470:		/* A write is posted on this connection.  Enqueue an event 
        -:  471:		   for the write indicating the connection is closed. */
    #####:  472:		MPIDU_SOCKI_EVENT_ENQUEUE(pollinfo, MPIDU_SOCK_OP_WRITE, 
        -:  473:					pollinfo->write_nb, pollinfo->user_ptr,
        -:  474:					  mpi_errno, mpi_errno, fn_exit);
    #####:  475:		MPIDU_SOCKI_POLLFD_OP_CLEAR(pollfd, pollinfo, POLLOUT);
        -:  476:	    }
        -:  477:	    
    #####:  478:	    pollinfo->state = MPIDU_SOCKI_STATE_DISCONNECTED;
        -:  479:	}
        -:  480:    }
        -:  481:    /* --END ERROR HANDLING-- */
        -:  482:
 10087490:  483:  fn_exit:
        -:  484:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_SOCK_READV);
 10087490:  485:    return mpi_errno;
        -:  486:}
        -:  487:/* end MPIDU_Sock_readv() */
        -:  488:
        -:  489:
        -:  490:#undef FUNCNAME
        -:  491:#define FUNCNAME MPIDU_Sock_write
        -:  492:#undef FCNAME
        -:  493:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  494:int MPIDU_Sock_write(MPIDU_Sock_t sock, void * buf, MPIU_Size_t len, 
        -:  495:		     MPIU_Size_t * num_written)
  5964324:  496:{
        -:  497:    struct pollfd * pollfd;
        -:  498:    struct pollinfo * pollinfo;
        -:  499:    ssize_t nb;
  5964324:  500:    int mpi_errno = MPI_SUCCESS;
        -:  501:    MPIDI_STATE_DECL(MPID_STATE_WRITE);
        -:  502:    MPIDI_STATE_DECL(MPID_STATE_MPIDU_SOCK_WRITE);
        -:  503:
        -:  504:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_SOCK_WRITE);
        -:  505:    
        -:  506:    MPIDU_SOCKI_VERIFY_INIT(mpi_errno, fn_exit);
        -:  507:    MPIDU_SOCKI_VALIDATE_SOCK(sock, mpi_errno, fn_exit);
        -:  508:
  5964324:  509:    pollfd = MPIDU_Socki_sock_get_pollfd(sock);
  5964324:  510:    pollinfo = MPIDU_Socki_sock_get_pollinfo(sock);
        -:  511:
        -:  512:    MPIDU_SOCKI_VERIFY_CONNECTED_WRITABLE(pollinfo, mpi_errno, fn_exit);
        -:  513:    MPIDU_SOCKI_VALIDATE_FD(pollinfo, mpi_errno, fn_exit);
        -:  514:    MPIDU_SOCKI_VERIFY_NO_POSTED_WRITE(pollfd, pollinfo, mpi_errno, fn_exit);
        -:  515:    
        -:  516:    /* FIXME: multiple passes should be made if len > SSIZE_MAX and nb == SSIZE_MAX */
  5964324:  517:    if (len > SSIZE_MAX)
        -:  518:    {
    #####:  519:	len = SSIZE_MAX;
        -:  520:    }
        -:  521:    
        -:  522:    do
        -:  523:    {
        -:  524:	MPIDI_FUNC_ENTER(MPID_STATE_WRITE);
  5964324:  525:	nb = write(pollinfo->fd, buf, len);
        -:  526:	MPIDI_FUNC_EXIT(MPID_STATE_WRITE);
        -:  527:    }
  5964324:  528:    while (nb == -1 && errno == EINTR);
        -:  529:
  5964324:  530:    if (nb >= 0)
        -:  531:    {
  5964311:  532:	*num_written = nb;
        -:  533:    }
        -:  534:    /* --BEGIN ERROR HANDLING-- */
       13:  535:    else if (errno == EAGAIN || errno == EWOULDBLOCK)
        -:  536:    {
       13:  537:	*num_written = 0;
        -:  538:    }
        -:  539:    else
        -:  540:    {
        -:  541:	int disconnected;
        -:  542:	
    #####:  543:	*num_written = 0;
        -:  544:	
    #####:  545:	mpi_errno = MPIDU_Socki_os_to_mpi_errno(pollinfo, errno, FCNAME, 
        -:  546:						__LINE__, &disconnected);
    #####:  547:	if (MPIR_Err_is_fatal(mpi_errno))
        -:  548:	{
        -:  549:	    /*
        -:  550:	     * A serious error occurred.  There is no guarantee that the data 
        -:  551:	     * structures are still intact.  Therefore, we avoid
        -:  552:	     * modifying them.
        -:  553:	     */
    #####:  554:	    goto fn_exit;
        -:  555:	}
        -:  556:
    #####:  557:	if (disconnected)
        -:  558:	{
        -:  559:	    /*
        -:  560:	     * The connection is dead but data may still be in the socket
        -:  561:	     * buffer; thus, we change the state and let
        -:  562:	     * MPIDU_Sock_wait() clean things up.
        -:  563:	     */
    #####:  564:	    pollinfo->state = MPIDU_SOCKI_STATE_CONNECTED_RO;
        -:  565:	}
        -:  566:    }
        -:  567:    /* --END ERROR HANDLING-- */
        -:  568:
  5964324:  569:  fn_exit:
        -:  570:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_SOCK_WRITE);
  5964324:  571:    return mpi_errno;
        -:  572:}
        -:  573:/* end MPIDU_Sock_write() */
        -:  574:
        -:  575:
        -:  576:#undef FUNCNAME
        -:  577:#define FUNCNAME MPIDU_Sock_writev
        -:  578:#undef FCNAME
        -:  579:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  580:int MPIDU_Sock_writev(MPIDU_Sock_t sock, MPID_IOV * iov, int iov_n, MPIU_Size_t * num_written)
 10067767:  581:{
        -:  582:    struct pollfd * pollfd;
        -:  583:    struct pollinfo * pollinfo;
        -:  584:    ssize_t nb;
 10067767:  585:    int mpi_errno = MPI_SUCCESS;
        -:  586:    MPIDI_STATE_DECL(MPID_STATE_WRITEV);
        -:  587:    MPIDI_STATE_DECL(MPID_STATE_MPIDU_SOCK_WRITEV);
        -:  588:
        -:  589:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_SOCK_WRITEV);
        -:  590:    
        -:  591:    MPIDU_SOCKI_VERIFY_INIT(mpi_errno, fn_exit);
        -:  592:    MPIDU_SOCKI_VALIDATE_SOCK(sock, mpi_errno, fn_exit);
        -:  593:
 10067767:  594:    pollfd = MPIDU_Socki_sock_get_pollfd(sock);
 10067767:  595:    pollinfo = MPIDU_Socki_sock_get_pollinfo(sock);
        -:  596:
        -:  597:    MPIDU_SOCKI_VALIDATE_FD(pollinfo, mpi_errno, fn_exit);
        -:  598:    MPIDU_SOCKI_VERIFY_CONNECTED_WRITABLE(pollinfo, mpi_errno, fn_exit);
        -:  599:    MPIDU_SOCKI_VERIFY_NO_POSTED_WRITE(pollfd, pollinfo, mpi_errno, fn_exit);
        -:  600:    
        -:  601:    /*
        -:  602:     * FIXME: The IEEE 1003.1 standard says that if the sum of the iov_len 
        -:  603:     * fields exceeds SSIZE_MAX, an errno of EINVAL will be
        -:  604:     * returned.  How do we handle this?  Can we place an equivalent 
        -:  605:     * limitation in the Sock interface?
        -:  606:     */
        -:  607:    do
        -:  608:    {
        -:  609:	MPIDI_FUNC_ENTER(MPID_STATE_WRITEV);
 10067767:  610:	nb = writev(pollinfo->fd, iov, iov_n);
        -:  611:	MPIDI_FUNC_EXIT(MPID_STATE_WRITEV);
        -:  612:    }
 10067767:  613:    while (nb == -1 && errno == EINTR);
        -:  614:
 10067767:  615:    if (nb >= 0)
        -:  616:    {
 10067699:  617:	*num_written = (MPIU_Size_t) nb;
        -:  618:    }
        -:  619:    /* --BEGIN ERROR HANDLING-- */
       68:  620:    else if (errno == EAGAIN || errno == EWOULDBLOCK)
        -:  621:    {
       68:  622:	*num_written = 0;
        -:  623:    }
        -:  624:    else
        -:  625:    {
        -:  626:	int disconnected;
        -:  627:	
    #####:  628:	*num_written = 0;
        -:  629:	
    #####:  630:	mpi_errno = MPIDU_Socki_os_to_mpi_errno(pollinfo, errno, FCNAME, 
        -:  631:						__LINE__, &disconnected);
    #####:  632:	if (MPIR_Err_is_fatal(mpi_errno))
        -:  633:	{
        -:  634:	    /*
        -:  635:	     * A serious error occurred.  There is no guarantee that the 
        -:  636:	     * data structures are still intact.  Therefore, we avoid
        -:  637:	     * modifying them.
        -:  638:	     */
    #####:  639:	    goto fn_exit;
        -:  640:	}
        -:  641:
    #####:  642:	if (disconnected)
        -:  643:	{
        -:  644:	    /*
        -:  645:	     * The connection is dead but data may still be in the socket 
        -:  646:	     * buffer; thus, we change the state and let
        -:  647:	     * MPIDU_Sock_wait() clean things up.
        -:  648:	     */
    #####:  649:	    pollinfo->state = MPIDU_SOCKI_STATE_CONNECTED_RO;
        -:  650:	}
        -:  651:    }
        -:  652:    /* --END ERROR HANDLING-- */
        -:  653:
 10067767:  654:  fn_exit:
        -:  655:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_SOCK_WRITEV);
 10067767:  656:    return mpi_errno;
        -:  657:}
        -:  658:/* end MPIDU_Sock_writev() */
        -:  659:
        -:  660:
        -:  661:#undef FUNCNAME
        -:  662:#define FUNCNAME MPIDU_Sock_wakeup
        -:  663:#undef FCNAME
        -:  664:#define FCNAME MPIU_QUOTE(FUNCNAME)
        -:  665:int MPIDU_Sock_wakeup(struct MPIDU_Sock_set * sock_set)
      101:  666:{
      101:  667:    int mpi_errno = MPI_SUCCESS;
        -:  668:    MPIDI_STATE_DECL(MPID_STATE_MPIDU_SOCK_WAKEUP);
        -:  669:
        -:  670:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_SOCK_WAKEUP);
        -:  671:
        -:  672:    MPIDU_SOCKI_VERIFY_INIT(mpi_errno, fn_exit);
        -:  673:    MPIDU_SOCKI_VALIDATE_SOCK_SET(sock_set, mpi_errno, fn_exit);
        -:  674:
        -:  675:    /* FIXME: We need (1) a standardized test for including multithreaded
        -:  676:       code and (2) include support for user requests for a lower-level
        -:  677:       of thread safety.  Finally, things like this should probably 
        -:  678:       be implemented as an abstraction (e.g., wakeup_progress_threads?)
        -:  679:       rather than this specific code.  */
        -:  680:#ifdef MPICH_IS_THREADED
      101:  681:    MPIU_THREAD_CHECK_BEGIN
        -:  682:    {
        -:  683:	struct pollinfo * pollinfo;
        -:  684:	
      101:  685:	pollinfo = MPIDU_Socki_sock_get_pollinfo(sock_set->intr_sock);
      101:  686:	MPIDU_SOCKI_EVENT_ENQUEUE(pollinfo, MPIDU_SOCK_OP_WAKEUP, 0, NULL, 
        -:  687:				  mpi_errno, mpi_errno, fn_exit);
      101:  688:	MPIDU_Socki_wakeup(sock_set);
        -:  689:    }
        -:  690:    MPIU_THREAD_CHECK_END
        -:  691:#   endif
        -:  692:
        -:  693:#ifdef MPICH_IS_THREADED
      101:  694:    fn_exit:
        -:  695:#endif
        -:  696:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_SOCK_WAKEUP);
      101:  697:    return mpi_errno;
        -:  698:}
        -:  699:/* end MPIDU_Sock_wakeup() */
        -:  700:
        -:  701: