⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scs_event.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
 *   sb				- System Block pointer *   lk_scadb			- SCA database lock structure *   scs_listeners		- Listening SYSAP queue head * *   Outputs: * *   IPL_SCS			- Interrupt processor level * *   SMP:	The SCA database is locked to postpone potential modifications *		to the queue of listening SYSAPs while it is being traversed. * *		The CB is locked to synchronize access and to prevent deletion. *		It is indirectly locked through its CBVTE.  Locking the CB also *		prevents premature PB deletion as required by scs_init_cmsb(). * *		The CBVTE semaphore is incremented prior to SYSAP notification *		of new path existence.  This prevents connection termination *		while call backs are in progress.  The semaphore is decremented *		after SYSAP notification completes. * *		The validity of the PB address must be guaranteed EXTERNALLY. *		 *		NO EXTERNAL locks may be held when this routine is invoked. */voidscs_new_path( sb, pb )    SB			*sb;    PB			*pb;{    CMSB		cmsb;    register cbq	*cb;    register CBVTE	*cbvte;    register void	( *control )();    register u_long	dirid = 0;    /* Iteratively scan the queue of listening SYSAPs.  Each scan:     *     * 1. Locks the SCA database.     * 2. Positions and locks the "next" CB within the queue( now the "current"     *    CB ).     * 3. Increments the CBVTE semaphore.     * 4. Unlocks the CB.     * 5. Unlocks the SCA database.     * 6. Notifies the SYSAP corresponding to the "current" CB of the existence     *    of a path to a previously unknown system.     * 7. Decrements the CBVTE semaphore.     *     * Incrementing the appropriate CBVTE semaphore protects the connection     * against termination for the duration of SYSAP notification of new path     * existence and while any call backs on the connection are in progress.     * Such protection is necessary because termination of listening     * connections is synchronous and immediate which would allow SYSAPs to     * receive notifications on connections which no longer exist if such     * protection was not provided.     *     * Positioning to the "next" CB is accomplished by means of the "current"     * CB's directory identification number.  This allows positioning to be     * relative and accomplished even when the "current" CB is deleted from the     * the queue between iterative scans.     */    do	{	Lock_scadb()	for( cb = scs_listeners.flink;	     cb != &scs_listeners && Cb->cinfo.Dirid <= dirid;	     cb = cb->flink ) {}	if( cb != &scs_listeners ) {	    if( Cb->cinfo.cstate != CS_LISTEN ) {		( void )panic( SCSPANIC_LQUEUE );	    }	    cbvte = Get_cbvte( Cb->cinfo.lconnid );	    Lock_cbvte( cbvte )	    ( void )scs_init_cmsb( CRE_NEW_PATH,				   ADR_SUCCESS,				   &cmsb,				   cb,				   pb,				   0 );	    control = Cb->control;	    dirid = Cb->cinfo.Dirid;	    Incr_cbvte_sem( cbvte )	    Unlock_cbvte( cbvte )	} else {	    control = NULL;	}	Unlock_scadb()	if( control ) {	    ( void )( *control )( CRE_NEW_PATH, &cmsb );	    Decr_cbvte_sem( cbvte )	}    }	while( cb != &scs_listeners );}/*   Name:	scs_path_crash	- Path to System Crashed * *   Abstract:	This SCS event notification routine is asynchronously invoked *		by PDs following path failure, disablement, and invalidation of *		the appropriate port's translation cache( as required ).  It *		directs clean up the failed path with the ultimate goal of *		removing the PB from the system-wide configuration database and *		deleting it.  It must only be invoked once for each path *		incarnation. * *		PBs passed to this routine are guaranteed to be valid because: * *		1. Path clean up is single threaded even in SMP environments. *		2. It is this routine which is responsible for directing clean *		   up and deallocation of PBs. * *		NOTE: Once this routine is invoked the PD may only notify SCS *		      of the successful transmission and reception of datagrams *		      over this incarnation of the failed path. * *		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 *   pb				- Path Block pointer *	pinfo.state		-  PS_PATH_FAILURE *  	pinfo.reason		-  Reason for path failure *   lk_scadb			- SCA database lock structure *   scs_cbvtdb			- CB vector table database pointer *   scs_timeoutq		- SCS protocol sequence timeout queue head * *   Outputs: * *   IPL_SCS			- Interrupt processor level *   pb				- Path Block pointer *	pinfo.nconns		-  Number of connections *	pinfo.status.sanity	-  0 * *   SMP:	The SCA database is locked for traversing and removing CBs and *		PBs( when necessary ) from the system-wide configuration *		database, and deallocating CBVTEs.  Locking the SCA database *		also prevents premature PB deletion and allows their removal *		from the SCS protocol sequence timeout queue when necessary. * *   		CBs are 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.  They are *		indirectly locked through their CBVTEs. * *		CBVTE semaphores are synchronized to in order to postpone *		changes in connection state while call backs to the *		corresponding SYSAPs are in progress. * *		The PB is locked to synchronize access and whenever it is found *		necessary to remove a CB from its SCS CB wait queue or the PB *		from the SCS protocol sequence timeout queue. * *		The validity of the PB address must be guaranteed EXTERNALLY. *		 *		NO EXTERNAL locks may be held when this routine is invoked. */voidscs_path_crash( pb )    register PB		*pb;{    CMSB		cmsb;    u_long		sn;    void		( *control )();    register cbq	*cb;    register CBVTE	*cbvte;    register u_long	port_failure, event, status;    /* Clean up of the failed path involves the following steps:     *     *  1. Lock the SCA database.     *  2. Lock the PB.     *  3. Abort the PB sanity timer if currently operational.     *  4. Determine whether the path failed due to local port failure.     *  5. Unlock the PB.     *  6. Temporarily increment the count of CBs associated with the path.     *  7. Initiate clean up of all CBs associated with the path.     *  8. Decrement the count of CBs associated with the path restoring it to     * 	   its proper value.     *  9. Invoke the appropriate PD routine to remove the PB from the     *	   system-wide configuration database and deallocate it provided all     *	   CBs have been cleaned up and there are none associated with the PB.     *	   Otherwise, the PB is removed and deallocated when the last     *	   connection across the path is terminated by SYSAP request.     * 10. Unlock the SCA database.     *     * Temporarily incrementing the CB count( Step 6 ) prevents PB deletion and     * simplifies path clean up while guaranteeing the validity of the cached     * PB address.  Locks are insufficient for this purpose because they must     * be repeatedly released and re-established during path clean up.     *     * The clean up of each CB( Step 7 ) proceeds as follows:     *     * 1. Lock the CB.     * 2. Synchronize to the CBVTE semaphore.     * 3. Abort any scheduled SCS request.     * 4. Remove the CB from all internal resource queues.     * 5. Prohibit the removal of buffers from the local port's free pools     *    during CB clean up whenever path failure resulted from local port     *    failure.  The buffers credited to the connection are retrieved and     *    disposed of during clean up of the failed port itself.     * 6. Complete CB clean up according to its connection state.     * 7. Unlock the CB.     *     * Synchronizing to the CBVTE semaphore( Step 2 ) postpones processing of     * the connection and subsequent changes in its state while call backs to     * the corresponding SYSAP are in progress.  Failure to synchronize can     * lead to numerous aberrant situations in SMP environments such as SYSAP     * notification of application message reception FOLLOWING notification of     * connection termination due to path failure.  Synchronization is     * achieved by releasing the SCA database and CB locks and re-obtaining     * them in the proper order until all call backs have completed( CBVTE     * semaphore == 0 ).     *     * Connection state dependent clean up( Step 6 ) of open connections and     * those partially disconnected due to remote SYSAP action is asynchronous.     * The local SYSAP is notified of path failure through asynchronous     * invocation of the connection's control event routine and it must     * explicitly request connection termination.  It may do so at its leisure.     *     * Connection state dependent clean up( Step 6 ) of formative connections     * initiated by the remote SYSAP but not yet responded to by the local     * SYSAP is synchronous.  The event is logged.  The CB is removed from the     * system-wide configuration database and is deallocated along with all     * associated resources.  The corresponding local SYSAP is not notified of     * this occurrence but discover it when it attempts to respond to the     * connection request.     *     * Connection state dependent clean up( Step 6 ) of connections in all     * other states is asynchronous and proceeds as follows:     *     * 1. Termination of the fully established or formative SCS connection due     *	  to path failure is logged.     * 2. The CB is removed from the system-wide configuration database.     * 3. The CB is deallocated along with all associated resources.     * 4. The local SYSAP is notified of connection failure through     *	  asynchronous invocation of the connection's control event routine.     *     * Which specific event the local SYSAP is notified of depends upon the     * connection's former state.     *     * NOTE: All locks are released prior to local SYSAP notification to allow     *	     it to respond to the event.  The SCA database lock is     *	     re-established following SYSAP notification but prior to obtaining     *	     the next CB associated with the failed path.  Cached PB addresses     *	     are valid following re-establishment of the SCA database lock     *	     because the number of CBs associated with them was artificially     *	     increased to prevent PB removal from the system-wide configuration     *	     database and deletion.     *     * NOTE: Cached CB addresses are valid after synchronization to the CBVTE     *	     semaphore is achieved because once path failure is reported to SCS     *	     the only way for CBs to be deallocated is for their SYSAPs to     *	     request disconnection of their corresponding connections following     *	     explicit notification of the path failure.     */    Lock_scadb()    Lock_pb( pb )    if( pb->pinfo.status.sanity ) {	Remove_scs_timeoutq( pb )    }    port_failure = Port_failure( pb->pinfo.reason );    Unlock_pb( pb )    ++pb->pinfo.nconns;    for( cb = pb->cbs.flink; cb != &pb->cbs; ) {	event = 0;	cbvte = Get_cbvte( Cb->cinfo.lconnid );	Lock_cbvte( cbvte )	sn = cbvte->connid.seq_num;	while( Test_cbvte_sem( cbvte )) {	    Unlock_cbvte( cbvte )	    Unlock_scadb()	    Lock_scadb()	    Lock_cbvte( cbvte )	}	if( sn != cbvte->connid.seq_num ) {	    ( void )panic( SCSPANIC_SCADB );	}	Remove_pb_waitq( Cb )	Cb->cinfo.status.cwait = 0;	if( port_failure ) {	    Cb->cinfo.rec_credit = 0,	    Cb->cinfo.pend_rec_credit = 0,	    Cb->cinfo.ntransfers = 0;	    Cb->cinfo.dg_credit = 0;	}	switch( Cb->cinfo.cstate ) {	    case CS_OPEN:	    case CS_DISCONN_REC:		break;	    case CS_DISCONN_ACK:	    case CS_DISCONN_SNT:	    case CS_DISCONN_MTCH:		event = W_FAIL_CONN;		break;	    case CS_CONN_SNT:	    case CS_CONN_ACK:	    case CS_CONN_REC:	    case CS_ACCEPT_SNT:	    case CS_REJECT_SNT:		event = W_FAIL_FCONN;		break;	    default:		( void )panic( SCSPANIC_CSTATE );	}	if( event ) {	    ( void )scs_log_event( Cb, event, CONN_EVENT );	    event = 0;	}	switch( Cb->cinfo.cstate ) {	    case CS_OPEN:	    case CS_DISCONN_REC:		Cb->cinfo.cstate = CS_PATH_FAILURE;		status = pb->pinfo.reason;		event = CRE_PATH_FAILURE;		break;	    case CS_DISCONN_ACK:	    case CS_DISCONN_SNT:	    case CS_DISCONN_MTCH:		Cb->cinfo.cstate = CS_CLOSED;		status = ADR_PATH_FAILURE;		event = CRE_DISCONN_DONE;		break;	    case CS_CONN_SNT:	    case CS_CONN_ACK:		Cb->cinfo.cstate = CS_CLOSED;		status = ADR_PATH_FAILURE;		event = CRE_CONN_DONE;		/* Asynchronous local SYSAP notification triggered by		 * unilateral connection abortion is unscheduled.		 */		if( Cb->cinfo.status.abort_fork ) {		    ( void )unksched( &Cb->forkb );		    Cb->cinfo.status.abort_fork = 0;		}		break;	    case CS_CONN_REC: {		cbq	*next_cb = cb->flink;		Cb->cinfo.cstate = CS_CLOSED;		Remove_cb( Cb, pb )		Unlock_cbvte( cbvte )		cb = next_cb;		continue;	    }	    case CS_ACCEPT_SNT:	    case CS_REJECT_SNT:		if( Cb->cinfo.cstate == CS_ACCEPT_SNT ) {		    event = CRE_ACCEPT_DONE;		} else if( Cb->cinfo.status.disconnect ) {		    event = CRE_DISCONN_DONE;		} else {		    event = CRE_REJECT_DONE;		}		status = ADR_PATH_FAILURE;		Cb->cinfo.cstate = CS_CLOSED;		break;	    default:		( void )panic( SCSPANIC_CSTATE );	}	( void )scs_init_cmsb( event, status, &cmsb, Cb, pb, 0 );	control = Cb->control;	if( Cb->cinfo.cstate == CS_CLOSED ) {	    Remove_cb( Cb, pb )	}	Unlock_cbvte( cbvte )	Unlock_scadb()	( void )( *control )( event, &cmsb );	Lock_scadb()	for( cb = pb->cbs.flink;	     cb != &pb->cbs && Cb->cinfo.cstate == CS_PATH_FAILURE;	     cb = cb->flink ) {}    }    if( --pb->pinfo.nconns == 0 ) {	( void )( *pb->Remove_pb )( pb->pccb, pb );    }    Unlock_scadb()}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -