📄 scs_conn.c
字号:
* RET_INVCSTATE - Connection in invalid state * * SMP: The SCA database is locked for requesting acceptance and * establishment of the new connection. * * The CB is locked to synchronize access, prevent deletion, and * for requesting acceptance and establishment of the new * connection. It is indirectly locked through its CBVTE. * Locking the CB also prevents PB deletion. */u_longscs_accept( cmsb ) register CMSB *cmsb;{ register CB *cb; register CBVTE *cbvte; register u_long status = RET_SUCCESS; /* Acceptance of a logical SCS connection request proceeds as follows: * * 1. Lock the SCA database. * 2. Lock and retrieve the CB for the new connection. * 3. Allocate and add to the appropriate local port's free message and * datagram pools an initial credits worth of message and datagram * buffers. * 4. Complete CB initialization. * 5. Request acceptance of the connection request and establishment of a * new connection. * 6. Unlock the CB and SCA database. * 7. Return an appropriate status. * * Partial buffer allocations may occur( Step 3 ). Buffers allocated are * deallocated, but the connection is NOT cleaned up. This allows the * SYSAP to retry acceptance of the connection request. */ Check_connid2( cmsb->connid, cbvte, cb ) if( cb->cinfo.cstate != CS_CONN_REC ) { status = RET_INVCSTATE; } else if( scs_alloc_buf( cb, cmsb->init_rec_credit, cmsb->init_dg_credit ) == RET_SUCCESS ) { cb->control = cmsb->control; cb->msg_event = cmsb->msg_event; cb->dg_event = cmsb->dg_event; cb->aux = cmsb->aux; Move_data( cmsb->conn_data, cb->cinfo.lconn_data ) cb->cinfo.cstate = CS_ACCEPT_SNT; cb->cinfo.min_snd_credit = cmsb->min_snd_credit; cb->cinfo.init_rec_credit = cmsb->init_rec_credit; ( void )scs_request( CB_ACCEPT_PEND, cb, cb->pb, NULL ); } else { ( void )scs_dealloc_buf( cb ); status = RET_ALLOCFAIL; } Unlock_cbvte( cbvte ) Unlock_scadb() return( status );}/* Name: scs_reject - Reject Logical SCS Connection Request * * Abstract: This function prevents establishment of a logical SCS * connection by rejecting a connection request. The SYSAP is * notified of the outcome of its rejection request through * asynchronous invocation of the connection's control event * routine. * * The CB allocated for the connection is deallocated just prior * to SYSAP notification. The CBVTE referencing the CB is also * deallocated. * * Inputs: * * IPL_SCS - Interrupt processor level * cmsb - Connection Management Service Block pointer * connid - Identification of rejecting SCS connection * Reason - Reject reason( OPTIONAL ) * lscs - Local system permanent information * lk_scadb - SCA database lock structure * scs_cbvtdb - CB vector table database pointer * * Outputs: * * IPL_SCS - Interrupt processor level * cb - Connection Block pointer * cinfo.reason - Rejection reason * * Return Values: * * RET_SUCCESS - Initiated rejection of connection request * RET_INVCONNID - Invalid connection identification number * RET_INVCSTATE - Connection in invalid state * * SMP: The SCA database is locked for requesting rejection of the * connection request. * * The CB is locked to synchronize access, prevent premature * deletion, and for requesting rejection of the connection * request. It is indirectly locked through its CBVTE. Locking * the CB also prevents PB deletion. */u_longscs_reject( cmsb ) register CMSB *cmsb;{ register CB *cb; register CBVTE *cbvte; register u_long status = RET_SUCCESS; /* Rejecting a logical SCS connection request proceeds as follows: * * 1. Lock the SCA database. * 2. Lock and retrieve the CB for the connection. * 3. Request rejection of the connection request. * 4. Unlock the CB and SCA database. * 5. Return an appropriate status. */ Check_connid2( cmsb->connid, cbvte, cb ) if( cb->cinfo.cstate == CS_CONN_REC ) { cb->cinfo.cstate = CS_REJECT_SNT; if(( cb->cinfo.reason = cmsb->Reason ) == 0 ) { cb->cinfo.reason = ADR_DISCONN; } ( void )scs_request( CB_REJECT_PEND, cb, cb->pb, NULL ); } else { status = RET_INVCSTATE; } Unlock_cbvte( cbvte ) Unlock_scadb() return( status );}/* Name: scs_disconnect - Disconnect SCS Connection * * Abstract: This function terminates logical, listening, and formative * SCS connections. Connection termination may be temporarily * disallowed. This occurs only when termination may lead to * database corruption or an unknown SCS state. * * Connection termination always involves CB removal from all * internal resource queues and the system-wide configuration * database and its deallocation along with all associated * resources. The CBVTE referencing the CB is also deallocated. * * SYSAPs are usually notified of connection termination through * asynchronous invocation of their connections' control event * routines. However, the termination of listening SCS * connections and those connections established across now failed * paths always conclude synchronously. No notification occurs. * * NOTE: Termination of open connections must always be * asynchronously initiated. All SYSAP attempts to * disconnect connections following call back on those * connections fail with a "connection busy" error. * * NOTE: The appropriate port drivers are always responsible for * the clean up of all port specific resources associated * with failed local ports including free datagram and * message buffers. SCS must never attempt to dispose of * such resources during clean up of the paths and * connections associated with such failed ports. * * Inputs: * * IPL_SCS - Interrupt processor level * cmsb - Connection Management Service Block pointer * connid - Identification of SCS connection * Reason - Disconnect reason( OPTIONAL ) * lscs - Local system permanent information * lk_scadb - SCA database lock structure * scs_cbvtdb - CB vector table database pointer * * Outputs: * * IPL_SCS - Interrupt processor level * cb - Connection Block pointer * cinfo.cstate - Connection state * cinfo.reason - Disconnection reason * cinfo.status.abort_fork - Connection abortion fork in progress * cinfo.status.disconnect - Disconnect converted into reject flag * fork - CB fork context ( INITIALIZED ) * pb - Address of Path Block * pinfo.nconns - Number of connections * * * Return Values: * * RET_SUCCESS - Disconnection initiated ( or completed ) * RET_CONNBUSY - Connection is busy & can not be disconnected * RET_INVCONNID - Invalid connection identification number * * SMP: The SCA database is locked for CB removal from either the queue * of listening SYSAPs or the system-wide configuration database( * depending upon the SCS connection state ), CBVTE deallocation, * and for requesting connection termination( or rejection of a * connection request when connection state == CS_CONN_REC ). It * is also required for PB deletion from the system-wide * configuration database when such action becomes necessary. * * The CB is locked to synchronize access, for deletion in some * cases, to prevent premature deletion in others, and as required * by scs_log_event() in case logging becomes necessary. It is * indirectly locked through its CBVTE. Locking the CB also * prevents PB deletion and is required for requesting connection * termination( or rejection of a connection request when * connection state == CS_CONN_REC ). * * The CBVTE semaphore is accessed to ascertain whether or not * call backs on the connection are currently in progress. * Connection termination is not allowed as long as call backs are * in progress. * * The PB is locked whenever it is found necessary to remove a CB * from its SCS CB wait queue. */u_longscs_disconnect( cmsb ) register CMSB *cmsb;{ register CB *cb; register PB *pb; register CBVTE *cbvte; register u_long status = RET_SUCCESS; /* The steps involved in terminating a connection are as follows: * * 1. Lock the SCA database. * 2. Lock and retrieve the CB for the connection. * 3. Terminate the connection according to its current connection state. * 4. Unlock the CB and SCA database. * 5. Return an appropriate status. * * The following table lists the states connections may be found in and the * corresponding actions which are required to delete such connections: * * State Actions * * LISTEN 1. Remove the CB from the queue of listening SYSAPs * 2. Log termination of the listening SCS connection. * 3. Delete the CB releasing all associated resources. * * OPEN 1. Remove the CB from various resource queues. * DISCONN_REC 2. Request SCS to terminate the connection. * -- Following asynchronous connection termination -- * 3. Remove the CB from the system-wide configuration * database. * 4. Delete the CB releasing all associated resources. * 5. Notify the SYSAP of connection termination. * * CONN_SNT 1. Abort any pending SCS connection request. * CONN_ACK 2. Asynchronously call back SCS. * -- Following asynchronous SCS notification -- * 3. Remove the CB from the system-wide configuration * database. * 4. Delete the CB releasing all associated resources. * 5. Notify the SYSAP of connection abortion. * * CONN_REC 1. Request SCS to reject the connection request. * -- Following asynchronous connection termination -- * 2. Remove the CB from the system-wide configuration * database. * 3. Delete the CB releasing all associated resources. * 4. Notify the SYSAP of connection termination. * * PATH_FAILURE 1. Remove the CB from the system-wide configuration * database. * 2. Log failure of the established SCS connection. * 3. Delete the CB releasing all associated resources. * 4. Invoke the appropriate PD specific routine to * eliminate the appropriate PB when all connections * across the corresponding path have been terminated. * * CLOSED 1. Return an illegal connection state error. * DISCONN_ACK * DISCONN_SNT * DISCONN_MTCH * ACCEPT_SNT * REJECT_SNT * * SYSAPs are never allowed to terminate connections in either the LISTEN, * or OPEN connection states when asynchronous call backs to the SYSAP are * currently in progress on the connection. SYSAPs are never allowed to * terminate connections in either the OPEN or DISCONN_REC connection * states when block data transfers are currently in progress on the * connection. In both cases, SYSAPs should prevent further activity on * the connection and schedule connection termination; however, when * connection termination should be scheduled is different in each case. * Connection termination may immediately be scheduled in the former case * as it may well be the call back of the current thread which is * preventing disconnection. In the latter case connection termination * should be scheduled following completion of all transfers currently in * progress. SYSAPs are notified on the completion of each block data * transfer through asynchronous invocations of the connection's control * event routine. Once scheduled connection termination commences, the * SYSAP should repeatedly attempt to disconnect the connection until * either successful or an error other than "connection busy" is returned. * * NOTE: Allowing SYSAPs to disconnect connections with call backs in * progress can lead to numerous aberrant situations in SMP * environments such as SYSAP notification of application message * reception FOLLOWING notification of connection termination. There * is no way to prevent such situations from developing although * granted the possibility of their occurrence is extremely low. * Therefore, the decision was made to maintain a consistent meaning * to connection disconnection and avoid these situations altogether * by not allowing disconnects while call backs to the SYSAP on the * connection are in progress. Ultimately, this requires SYSAPs to * schedule their connection disconnections. This was thought to be * the least of all possible evils. */ Check_connid2( cmsb->connid, cbvte, cb ) switch( cb->cinfo.cstate ) { case CS_LISTEN: if( Test_cbvte_sem( cbvte )) { status = RET_CONNBUSY; } else { ( void )scs_log_event( cb, W_TERM_LISTENER, LSYSAP_EVENT ); Remove_entry( cb->flink ) ( void )scs_dealloc_cb( cb ); } break; case CS_OPEN: if( Test_cbvte_sem( cbvte )) { status = RET_CONNBUSY; break; } /* Fall through. */ case CS_DISCONN_REC: if( cb->cinfo.ntransfers ) { status = RET_CONNBUSY; } else { cb->cinfo.status.cwait = 0; Remove_pb_waitq( cb ) if( cb->cinfo.cstate == CS_OPEN ) { cb->cinfo.cstate = CS_DISCONN_SNT; } else { cb->cinfo.cstate = CS_DISCONN_MTCH; } cb->cinfo.reason = cmsb->Reason; ( void )scs_request( CB_DISCONN_PEND, cb, cb->pb, NULL ); } break; case CS_CONN_SNT: case CS_CONN_ACK: if( cb->cinfo.status.abort_fork ) { status = RET_CONNBUSY; } else { cb->cinfo.status.abort_fork = 1; Remove_pb_waitq( cb ) Kfork( &cb->forkb, scs_abort_conn, U_long( cbvte->connid )); } break; case CS_CONN_REC: cb->cinfo.cstate = CS_REJECT_SNT; cb->cinfo.status.disconnect = 1; cb->cinfo.reason = ADR_DISCONN; ( void )scs_request( CB_REJECT_PEND, cb, cb->pb, NULL ); break; case CS_PATH_FAILURE: ( void )scs_log_event( cb, W_FAIL_CONN, CONN_EVENT ); pb = cb->pb; Remove_cb( cb, pb ) if( pb->pinfo.nconns == 0 ) { ( void )( *pb->Remove_pb )( pb->pccb, pb ); } break; case CS_CLOSED: case CS_DISCONN_ACK: case CS_DISCONN_SNT: case CS_DISCONN_MTCH: case CS_ACCEPT_SNT: case CS_REJECT_SNT: status = RET_INVCSTATE; break; default: ( void )panic( SCSPANIC_CSTATE ); } Unlock_cbvte( cbvte ) Unlock_scadb() return( status );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -