Ejs *ejsCreateVM(int argc, cchar **argv, int flags) { EjsService *sp; Ejs *ejs; if ((ejs = mprAllocObj(Ejs, manageEjs)) == NULL) { return 0; } sp = ejs->service = MPR->ejsService; if (sp == 0) { sp = ejs->service = createService(); defineSharedTypes(ejs); } ejs->empty = 1; ejs->state = mprAllocZeroed(sizeof(EjsState)); ejs->argc = argc; ejs->argv = argv; ejs->name = sfmt("ejs-%d", sp->seqno++); ejs->dispatcher = mprCreateDispatcher(ejs->name, MPR_DISPATCHER_ENABLED); ejs->mutex = mprCreateLock(ejs); ejs->dontExit = sp->dontExit; ejs->flags |= (flags & (EJS_FLAG_NO_INIT | EJS_FLAG_DOC | EJS_FLAG_HOSTED)); ejs->hosted = (flags & EJS_FLAG_HOSTED) ? 1 : 0; ejs->global = ejsCreateBlock(ejs, 0); mprSetName(ejs->global, "global"); ejsDefineGlobalNamespaces(ejs); /* Modules are not marked in the modules list. This way, modules are collected when not referenced. Workers are marked. This way workers are preserved to run in the background until they exit. */ ejs->modules = mprCreateList(-1, MPR_LIST_STATIC_VALUES); ejs->workers = mprCreateList(0, 0); initStack(ejs); initSearchPath(ejs, 0); mprAddItem(sp->vmlist, ejs); if (ejs->hasError || mprHasMemError(ejs)) { ejsDestroyVM(ejs); mprError("Cannot create VM"); return 0; } mprLog(5, "ejs: create VM"); return ejs; }
/* Per-thread execution. Called for main thread and helper threads. */ static void threadMain(void *data, MprThread *tp) { ThreadData *td; HttpConn *conn; MprEvent e; td = tp->data; td->dispatcher = mprCreateDispatcher(tp->name, 1); td->conn = conn = httpCreateConn(app->http, NULL, td->dispatcher); /* Relay to processThread via the dispatcher. This serializes all activity on the conn->dispatcher */ e.mask = MPR_READABLE; e.data = tp; mprRelayEvent(conn->dispatcher, (MprEventProc) processThread, conn, &e); }
PUBLIC void mprQueueIOEvent(MprWaitHandler *wp) { MprDispatcher *dispatcher; MprEvent *event; if (wp->flags & MPR_WAIT_NEW_DISPATCHER) { dispatcher = mprCreateDispatcher("IO", MPR_DISPATCHER_AUTO); } else if (wp->dispatcher) { dispatcher = wp->dispatcher; } else { dispatcher = mprGetDispatcher(); } event = mprCreateEvent(dispatcher, "IOEvent", 0, ioEvent, wp->handlerData, MPR_EVENT_DONT_QUEUE); event->mask = wp->presentMask; event->handler = wp; wp->event = event; mprQueueEvent(dispatcher, event); }
/* Convenience method to issue a client http request. Assumes the Mpr and Http services are created and initialized. */ PUBLIC HttpConn *httpRequest(cchar *method, cchar *uri, cchar *data, char **err) { HttpConn *conn; MprDispatcher *dispatcher; ssize len; if (err) { *err = 0; } dispatcher = mprCreateDispatcher("httpRequest", MPR_DISPATCHER_AUTO); mprStartDispatcher(dispatcher); conn = httpCreateConn(NULL, dispatcher); mprAddRoot(conn); /* Open a connection to issue the request. Then finalize the request output - this forces the request out. */ if (httpConnect(conn, method, uri, NULL) < 0) { mprRemoveRoot(conn); httpDestroyConn(conn); *err = sfmt("Cannot connect to %s", uri); return 0; } if (data) { len = slen(data); if (httpWriteBlock(conn->writeq, data, len, HTTP_BLOCK) != len) { *err = sclone("Cannot write request body data"); } } httpFinalizeOutput(conn); if (httpWait(conn, HTTP_STATE_CONTENT, MPR_MAX_TIMEOUT) < 0) { mprRemoveRoot(conn); httpDestroyConn(conn); *err = sclone("No response"); return 0; } mprRemoveRoot(conn); return conn; }
/* Convenience method to issue a client http request. Assumes the Mpr and Http services are created and initialized. */ PUBLIC HttpStream *httpRequest(cchar *method, cchar *uri, cchar *data, int protocol, char **err) { HttpNet *net; HttpStream *stream; MprDispatcher *dispatcher; assert(err); dispatcher = mprCreateDispatcher("httpRequest", MPR_DISPATCHER_AUTO); mprStartDispatcher(dispatcher); net = httpCreateNet(dispatcher, NULL, protocol, 0); if ((stream = httpCreateStream(net, 0)) == 0) { return 0; } mprAddRoot(stream); if (clientRequest(stream, method, uri, data, protocol, err) < 0) { mprRemoveRoot(stream); httpDestroyNet(net); return 0; } mprRemoveRoot(stream); return stream; }
/* * Add a shell parameter then do the regular init */ Mpr *mprCreateEx(int argc, char **argv, MprAllocNotifier cback, void *shell) { MprFileSystem *fs; Mpr *mpr; char *cp; if (cback == 0) { cback = memoryFailure; } mpr = (Mpr*) mprCreateAllocService(cback, (MprDestructor) mprDestructor); if (mpr == 0) { mprAssert(mpr); return 0; } /* * Wince and Vxworks passes an arg via argc, and the program name in argv. NOTE: this will only work on 32-bit systems. */ #if WINCE mprMakeArgv(mpr, (char*) argv, mprToAsc(mpr, (uni*) argc), &argc, &argv); #elif VXWORKS mprMakeArgv(mpr, NULL, (char*) argc, &argc, &argv); #endif mpr->argc = argc; mpr->argv = argv; mpr->name = mprStrdup(mpr, BLD_PRODUCT); mpr->title = mprStrdup(mpr, BLD_NAME); mpr->version = mprStrdup(mpr, BLD_VERSION); mpr->idleCallback = mprServicesAreIdle; if (mprCreateTimeService(mpr) < 0) { goto error; } if ((mpr->osService = mprCreateOsService(mpr)) < 0) { goto error; } /* * See if any of the preceeding allocations failed and mark all blocks allocated so far as required. * They will then be omitted from leak reports. */ if (mprHasAllocError(mpr)) { goto error; } #if BREW mprSetShell(mpr, shell); #endif #if BLD_FEATURE_MULTITHREAD mpr->multiThread = 1; if ((mpr->threadService = mprCreateThreadService(mpr)) == 0) { goto error; } mpr->mutex = mprCreateLock(mpr); mpr->spin = mprCreateSpinLock(mpr); #endif if ((fs = mprCreateFileSystem(mpr, "/")) == 0) { goto error; } mprAddFileSystem(mpr, fs); if ((mpr->moduleService = mprCreateModuleService(mpr)) == 0) { goto error; } if ((mpr->dispatcher = mprCreateDispatcher(mpr)) == 0) { goto error; } #if BLD_FEATURE_CMD if ((mpr->cmdService = mprCreateCmdService(mpr)) == 0) { goto error; } #endif #if BLD_FEATURE_MULTITHREAD if ((mpr->workerService = mprCreateWorkerService(mpr)) == 0) { goto error; } #endif if ((mpr->waitService = mprCreateWaitService(mpr)) == 0) { goto error; } if ((mpr->socketService = mprCreateSocketService(mpr)) == 0) { goto error; } #if BLD_FEATURE_HTTP if ((mpr->httpService = mprCreateHttpService(mpr)) == 0) { goto error; } #endif if (mpr->argv && mpr->argv[0] && *mpr->argv[0]) { mprFree(mpr->name); mpr->name = mprGetPathBase(mpr, mpr->argv[0]); if ((cp = strchr(mpr->name, '.')) != 0) { *cp = '\0'; } } /* * Now catch all memory allocation errors up to this point. Should be none. */ if (mprHasAllocError(mpr)) { goto error; } return mpr; /* * Error return */ error: mprFree(mpr); return 0; }
/* Per-thread execution. Called for main thread and helper threads. */ static void threadMain(void *data, MprThread *tp) { ThreadData *td; HttpConn *conn; cchar *path; char *url; int next, count; td = tp->data; /* Create and start a dispatcher. This ensures that all activity on the connection in this thread will be serialized with respect to all I/O events and httpProtocol work. This also ensures that I/O events will be handled by this thread from httpWait. */ td->dispatcher = mprCreateDispatcher(tp->name, 0); mprStartDispatcher(td->dispatcher); td->conn = conn = httpCreateConn(NULL, td->dispatcher); httpFollowRedirects(conn, !app->nofollow); httpSetTimeout(conn, app->timeout, app->timeout); if (strcmp(app->protocol, "HTTP/1.0") == 0) { httpSetKeepAliveCount(conn, 0); httpSetProtocol(conn, "HTTP/1.0"); } if (app->iterations == 1) { conn->limits->keepAliveMax = 0; } if (app->username) { if (app->password == 0 && !strchr(app->username, ':')) { app->password = getPassword(); } httpSetCredentials(conn, app->username, app->password, app->authType); } for (count = 0; count < app->iterations; count++) { if (mprShouldDenyNewRequests(conn)) { break; } if (!app->success && !app->continueOnErrors) { break; } if (app->singleStep) waitForUser(); if (app->files && !app->upload) { for (next = 0; (path = mprGetNextItem(app->files, &next)) != 0; ) { /* If URL ends with "/", assume it is a directory on the target and append each file name */ if (app->target[strlen(app->target) - 1] == '/') { url = mprJoinPath(app->target, mprGetPathBase(path)); } else { url = app->target; } app->requestFiles = mprCreateList(-1, MPR_LIST_STATIC_VALUES | MPR_LIST_STABLE); mprAddItem(app->requestFiles, path); td->url = url = resolveUrl(conn, url); if (app->verbose) { mprPrintf("putting: %s to %s\n", path, url); } if (doRequest(conn, url, app->requestFiles) < 0) { app->success = 0; break; } } } else { td->url = url = resolveUrl(conn, app->target); if (doRequest(conn, url, app->files) < 0) { app->success = 0; break; } } if (app->verbose > 1) { mprPrintf("."); } } httpDestroyConn(conn); mprDestroyDispatcher(conn->dispatcher); finishThread(tp); }