pascal void  NotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie)
static pascal void  NotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie)
pascal void  NotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie){	PRFilePrivate *secret  = (PRFilePrivate *) contextPtr;	_MDFileDesc * md       = &(secret->md);	EndpointRef   endpoint = (EndpointRef)secret->md.osfd;    PRThread *    thread   = NULL;	OSStatus      err;	OTResult	  resultOT;    TDiscon		  discon;    switch (code)    {// OTLook Events -         case T_LISTEN:        // A connection request is available        	// If md->doListen is true, then PR_Listen has been        	// called on this endpoint; therefore, we're ready to        	// accept connections. But we'll do that with PR_Accept        	// (which calls OTListen, OTAccept, etc) instead of         	// doing it here.         	if (md->doListen) {				thread = secret->md.misc.thread;	            secret->md.misc.thread    = NULL;	            secret->md.misc.cookie    = cookie;	            break;        	} else {        		// Reject the connection, we're not listening        		OTSndDisconnect(endpoint, NULL);        	}            break;			        case T_CONNECT:      // Confirmation of a connect request			// cookie = sndCall parameter from OTConnect()            err = OTRcvConnect(endpoint, NULL);            PR_ASSERT(err == kOTNoError);			// wake up waiting thread, if any            thread = secret->md.write.thread;            secret->md.write.thread    = NULL;            secret->md.write.cookie    = cookie;            secret->md.connectionOpen  = PR_TRUE;            break;        case T_DATA:        // Standard data is available			// Mark this socket as readable.			secret->md.readReady = PR_TRUE;			// wake up waiting thread, if any            thread = secret->md.read.thread;            secret->md.read.thread    = NULL;            secret->md.read.cookie    = cookie;			break;        case T_EXDATA:      // Expedited data is available            PR_ASSERT(!"T_EXDATA Not implemented");			return;        case T_DISCONNECT:  // A disconnect is available            discon.udata.len = 0;            err = OTRcvDisconnect(endpoint, &discon);            PR_ASSERT(err == kOTNoError);            secret->md.exceptReady     = PR_TRUE;            secret->md.connectionOpen  = PR_FALSE;			// wake up waiting threads, if any			result = -3199 - discon.reason; // obtain the negative error code            if ((thread = secret->md.read.thread) != NULL) {		        secret->md.read.thread    = NULL;    	        secret->md.read.cookie    = cookie;            	WakeUpNotifiedThread(thread, result);    	    }                        if ((thread = secret->md.write.thread) != NULL) {	            secret->md.write.thread    = NULL;	            secret->md.write.cookie    = cookie;	            WakeUpNotifiedThread(thread, result);	        }	        	        thread = NULL; // already took care of notification here            break;		        case T_ERROR:       // obsolete/unused in library            PR_ASSERT(!"T_ERROR Not implemented");			return;				        case T_UDERR:       // UDP Send error; clear the error			(void) OTRcvUDErr((EndpointRef) cookie, NULL);            break;        case T_ORDREL:      // An orderly release is available            err = OTRcvOrderlyDisconnect(endpoint);            PR_ASSERT(err == kOTNoError);            secret->md.readReady      = PR_TRUE;   // mark readable (to emulate bsd sockets)            // remember connection is closed, so we can return 0 on read or receive			secret->md.connectionOpen = PR_FALSE;	            thread = secret->md.read.thread;	        secret->md.read.thread    = NULL;	        secret->md.read.cookie    = cookie;            break;		        case T_GODATA:   // Flow control lifted on standard data            secret->md.writeReady = PR_TRUE;			resultOT = OTLook(endpoint);		// clear T_GODATA event			PR_ASSERT(resultOT == T_GODATA);						// wake up waiting thread, if any            thread = secret->md.write.thread;            secret->md.write.thread    = NULL;            secret->md.write.cookie    = cookie;            break;        case T_GOEXDATA: // Flow control lifted on expedited data            PR_ASSERT(!"T_GOEXDATA Not implemented");			return;        case T_REQUEST:  // An Incoming request is available            PR_ASSERT(!"T_REQUEST Not implemented");            return;        case T_REPLY:    // An Incoming reply is available            PR_ASSERT(!"T_REPLY Not implemented");            return;        case T_PASSCON:  // State is now T_DATAXFER			// OTAccept() complete, receiving endpoint in T_DATAXFER state			// cookie = OTAccept() resRef parameter			break;        case T_RESET:    // Protocol has been reset            PR_ASSERT(!"T_RESET Not implemented");			return;            // Async Completion Events        case T_BINDCOMPLETE:        case T_UNBINDCOMPLETE:        case T_ACCEPTCOMPLETE:        case T_OPTMGMTCOMPLETE:        case T_GETPROTADDRCOMPLETE:			thread = secret->md.misc.thread;            secret->md.misc.thread    = NULL;            secret->md.misc.cookie    = cookie;            break;//      case T_OPENCOMPLETE:			// we open endpoints in synchronous mode//      case T_REPLYCOMPLETE://      case T_DISCONNECTCOMPLETE:		// we don't call OTSndDisconnect()//      case T_RESOLVEADDRCOMPLETE://      case T_GETINFOCOMPLETE://      case T_SYNCCOMPLETE://      case T_MEMORYRELEASED:			// only if OTAckSends() called on endpoint//      case T_REGNAMECOMPLETE://      case T_DELNAMECOMPLETE://      case T_LKUPNAMECOMPLETE://      case T_LKUPNAMERESULT:		// OpenTptInternet.h//      case T_DNRSTRINGTOADDRCOMPLETE:	// DNS is handled by dnsContext in DNSNotifierRoutine()//      case T_DNRADDRTONAMECOMPLETE://      case T_DNRSYSINFOCOMPLETE://      case T_DNRMAILEXCHANGECOMPLETE://      case T_DNRQUERYCOMPLETE:        default:        	// we should probably have a bit more sophisticated handling of kOTSystemSleep, etc.			// PR_ASSERT(code != 0);            return;    }	WakeUpNotifiedThread(thread, result);}