void KPR_shell_execute_async(KprShellExec exec) { #define BUFSIZE 4096 char buffer[BUFSIZE]; DWORD result = 0; BOOL bSuccess = FALSE; CloseHandle(exec->hWritePipe); exec->hWritePipe = NULL; for (;;) { if (!ReadFile(exec->hReadPipe, buffer, BUFSIZE, &result, NULL) || (result == 0)) break; buffer[result] = 0; exec->usage++; FskThreadPostCallback(KprShellGetThread(gShell), (FskThreadCallback)KPR_shell_execute_stderr, exec, FskStrDoCopy(buffer), NULL, NULL); } WaitForSingleObject(exec->pi.hProcess, INFINITE); GetExitCodeProcess(exec->pi.hProcess, &result); exec->status = (xsIntegerValue)result; CloseHandle(exec->hReadPipe); exec->hReadPipe = NULL; CloseHandle(exec->pi.hProcess); exec->pi.hProcess = NULL; CloseHandle(exec->pi.hThread); exec->pi.hThread = NULL; FskThreadPostCallback(KprShellGetThread(gShell), (FskThreadCallback)KPR_shell_execute_callback, exec, NULL, NULL, NULL); }
FskErr KprMessageInvoke(KprMessage self, KprMessageCallbackProc callback, KprMessageDisposeProc dispose, void* target) { KprService service = gServices; FskInstrumentedItemSendMessageDebug(self, kprInstrumentedMessageInvoke, self); if (self->waiting) return kFskErrOutOfSequence; while (service) { if ((*service->accept)(service, self)) { self->waiting = true; if (target) { self->request.callback = callback; self->request.dispose = dispose; self->request.target = target; self->usage++; // request } FskListAppend(&gShell->messages, self); self->usage++; // message queue if (!service->thread) service->thread = KprShellGetThread(gShell); if (service == &gXKPRService) self->usage++; // event queue FskThreadPostCallback(service->thread, (FskThreadCallback)service->invoke, service, self, NULL, NULL); return kFskErrNone; } service = service->next; } return kFskErrUnimplemented; }
void KprMessageCancel(KprMessage self) { KprService service = gServices; FskInstrumentedItemSendMessageDebug(self, kprInstrumentedMessageCancel, self); if (self->waiting) { self->waiting = false; if (self->request.target) { if (self->request.dispose) (*self->request.dispose)(self->request.target); self->request.callback = NULL; self->request.dispose = NULL; self->request.target = NULL; self->usage--; // request } while (service) { if ((*service->accept)(service, self)) { if (!service->thread) service->thread = KprShellGetThread(gShell); if (service == &gXKPRService) self->usage++; // event queue FskThreadPostCallback(service->thread, (FskThreadCallback)service->cancel, service, self, NULL, NULL); break; } service = service->next; } } }
void KprHTTPClientResumeTarget(KprHTTPTarget target) { KprMessage message = target->message; FskInstrumentedItemSendMessageDebug(target->message, kprInstrumentedMessageHTTPEnd, message) KprHTTPTargetDispose(target); FskThreadPostCallback(KprShellGetThread(gShell), (FskThreadCallback)KprMessageComplete, message, NULL, NULL, NULL); }
FskErr KprMessageNotify(KprMessage self) { FskErr err = kFskErrNone; FskInstrumentedItemSendMessageDebug(self, kprInstrumentedMessageNotify, self); if (!FskStrCompareWithLength(self->parts.scheme, "xkpr", self->parts.schemeLength)) { self->usage++; // event queue FskThreadPostCallback(KprShellGetThread(gShell), (FskThreadCallback)KprMessageNotifyCallback, gShell, self, NULL, NULL); } else err = kFskErrUnimplemented; return err; }
void KprServicesForget(KprContext context, char* id) { KprService service = gServices; while (service) { if (service->forget) { if (!service->thread) service->thread = KprShellGetThread(gShell); FskThreadPostCallback(service->thread, (FskThreadCallback)service->forget, service, FskStrDoCopy(context->id), FskStrDoCopy(id), NULL); } service = service->next; } }
void KprServicesShare(KprContext context, Boolean shareIt, char* services) { KprService service = gServices; while (service) { if (service->share) { if (!service->thread) service->thread = KprShellGetThread(gShell); FskThreadPostCallback(service->thread, (FskThreadCallback)service->share, service, FskStrDoCopy(context->id), services ? (FskStrStr(services, service->id) != NULL) : shareIt, services ? false : true); } service = service->next; } }
void KprServicesStart(KprShell shell) { UInt32 flags = kFskThreadFlagsWaitForInit | kFskThreadFlagsJoinable; KprService service = gServices; FskThread thread = KprShellGetThread(gShell); xsMachine* the = gShell->the; gServicesThreadQuitting = false; FskThreadCreate(&gServicesThread, KprServicesLoop, flags, NULL, "services"); while (service) { if (!(service->flags & kprServicesThread)) { FskInstrumentedTypePrintfNormal(&KprServiceInstrumentation, "Starting %s", service->id); (*service->start)(service, thread, the); } service = service->next; } }
void KprMessageComplete(KprMessage self) { char* url; FskThread thread = KprShellGetThread(gShell); if (!thread) return; // @@ happens on exit if (thread != FskThreadGetCurrent()) { FskThreadPostCallback(thread, (FskThreadCallback)KprMessageComplete, self, NULL, NULL, NULL); return; } FskInstrumentedItemSendMessageDebug(self, kprInstrumentedMessageComplete, self); if (FskListRemove(&gShell->messages, self)) { self->usage--; // message queue self->waiting = false; url = KprMessageGetResponseHeader(self, "location"); if (url && (!FskStrCompareWithLength(self->url, "xkpr", 4)) && ((!self->sniffing) || (!FskStrCompareWithLength(url, "xkpr", 4)))) { FskMemPtrDispose(self->url); self->url = FskStrDoCopy(url); //bailIfNULL(self->url); KprURLSplit(self->url, &self->parts); FskAssociativeArrayDispose(self->response.headers); self->response.headers = NULL; FskMemPtrDispose(self->response.body); self->response.body = NULL; self->response.size = 0; if (self->request.target) self->usage--; // @@ request if (kFskErrNone == KprMessageInvoke(self, self->request.callback, self->request.dispose, self->request.target)) return; } if (self->request.target) { if (self->request.callback) (*self->request.callback)(self, self->request.target); if (self->request.dispose) (*self->request.dispose)(self->request.target); self->request.callback = NULL; self->request.dispose = NULL; self->request.target = NULL; self->usage--; // request } if (!self->usage) KprMessageDispose(self); } }
void KprServicesDiscover(KprContext context, char* id, char* services) { KprService service = gServices; while (service) { if (service->discover) { if (!service->thread) service->thread = KprShellGetThread(gShell); if (services) { if (FskStrStr(services, service->id)) FskThreadPostCallback(service->thread, (FskThreadCallback)service->discover, service, FskStrDoCopy(context->id), FskStrDoCopy(id), false); else if (service->forget) FskThreadPostCallback(service->thread, (FskThreadCallback)service->forget, service, FskStrDoCopy(context->id), FskStrDoCopy(id), NULL); } else FskThreadPostCallback(service->thread, (FskThreadCallback)service->discover, service, FskStrDoCopy(context->id), FskStrDoCopy(id), (void*)true); } service = service->next; } }
void KprHTTPClientInvoke(KprService service UNUSED, KprMessage message) { FskErr err = kFskErrNone; KprHTTPClient self = gKprHTTPClient; if (KprMessageContinue(message)) { KprHTTPTarget target = NULL; KprHTTPCacheValue cached = NULL; char* value; FskInstrumentedItemSendMessageDebug(message, kprInstrumentedMessageHTTPBegin, message) bailIfError(KprHTTPTargetNew(&target, message)); if (!message->method || !FskStrCompare(message->method, "GET")) KprHTTPCacheFetch(self->cache, message->url, &cached); if (cached) { if (KprHTTPCacheValueIsFresh(cached)) { if (KprHTTPClientReadCache(message, cached) == kFskErrNone) { KprMessageTransform(message, gHTTPService.machine); KprHTTPClientResumeTarget(target); return; } } else { value = FskAssociativeArrayElementGetString(cached->headers, kprHTTPHeaderLastModified); if (value) (void)KprMessageSetRequestHeader(message, kprHTTPHeaderIfModifiedSince, value); value = FskAssociativeArrayElementGetString(cached->headers, kprHTTPHeaderETag); if (value) (void)KprMessageSetRequestHeader(message, kprHTTPHeaderIfNoneMatch, value); target->cached = cached; } } KprHTTPClientCookiesGet(message->url, &value); if (value) { (void)KprMessageSetRequestHeader(message, kprHTTPHeaderCookie, value); FskMemPtrDispose(value); } KprHTTPClientAddTarget(target); return; bail: message->error = err; } FskThreadPostCallback(KprShellGetThread(gShell), (FskThreadCallback)KprMessageComplete, message, NULL, NULL, NULL); }
void KprWebSocketEndpointInvokeAfter(void *func, void *param1, void *param2, void *param3, void *param4) { FskThreadPostCallback(KprShellGetThread(gShell), (FskThreadCallback)func, param1, param2, param3, param4); }
void KprMQTTInvokeAfter(void *func, void *param1, void *param2, void *param3, void *param4) { FskThreadPostCallback(KprShellGetThread(gShell), (FskThreadCallback)func, param1, param2, param3, param4); }
void KprZeroconfBrowserServiceDown(KprZeroconfBrowser self, KprZeroconfServiceInfo service) { if (!self) self = KprZeroconfBrowserFind(NULL, service->type); if (!self) return; FskInstrumentedItemPrintfDebug(self, "%p - KprZeroconfBrowserServiceDown %s %s - %p %p", self, service->type, service->name, KprShellGetThread(gShell), FskThreadGetCurrent()); if (self->serviceDownCallback) (*self->serviceDownCallback)(self, service); KprZeroconfServiceInfoDispose(service); }