/** * Submits asynchronous XRPC call. Doesn't wait until the call completes. * This resolves the deadlock between Ecmt Gateway and emulator.exe */ STATIC void GWENG_SubmitAsyncCall(MidpSession* midp, XRpcString method, XRpcContainer* params) { if (params) { AsyncXRpcEntry* a = MEM_New(AsyncXRpcEntry); if (a) { memset(a, 0, sizeof(*a)); a->method = method; a->params = params; MUTEX_Lock(&midp->xrpcMutex); QUEUE_InsertTail(&midp->xrpcQueue, &a->entry); MUTEX_Unlock(&midp->xrpcMutex); if (!WKI_Submit(midp->xrpcWorkItem)) { /* * The work item is busy processing pending calls. It * could be that GWENG_AsyncXRpc callback has already * exited the loop but hasn't returned yet. In that case, * this asynchronous call would remain in the queue until * we submit the next one. That's not good. Try to "kick" * it with another work item. */ WKQ_InvokeLater(midp->xrpcWorkThread, GWENG_AsyncXRpc, midp); } } else { XRPC_FreeContainer(params); } } }
/** * Submits internal workitem that will invoke the specified callback function * with the specified parameters */ Bool WKQ_InvokeLater2 (WorkQueue * q, WorkProc2 cb, void * p1, void * p2) { Bool ok = False; WorkItem * w = WKI_Create2(q, cb, p1, p2); if (w) { ok = WKI_Submit(w); WKI_Detach(w); } return ok; }
/** * Submits internal workitem that will invoke the specified callback function * with the specified parameter */ Bool WKQ_InvokeLater(WorkQueue * q, WorkProc cb, void * par) { Bool ok = False; WorkItem * w = WKI_Create(q, cb, par); if (w) { ok = WKI_Submit(w); WKI_Detach(w); } return ok; }