-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/ch3/src/ch3u_handle_connection.c
        -:    0:Graph:ch3u_handle_connection.gcno
        -:    0:Data:ch3u_handle_connection.gcda
        -:    0:Runs:3459
        -:    0:Programs:899
        -:    1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
        -:    2:/*
        -:    3: *  (C) 2001 by Argonne National Laboratory.
        -:    4: *      See COPYRIGHT in top-level directory.
        -:    5: */
        -:    6:
        -:    7:#include "mpidimpl.h"
        -:    8:
        -:    9:/* Count the number of outstanding close requests */
        -:   10:static volatile int MPIDI_Outstanding_close_ops = 0;
        -:   11:
        -:   12:/* FIXME: What is this routine for?
        -:   13:   It appears to be used only in ch3_progress, ch3_progress_connect, or
        -:   14:   ch3_progress_sock files.  Is this a general operation, or does it 
        -:   15:   belong in util/sock ? It appears to be used in multiple channels, 
        -:   16:   but probably belongs in mpid_vc, along with the vc exit code that 
        -:   17:   is currently in MPID_Finalize */
        -:   18:
        -:   19:/* FIXME: The only event is event_terminated.  Should this have 
        -:   20:   a different name/expected function? */
        -:   21:
        -:   22:#undef FUNCNAME
        -:   23:#define FUNCNAME MPIDI_CH3U_Handle_connection
        -:   24:#undef FCNAME
        -:   25:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:   26:/*@
        -:   27:  MPIDI_CH3U_Handle_connection - handle connection event
        -:   28:
        -:   29:  Input Parameters:
        -:   30:+ vc - virtual connection
        -:   31:. event - connection event
        -:   32:
        -:   33:  NOTE:
        -:   34:  At present this function is only used for connection termination
        -:   35:@*/
        -:   36:int MPIDI_CH3U_Handle_connection(MPIDI_VC_t * vc, MPIDI_VC_Event_t event)
    12244:   37:{
        -:   38:    int inuse;
    12244:   39:    int mpi_errno = MPI_SUCCESS;
        -:   40:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3U_HANDLE_CONNECTION);
        -:   41:
        -:   42:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3U_HANDLE_CONNECTION);
        -:   43:
    12244:   44:    switch (event)
        -:   45:    {
        -:   46:	case MPIDI_VC_EVENT_TERMINATED:
        -:   47:	{
    12244:   48:	    switch (vc->state)
        -:   49:	    {
        -:   50:		case MPIDI_VC_STATE_CLOSE_ACKED:
        -:   51:		{
    12244:   52:                    MPIDI_CHANGE_VC_STATE(vc, INACTIVE);
        -:   53:		    /* FIXME: Decrement the reference count?  Who increments? */
        -:   54:		    /* FIXME: The reference count is often already 0.  But
        -:   55:		       not always */
        -:   56:		    /* MPIU_Object_set_ref(vc, 0); ??? */
        -:   57:
        -:   58:		    /*
        -:   59:		     * FIXME: The VC used in connect accept has a NULL 
        -:   60:		     * process group
        -:   61:		     */
        -:   62:                    /* XXX DJG FIXME-MT should we be checking this ref_count? */
    12244:   63:		    if (vc->pg != NULL && (MPIU_Object_get_ref(vc) == 0))
        -:   64:		    {
        -:   65:			/* FIXME: Who increments the reference count that
        -:   66:			   this is decrementing? */
        -:   67:			/* When the reference count for a vc becomes zero, 
        -:   68:			   decrement the reference count
        -:   69:			   of the associated process group.  */
        -:   70:			/* FIXME: This should be done when the reference 
        -:   71:			   count of the vc is first decremented */
     1808:   72:			MPIDI_PG_release_ref(vc->pg, &inuse);
     1808:   73:			if (inuse == 0) {
     1195:   74:			    MPIDI_PG_Destroy(vc->pg);
        -:   75:			}
        -:   76:		    }
        -:   77:
        -:   78:		    /* MT: this is not thread safe */
    12244:   79:		    MPIDI_Outstanding_close_ops -= 1;
        -:   80:		    MPIU_DBG_MSG_D(CH3_DISCONNECT,TYPICAL,
        -:   81:             "outstanding close operations = %d", MPIDI_Outstanding_close_ops);
        -:   82:	    
    12244:   83:		    if (MPIDI_Outstanding_close_ops == 0)
        -:   84:		    {
     5818:   85:			MPIDI_CH3_Progress_signal_completion();
     5818:   86:                        mpi_errno = MPIDI_CH3_Channel_close();
     5818:   87:                        if (mpi_errno) MPIU_ERR_POP(mpi_errno);
        -:   88:		    }
        -:   89:
        -:   90:		    break;
        -:   91:		}
        -:   92:
        -:   93:		default:
        -:   94:		{
        -:   95:		    MPIU_DBG_MSG_D(CH3_DISCONNECT,TYPICAL,
        -:   96:           "Unhandled connection state %d when closing connection",vc->state);
    #####:   97:		    mpi_errno = MPIR_Err_create_code(
        -:   98:			MPI_SUCCESS, MPIR_ERR_FATAL, FCNAME, __LINE__, 
        -:   99:                        MPI_ERR_INTERN, "**ch3|unhandled_connection_state",
        -:  100:			"**ch3|unhandled_connection_state %p %d", vc, event);
    #####:  101:                    goto fn_fail;
        -:  102:		    break;
        -:  103:		}
        -:  104:	    }
        -:  105:
        -:  106:	    break;
        -:  107:	}
        -:  108:    
        -:  109:	default:
        -:  110:	{
        -:  111:	    break;
        -:  112:	}
        -:  113:    }
        -:  114:
    12244:  115:fn_exit:
        -:  116:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3U_HANDLE_CONNECTION);
    12244:  117:    return mpi_errno;
        -:  118:fn_fail:
        -:  119:    goto fn_exit;
        -:  120:}
        -:  121:
        -:  122:#undef FUNCNAME
        -:  123:#define FUNCNAME MPIDI_VC_SendClose
        -:  124:#undef FCNAME
        -:  125:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  126:/*@
        -:  127:  MPIDI_CH3U_VC_SendClose - Initiate a close on a virtual connection
        -:  128:  
        -:  129:  Input Parameters:
        -:  130:+ vc - Virtual connection to close
        -:  131:- i  - rank of virtual connection within a process group (used for debugging)
        -:  132:
        -:  133:  Notes:
        -:  134:  The current state of this connection must be either 'MPIDI_VC_STATE_ACTIVE' 
        -:  135:  or 'MPIDI_VC_STATE_REMOTE_CLOSE'.  
        -:  136:  @*/
        -:  137:int MPIDI_CH3U_VC_SendClose( MPIDI_VC_t *vc, int rank )
    12244:  138:{
        -:  139:    MPIDI_CH3_Pkt_t upkt;
    12244:  140:    MPIDI_CH3_Pkt_close_t * close_pkt = &upkt.close;
        -:  141:    MPID_Request * sreq;
    12244:  142:    int mpi_errno = MPI_SUCCESS;
        -:  143:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3U_VC_SENDCLOSE);
        -:  144:
        -:  145:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3U_VC_SENDCLOSE);
        -:  146:
        -:  147:    /* FIXME: Remove this IFDEF */
        -:  148:#if defined(MPIDI_CH3_USES_SSHM) && 0
        -:  149:    MPIU_Assert( vc->state == MPIDI_VC_STATE_ACTIVE || 
        -:  150:		 vc->state == MPIDI_VC_STATE_REMOTE_CLOSE 
        -:  151:		 /* sshm queues are uni-directional.  A VC that is connected 
        -:  152:		 * in the read direction is marked MPIDI_VC_STATE_INACTIVE
        -:  153:		 * so that a connection will be formed on the first write.  
        -:  154:		 * Since the other side is marked MPIDI_VC_STATE_ACTIVE for 
        -:  155:		 * writing 
        -:  156:		 * we need to initiate the close protocol on the read side 
        -:  157:		 * even if the write state is MPIDI_VC_STATE_INACTIVE. */
        -:  158:		 || ((vc->state == MPIDI_VC_STATE_INACTIVE) && 
        -:  159:		     ((MPIDI_CH3I_VC *)(vc->channel_private))->shm_read_connected) );
        -:  160:#else
    12244:  161:    MPIU_Assert( vc->state == MPIDI_VC_STATE_ACTIVE || 
        -:  162:		 vc->state == MPIDI_VC_STATE_REMOTE_CLOSE );
        -:  163:#endif
        -:  164:
    12244:  165:    MPIDI_Pkt_init(close_pkt, MPIDI_CH3_PKT_CLOSE);
    12244:  166:    close_pkt->ack = (vc->state == MPIDI_VC_STATE_ACTIVE) ? FALSE : TRUE;
        -:  167:    
        -:  168:    /* MT: this is not thread safe */
    12244:  169:    MPIDI_Outstanding_close_ops += 1;
        -:  170:    MPIU_DBG_MSG_FMT(CH3_DISCONNECT,TYPICAL,(MPIU_DBG_FDEST,
        -:  171:		  "sending close(%s) on vc (pg=%p) %p to rank %d, ops = %d", 
        -:  172:		  close_pkt->ack ? "TRUE" : "FALSE", vc->pg, vc, 
        -:  173:		  rank, MPIDI_Outstanding_close_ops));
        -:  174:		    
        -:  175:
        -:  176:    /*
        -:  177:     * A close packet acknowledging this close request could be
        -:  178:     * received during iStartMsg, therefore the state must
        -:  179:     * be changed before the close packet is sent.
        -:  180:     */
    12244:  181:    if (vc->state == MPIDI_VC_STATE_ACTIVE) {
    10030:  182:        MPIDI_CHANGE_VC_STATE(vc, LOCAL_CLOSE);
        -:  183:    }
        -:  184:    else {
     2214:  185:	MPIU_Assert( vc->state == MPIDI_VC_STATE_REMOTE_CLOSE );
     2214:  186:        MPIDI_CHANGE_VC_STATE(vc, CLOSE_ACKED);
        -:  187:    }
        -:  188:		
    12244:  189:    mpi_errno = MPIU_CALL(MPIDI_CH3,iStartMsg(vc, close_pkt, 
        -:  190:					      sizeof(*close_pkt), &sreq));
    12244:  191:    if (mpi_errno != MPI_SUCCESS) {
    #####:  192:	MPIU_ERR_SET(mpi_errno,MPI_ERR_OTHER,
        -:  193:		     "**ch3|send_close_ack");
        -:  194:    }
        -:  195:    
    12244:  196:    if (sreq != NULL) {
        -:  197:	/* There is still another reference being held by the channel.  It
        -:  198:	   will not be released until the pkt is actually sent. */
    #####:  199:	MPID_Request_release(sreq);
        -:  200:    }
        -:  201:
        -:  202:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3U_VC_SENDCLOSE);
    12244:  203:    return mpi_errno;
        -:  204:}
        -:  205:
        -:  206:/* Here is the matching code that processes a close packet when it is 
        -:  207:   received */
        -:  208:int MPIDI_CH3_PktHandler_Close( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, 
        -:  209:				MPIDI_msg_sz_t *buflen, MPID_Request **rreqp )
    22274:  210:{
    22274:  211:    MPIDI_CH3_Pkt_close_t * close_pkt = &pkt->close;
    22274:  212:    int mpi_errno = MPI_SUCCESS;
        -:  213:	    
    22274:  214:    if (vc->state == MPIDI_VC_STATE_LOCAL_CLOSE)
        -:  215:    {
        -:  216:	MPIDI_CH3_Pkt_t upkt;
    10030:  217:	MPIDI_CH3_Pkt_close_t * resp_pkt = &upkt.close;
        -:  218:	MPID_Request * resp_sreq;
        -:  219:	
    10030:  220:	MPIDI_Pkt_init(resp_pkt, MPIDI_CH3_PKT_CLOSE);
    10030:  221:	resp_pkt->ack = TRUE;
        -:  222:	
        -:  223:	MPIU_DBG_MSG_D(CH3_DISCONNECT,TYPICAL,"sending close(TRUE) to %d",
        -:  224:		       vc->pg_rank);
    10030:  225:	mpi_errno = MPIU_CALL(MPIDI_CH3,iStartMsg(vc, resp_pkt, 
        -:  226:					  sizeof(*resp_pkt), &resp_sreq));
    10030:  227:	if (mpi_errno != MPI_SUCCESS) {
    #####:  228:	    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,
        -:  229:				"**ch3|send_close_ack");
        -:  230:	}
        -:  231:	
    10030:  232:	if (resp_sreq != NULL)
        -:  233:	{
        -:  234:	    /* There is still another reference being held by the channel.  It
        -:  235:	       will not be released until the pkt is actually sent. */
    #####:  236:	    MPID_Request_release(resp_sreq);
        -:  237:	}
        -:  238:    }
        -:  239:    
    22274:  240:    if (close_pkt->ack == FALSE)
        -:  241:    {
    10030:  242:	if (vc->state == MPIDI_VC_STATE_LOCAL_CLOSE)
        -:  243:	{
        -:  244:	    MPIU_DBG_MSG_D(CH3_DISCONNECT,TYPICAL,
        -:  245:		   "received close(FALSE) from %d, moving to CLOSE_ACKED.",
        -:  246:		   vc->pg_rank);
     7816:  247:            MPIDI_CHANGE_VC_STATE(vc, CLOSE_ACKED);
        -:  248:	}
        -:  249:#if 0
        -:  250:	else if (vc->state == MPIDI_VC_STATE_CLOSE_ACKED) {
        -:  251:	    /* FIXME: This situation has been seen with the ssm device,
        -:  252:	       when running on a single process.  It may indicate that the
        -:  253:	       close protocol, for shared memory connections, can
        -:  254:	       occasionally reach this state when both sides start
        -:  255:	       closing the connection.  We will act as if this is
        -:  256:	       duplicate information can be ignored (rather than triggering
        -:  257:	       the Assert in the next case) */
        -:  258:	    MPIU_DBG_MSG(CH3_DISCONNECT,TYPICAL,
        -:  259:			 "Saw CLOSE_ACKED while already in that state");
        -:  260:            MPIDI_CHANGE_VC_STATE(vc, REMOTE_CLOSE);
        -:  261: 	    /* We need this terminate to decrement the outstanding closes */
        -:  262:	    /* For example, with sockets, Connection_terminate will close
        -:  263:	       the socket */
        -:  264:	    mpi_errno = MPIU_CALL(MPIDI_CH3,Connection_terminate(vc));
        -:  265:	}
        -:  266:#endif
        -:  267:	else /* (vc->state == MPIDI_VC_STATE_ACTIVE) */
        -:  268:	{
        -:  269:	    /* FIXME: Debugging */
     2214:  270:	    if (vc->state != MPIDI_VC_STATE_ACTIVE) {
    #####:  271:		printf( "Unexpected state %d in vc %p\n", vc->state, vc );
    #####:  272:		fflush(stdout);
        -:  273:	    }
        -:  274:	    MPIU_DBG_MSG_D(CH3_DISCONNECT,TYPICAL,
        -:  275:                     "received close(FALSE) from %d, moving to REMOTE_CLOSE.",
        -:  276:				   vc->pg_rank);
     2214:  277:	    MPIU_Assert(vc->state == MPIDI_VC_STATE_ACTIVE);
     2214:  278:            MPIDI_CHANGE_VC_STATE(vc, REMOTE_CLOSE);
        -:  279:	}
        -:  280:    }
        -:  281:    else /* (close_pkt->ack == TRUE) */
        -:  282:    {
        -:  283:	MPIU_DBG_MSG_D(CH3_DISCONNECT,TYPICAL,
        -:  284:                       "received close(TRUE) from %d, moving to CLOSE_ACKED.", 
        -:  285:			       vc->pg_rank);
    12244:  286:	MPIU_Assert (vc->state == MPIDI_VC_STATE_LOCAL_CLOSE || 
        -:  287:		     vc->state == MPIDI_VC_STATE_CLOSE_ACKED);
    12244:  288:        MPIDI_CHANGE_VC_STATE(vc, CLOSE_ACKED);
        -:  289:	/* For example, with sockets, Connection_terminate will close
        -:  290:	   the socket */
    12244:  291:	mpi_errno = MPIU_CALL(MPIDI_CH3,Connection_terminate(vc));
        -:  292:    }
        -:  293:    
    22274:  294:    *buflen = sizeof(MPIDI_CH3_Pkt_t);
    22274:  295:    *rreqp = NULL;
        -:  296:
    22274:  297: fn_fail:
    22274:  298:    return mpi_errno;
        -:  299:}
        -:  300:
        -:  301:#ifdef MPICH_DBG_OUTPUT
        -:  302:int MPIDI_CH3_PktPrint_Close( FILE *fp, MPIDI_CH3_Pkt_t *pkt )
        -:  303:{
        -:  304:    MPIU_DBG_PRINTF((" type ......... MPIDI_CH3_PKT_CLOSE\n"));
        -:  305:    MPIU_DBG_PRINTF((" ack ......... %s\n", pkt->close.ack ? "TRUE" : "FALSE"));
        -:  306:    return MPI_SUCCESS;
        -:  307:}
        -:  308:#endif
        -:  309:
        -:  310:/* 
        -:  311: * This routine can be called to progress until all pending close operations
        -:  312: * (initiated in the SendClose routine above) are completed.  It is 
        -:  313: * used in MPID_Finalize and MPID_Comm_disconnect.
        -:  314: */
        -:  315:#undef FUNCNAME
        -:  316:#define FUNCNAME MPIDI_CH3U_VC_WaitForClose
        -:  317:#undef FCNAME
        -:  318:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  319:/*@
        -:  320:  MPIDI_CH3U_VC_WaitForClose - Wait for all virtual connections to close
        -:  321:  @*/
        -:  322:int MPIDI_CH3U_VC_WaitForClose( void )
     6012:  323:{
        -:  324:    MPID_Progress_state progress_state;
     6012:  325:    int mpi_errno = MPI_SUCCESS;
        -:  326:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3U_VC_WAITFORCLOSE);
        -:  327:
        -:  328:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3U_VC_WAITFORCLOSE);
        -:  329:
     6012:  330:    MPID_Progress_start(&progress_state);
    16700:  331:    while(MPIDI_Outstanding_close_ops > 0) {
        -:  332:	MPIU_DBG_MSG_D(CH3_DISCONNECT,TYPICAL,
        -:  333:		       "Waiting for %d close operations",
        -:  334:		       MPIDI_Outstanding_close_ops);
     4676:  335:	mpi_errno = MPID_Progress_wait(&progress_state);
        -:  336:	/* --BEGIN ERROR HANDLING-- */
     4676:  337:	if (mpi_errno != MPI_SUCCESS) {
    #####:  338:	    MPIU_ERR_SET(mpi_errno,MPI_ERR_OTHER,"**ch3|close_progress");
    #####:  339:	    break;
        -:  340:	}
        -:  341:	/* --END ERROR HANDLING-- */
        -:  342:    }
        -:  343:    MPID_Progress_end(&progress_state);
        -:  344:
        -:  345:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3U_VC_WAITFORCLOSE);
     6012:  346:    return mpi_errno;
        -:  347:}
        -:  348: