// Notification routine // Async callback routine. // A5 is OK. Cannot allocate memory here pascal void NotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie) { PRThread * thread = (PRThread *) contextPtr; _PRCPU *cpu = _PR_MD_CURRENT_CPU(); switch (code) { // Async Completion Event case T_OPENCOMPLETE: case T_BINDCOMPLETE: case T_UNBINDCOMPLETE: case T_GETPROTADDRCOMPLETE: case T_ACCEPTCOMPLETE: // Connect callback case T_CONNECT: // Standard or expedited data is available case T_DATA: case T_EXDATA: // Standard or expedited data Flow control lifted case T_GODATA: case T_GOEXDATA: // Asynchronous Listen Event case T_LISTEN: // DNR String To Address Complete Event case T_DNRSTRINGTOADDRCOMPLETE: // Option Management Request Complete Event case T_OPTMGMTCOMPLETE: thread->md.osErrCode = result; thread->md.cookie = cookie; if (_PR_MD_GET_INTSOFF()) { cpu->u.missed[cpu->where] |= _PR_MISSED_IO; thread->md.notifyPending = PR_TRUE; return; } DoneWaitingOnThisThread(thread); break; // T_ORDREL orderly release is available; nothing to do case T_ORDREL: break; // T_PASSCON; nothing to do case T_PASSCON: break; // T_DISCONNECT; disconnect is available; nothing to do case T_DISCONNECT: break; // UDP Send error; clear the error case T_UDERR: (void) OTRcvUDErr((EndpointRef) cookie, NULL); default: PR_ASSERT(0); } }
static void asyncIOCompletion (ExtendedParamBlock pbAsyncPtr_thread) { while (__START_ASYNC__ == False) {}; // second thread waits until the async read is issued PRThread thread = pbAsyncPtr_thread; if (_PR_MD_GET_INTSOFF()) { return; } _PR_MD_SET_INTSOFF(1); DoneWaitingOnThisThread(thread); _PR_MD_SET_INTSOFF(0); }