NMErr EndpointHander::GetStreamEP(void) { DEBUG_ENTRY_EXIT("EndpointHander::GetStreamEP"); CachedEP *streamEP = NULL; OTLink *acceptorLink = NULL; NMErr status = kNMNoError; //Try_ { // Get a cached stream ep acceptorLink = OTLIFODequeue(&OTEndpoint::sStreamEPCache.Q); //if there was an available one in the cache if (acceptorLink) { OTAtomicAdd32(-1, &OTEndpoint::sStreamEPCache.readyCount); OTAtomicAdd32(-1, &OTEndpoint::sStreamEPCache.totalCount); //jacked up and good to go mState |= kGotStreamEP; //get the cache reloading itself OTEndpoint::ServiceEPCaches(); } //otherwise, make one now else { return OTAsyncOpenEndpoint(OTCreateConfiguration(mListenerEP->GetStreamProtocolName()), 0, NULL, mNotifier.fUPP, this); } // Get the pointer to the cached ep object streamEP = OTGetLinkObject(acceptorLink, CachedEP, link); op_assert(streamEP != NULL); // Remove the notifier that was being used for cacheing and install the "normal" one OTRemoveNotifier(streamEP->ep); OTInstallNotifier(streamEP->ep, mNotifier.fUPP, this); mNewEP->mStreamEndpoint->mEP = streamEP->ep; delete streamEP; } //Catch_(code) error: if (status) { NMErr code = status; return code; } mState |= kStreamDone; return kNMNoError; }
static void PrepareThreadForAsyncIO(PRThread *thread, EndpointRef endpoint, PRInt32 osfd) { OSStatus err; thread->io_pending = PR_TRUE; thread->io_fd = osfd; thread->md.osErrCode = noErr; OTRemoveNotifier(endpoint); err = OTInstallNotifier(endpoint, NotifierRoutine, thread); PR_ASSERT(err == kOTNoError); }
NMErr EndpointHander::Finish(void) { DEBUG_ENTRY_EXIT("EndpointHander::Finish"); NMErr status; OTRemoveNotifier(mNewEP->mStreamEndpoint->mEP); OTInstallNotifier(mNewEP->mStreamEndpoint->mEP, mNewEP->mNotifier.fUPP, mNewEP->mStreamEndpoint); if (mNewEP->mMode == kNMNormalMode) { OTRemoveNotifier(mNewEP->mDatagramEndpoint->mEP); OTInstallNotifier(mNewEP->mDatagramEndpoint->mEP, mNewEP->mNotifier.fUPP, mNewEP->mDatagramEndpoint); } status = OTAccept(mListenerEP->mStreamEndpoint->mEP, mNewEP->mStreamEndpoint->mEP, mCall); DEBUG_NETWORK_API(mListenerEP->mStreamEndpoint->mEP, "OTAccept", status); if (status == kOTLookErr) { OTResult lookResult = OTLook(mListenerEP->mStreamEndpoint->mEP); if (lookResult == T_DISCONNECT) // the active peer disconnected OTRcvDisconnect(mListenerEP->mStreamEndpoint->mEP, NULL); // fake the accept complete mListenerEP->HandleAcceptComplete(); // kill the new endpoint EndpointDisposer *killer = new EndpointDisposer(mNewEP, true); } if (! ScheduleDelete()) delete this; // this is pretty damn likely to crach [gg] return kNMNoError; }
NMErr EndpointHander::GetDatagramEP(void) { DEBUG_ENTRY_EXIT("EndpointHander::GetDatagramEP"); CachedEP *datagramEP = NULL; OTLink *acceptorLink = NULL; NMErr status = kNMNoError; // if we're not in uber mode, there should be no datagram ep // just jump to the notifier if (mNewEP->mMode != kNMNormalMode) { Notifier(this, T_BINDCOMPLETE, kNMNoError, NULL); return kNMNoError; } //Try_ { // Get a datagram endpoint from the cache acceptorLink = OTLIFODequeue(&OTEndpoint::sDatagramEPCache.Q); if (acceptorLink) { OTAtomicAdd32(-1, &OTEndpoint::sDatagramEPCache.readyCount); OTAtomicAdd32(-1, &OTEndpoint::sDatagramEPCache.totalCount); //jacked up and good to go mState |= kGotDatagramEP; //get the cache reloading itself OTEndpoint::ServiceEPCaches(); } //if we couldn't get one off the cache, we'll make one after we have a stream endpoint // (one at a time for simplicity) else { if (mState & kGotStreamEP) { return OTAsyncOpenEndpoint(OTCreateConfiguration(mListenerEP->GetDatagramProtocolName()), 0, NULL, mNotifier.fUPP, this); } return kNMNoError; //we just wait for the stream endpoint to get done } // Get the pointer to the cached ep object datagramEP = OTGetLinkObject(acceptorLink, CachedEP, link); op_assert(datagramEP != NULL); // Remove the notifier that was being used for cacheing and install the "normal" one OTRemoveNotifier(datagramEP->ep); OTInstallNotifier(datagramEP->ep, mNotifier.fUPP, this); mNewEP->mDatagramEndpoint->mEP = datagramEP->ep; delete datagramEP; //if we got both endpoints, go ahead and bind here if (mState & kGotStreamEP) { // Bind the endpoint. Execution continues in the notifier for T_BINDCOMPLETE mBindReq.addr.len = 0; mBindReq.addr.buf = NULL; mBindRet.addr = mNewEP->mDatagramEndpoint->mLocalAddress; status = OTBind(mNewEP->mDatagramEndpoint->mEP,NULL, &mBindRet); //status = OTBind(mNewEP->mDatagramEndpoint->mEP,&mBindReq, &mBindRet); DEBUG_NETWORK_API(mNewEP->mDatagramEndpoint->mEP, "OTBind", status); //ThrowIfOSErr_(status); if (status) goto error; } } //Catch_(code) error: if (status) { NMErr code = status; return code; } return kNMNoError; }