int64 mprIncCache(MprCache *cache, cchar *key, int64 amount) { CacheItem *item; int64 value; mprAssert(cache); mprAssert(key && *key); if (cache->shared) { cache = cache->shared; mprAssert(cache == shared); } value = amount; lock(cache); if ((item = mprLookupKey(cache->store, key)) == 0) { if ((item = mprAllocObj(CacheItem, manageCacheItem)) == 0) { return 0; } } else { value += stoi(item->data); } if (item->data) { cache->usedMem -= slen(item->data); } item->data = itos(value); cache->usedMem += slen(item->data); item->version++; item->lastAccessed = mprGetTime(); item->expires = item->lastAccessed + item->lifespan; unlock(cache); return value; }
/* Open the handler for a new request */ static int openCgi(HttpQueue *q) { HttpConn *conn; Cgi *cgi; int nproc; conn = q->conn; mprTrace(5, "Open CGI handler"); if ((nproc = (int) httpMonitorEvent(conn, HTTP_COUNTER_ACTIVE_PROCESSES, 1)) >= conn->limits->processMax) { mprLog(2, "Too many concurrent processes %d/%d", nproc, conn->limits->processMax); httpError(conn, HTTP_CODE_SERVICE_UNAVAILABLE, "Server overloaded"); httpMonitorEvent(q->conn, HTTP_COUNTER_ACTIVE_PROCESSES, -1); return MPR_ERR_CANT_OPEN; } if ((cgi = mprAllocObj(Cgi, manageCgi)) == 0) { /* Normal mem handler recovery */ return MPR_ERR_MEMORY; } httpTrimExtraPath(conn); httpMapFile(conn); httpCreateCGIParams(conn); q->queueData = q->pair->queueData = cgi; cgi->conn = conn; cgi->readq = httpCreateQueue(conn, conn->http->cgiConnector, HTTP_QUEUE_RX, 0); cgi->writeq = httpCreateQueue(conn, conn->http->cgiConnector, HTTP_QUEUE_TX, 0); cgi->readq->pair = cgi->writeq; cgi->writeq->pair = cgi->readq; cgi->writeq->queueData = cgi->readq->queueData = cgi; return 0; }
MprModule *mprCreateModule(cchar *name, cchar *path, cchar *entry, void *data) { MprModuleService *ms; MprModule *mp; int index; ms = MPR->moduleService; mprAssert(ms); if ((mp = mprAllocObj(MprModule, manageModule)) == 0) { return 0; } mp->name = sclone(name); mp->path = sclone(path); if (entry && *entry) { mp->entry = sclone(entry); } mp->moduleData = data; mp->lastActivity = mprGetTime(); index = mprAddItem(ms->modules, mp); if (index < 0 || mp->name == 0) { return 0; } return mp; }
/* Action to run in response to the "test/output" URI */ static void output_action() { Output *output; /* Don't automatically finalize (complete) the request when this routine returns. This keeps the connection open. */ dontAutoFinalize(); /* Define the event notifier. We're interested in WRITABLE events */ setNotifier(output_callback); /* Open a file for output. Could use open/write, but we use the MPR equivalents for cross-platform I/O. */ output = mprAllocObj(Output, manageOutput); if ((output->file = mprOpenFile(OUTPUT_FILE, O_RDONLY, 0)) == 0) { httpError(getConn(), HTTP_CODE_INTERNAL_SERVER_ERROR, "Cannot open huge.txt"); return; } mprGetPathInfo(OUTPUT_FILE, &output->info); /* Save a reference to our output state */ setData(output); }
static EspRoute *cloneEspRoute(HttpRoute *route, EspRoute *parent) { EspRoute *eroute; assert(parent); assert(route); if ((eroute = mprAllocObj(EspRoute, espManageEspRoute)) == 0) { return 0; } eroute->route = route; eroute->top = parent->top; eroute->searchPath = parent->searchPath; eroute->configFile = parent->configFile; eroute->edi = parent->edi; eroute->commonController = parent->commonController; if (parent->compile) { eroute->compile = sclone(parent->compile); } if (parent->link) { eroute->link = sclone(parent->link); } if (parent->env) { eroute->env = mprCloneHash(parent->env); } eroute->appName = parent->appName; eroute->combine = parent->combine; #if DEPRECATED || 1 eroute->combineScript = parent->combineScript; eroute->combineSheet = parent->combineSheet; #endif route->eroute = eroute; return eroute; }
static EjsService *createService() { EjsService *sp; if (MPR->ejsService) { return MPR->ejsService; } if ((sp = mprAllocObj(EjsService, manageEjsService)) == NULL) { return 0; } mprGlobalLock(); MPR->ejsService = sp; #if FUTURE && KEEP mprSetMemNotifier((MprMemNotifier) allocNotifier); #endif sp->nativeModules = mprCreateHash(-1, MPR_HASH_STATIC_KEYS); sp->mutex = mprCreateLock(); sp->vmlist = mprCreateList(-1, MPR_LIST_STATIC_VALUES); sp->vmpool = mprCreateList(-1, MPR_LIST_STATIC_VALUES); sp->intern = ejsCreateIntern(sp); sp->dtoaSpin[0] = mprCreateSpinLock(); sp->dtoaSpin[1] = mprCreateSpinLock(); ejsInitCompiler(sp); mprGlobalUnlock(); return sp; }
PUBLIC HttpTx *httpCreateTx(HttpConn *conn, MprHash *headers) { HttpTx *tx; if ((tx = mprAllocObj(HttpTx, manageTx)) == 0) { return 0; } conn->tx = tx; tx->conn = conn; tx->status = HTTP_CODE_OK; tx->length = -1; tx->entityLength = -1; tx->chunkSize = -1; tx->queue[HTTP_QUEUE_TX] = httpCreateQueueHead(conn, "TxHead"); conn->writeq = tx->queue[HTTP_QUEUE_TX]->nextQ; tx->queue[HTTP_QUEUE_RX] = httpCreateQueueHead(conn, "RxHead"); conn->readq = tx->queue[HTTP_QUEUE_RX]->prevQ; if (headers) { tx->headers = headers; } else { tx->headers = mprCreateHash(HTTP_SMALL_HASH_SIZE, MPR_HASH_CASELESS); if (!conn->endpoint) { httpAddHeaderString(conn, "User-Agent", sclone(BIT_HTTP_SOFTWARE)); } } return tx; }
static int mdbAddTable(Edi *edi, cchar *tableName) { Mdb *mdb; MdbTable *table; assure(edi); assure(tableName && *tableName); mdb = (Mdb*) edi; lock(mdb); if ((table = lookupTable(mdb, tableName)) != 0) { unlock(mdb); return MPR_ERR_ALREADY_EXISTS; } if ((table = mprAllocObj(MdbTable, manageTable)) == 0) { unlock(mdb); return MPR_ERR_MEMORY; } if ((table->rows = mprCreateList(0, 0)) == 0) { unlock(mdb); return MPR_ERR_MEMORY; } table->name = sclone(tableName); if (mdb->tables == 0) { mdb->tables = mprCreateList(0, 0); } if (!growSchema(table)) { unlock(mdb); return MPR_ERR_MEMORY; } mprAddItem(mdb->tables, table); autoSave(mdb, lookupTable(mdb, tableName)); unlock(mdb); return 0; }
static void processing() { MprThread *tp; ThreadData *data; int j; if (app->chunkSize > 0) { mprAddItem(app->headers, mprCreateKeyPair("X-Appweb-Chunk-Size", sfmt("%d", app->chunkSize))); } app->activeLoadThreads = app->loadThreads; app->threadData = mprCreateList(app->loadThreads, 0); for (j = 0; j < app->loadThreads; j++) { char name[64]; if ((data = mprAllocObj(ThreadData, manageThreadData)) == 0) { return; } mprAddItem(app->threadData, data); mprSprintf(name, sizeof(name), "http.%d", j); tp = mprCreateThread(name, threadMain, NULL, 0); tp->data = data; mprStartThread(tp); } }
MAIN(simpleClient, int argc, char** argv) { Mpr *mpr; App *app; cchar *content; int code; /* Create the Multithreaded Portable Runtime */ mpr = mprCreate(argc, argv, MPR_USER_EVENTS_THREAD); if ((app = mprAllocObj(App, manageApp)) == 0) { return MPR_ERR_MEMORY; } mprAddRoot(app); mprAddStandardSignals(app); /* Start the Multithreaded Portable Runtime */ mprStart(); /* Create an Http service object */ app->http = httpCreate(mpr); /* Get a client http object to work with. We can issue multiple requests with this one object. */ app->conn = httpCreateConn(app->http, NULL, NULL); /* Get a URL */ if (httpConnect(app->conn, "GET", "http://www.embedthis.com/index.html") < 0) { mprError("Can't get URL"); exit(2); } /* Examine the HTTP response HTTP code. 200 is success. */ code = httpGetStatus(app->conn); if (code != 200) { mprError("Server responded with code %d\n", code); exit(1); } /* Get the actual response content */ content = httpReadString(app->conn); if (content) { mprPrintf("Server responded with: %s\n", content); } mprDestroy(MPR_EXIT_DEFAULT); return 0; }
MAIN(benchMpr, int argc, char **argv, char **envp) { MprThread *thread; Mpr *mpr; char *argp; int err, nextArg; if ((mpr = mprCreate(argc, argv, MPR_USER_EVENTS_THREAD)) == 0) { return MPR_ERR_MEMORY; } if ((app = mprAllocObj(App, manageApp)) == 0) { return MPR_ERR_MEMORY; } mprAddRoot(app); app->mutex = mprCreateLock(mpr); app->complete = mprCreateCond(); app->iterations = 5; err = 0; for (nextArg = 1; nextArg < argc; nextArg++) { argp = argv[nextArg]; if (*argp != '-') { break; } if (strcmp(argp, "--iterations") == 0 || strcmp(argp, "-i") == 0) { if (nextArg >= argc) { err++; } else { app->iterations = atoi(argv[++nextArg]); } } else if (strcmp(argp, "--alloc") == 0 || strcmp(argp, "-a") == 0) { app->testAllocOnly++; } else { err++; } } if (err) { mprEprintf("usage: bench [-a] [-i iterations]\n"); mprEprintf("usage: %s [options]\n" " -a # Alloc test only\n" " --iterations count # Number of iterations to run the test\n", mprGetAppName(mpr)); exit(2); } mprStart(mpr); thread = mprCreateThread("bench", (MprThreadProc) doBenchmark, (void*) MPR, 0); mprStartThread(thread); while (!testComplete) { mprServiceEvents(250, 0); } mprPrintMem("Memory Report", 0); mprDestroy(); return 0; }
MAIN(httpMain, int argc, char *argv[]) { MprTime start; double elapsed; if (mprCreate(argc, argv, MPR_USER_EVENTS_THREAD) == 0) { return MPR_ERR_MEMORY; } if ((app = mprAllocObj(App, manageApp)) == 0) { return MPR_ERR_MEMORY; } mprAddRoot(app); mprAddStandardSignals(); initSettings(); if (!parseArgs(argc, argv)) { showUsage(); return MPR_ERR_BAD_ARGS; } mprSetMaxWorkers(app->workers); #if BLD_FEATURE_SSL if (!mprLoadSsl(1)) { mprError("Can't load SSL"); exit(1); } #endif if (mprStart() < 0) { mprError("Can't start MPR for %s", mprGetAppTitle()); exit(2); } start = mprGetTime(); app->http = httpCreate(); httpEaseLimits(app->http->clientLimits); processing(); mprServiceEvents(-1, 0); if (app->benchmark) { elapsed = (double) (mprGetTime() - start); if (app->fetchCount == 0) { elapsed = 0; app->fetchCount = 1; } mprPrintf("\nRequest Count: %13d\n", app->fetchCount); mprPrintf("Time elapsed: %13.4f sec\n", elapsed / 1000.0); mprPrintf("Time per request: %13.4f sec\n", elapsed / 1000.0 / app->fetchCount); mprPrintf("Requests per second: %13.4f\n", app->fetchCount * 1.0 / (elapsed / 1000.0)); mprPrintf("Load threads: %13d\n", app->loadThreads); mprPrintf("Worker threads: %13d\n", app->workers); } if (!app->success && app->verbose) { mprError("Request failed"); } return (app->success) ? 0 : 255; }
/* Initialize the MPR SSL layer */ PUBLIC int mprSslInit(void *unused, MprModule *module) { RandBuf randBuf; int i; randBuf.now = mprGetTime(); randBuf.pid = getpid(); RAND_seed((void*) &randBuf, sizeof(randBuf)); #if ME_UNIX_LIKE RAND_load_file("/dev/urandom", 256); #endif if ((openProvider = mprAllocObj(MprSocketProvider, manageOpenProvider)) == NULL) { return MPR_ERR_MEMORY; } openProvider->name = sclone("openssl"); openProvider->upgradeSocket = upgradeOss; openProvider->closeSocket = closeOss; openProvider->disconnectSocket = disconnectOss; openProvider->flushSocket = flushOss; openProvider->socketState = getOssState; openProvider->readSocket = readOss; openProvider->writeSocket = writeOss; mprSetSslProvider(openProvider); /* Configure the SSL library. Use the crypto ID as a one-time test. This allows users to configure the library and have their configuration used instead. */ mprGlobalLock(); if (CRYPTO_get_id_callback() == 0) { numLocks = CRYPTO_num_locks(); if ((olocks = mprAlloc(numLocks * sizeof(MprMutex*))) == 0) { return MPR_ERR_MEMORY; } for (i = 0; i < numLocks; i++) { olocks[i] = mprCreateLock(); } CRYPTO_set_id_callback(sslThreadId); CRYPTO_set_locking_callback(sslStaticLock); CRYPTO_set_dynlock_create_callback(sslCreateDynLock); CRYPTO_set_dynlock_destroy_callback(sslDestroyDynLock); CRYPTO_set_dynlock_lock_callback(sslDynLock); #if !ME_WIN_LIKE OpenSSL_add_all_algorithms(); #endif /* WARNING: SSL_library_init() is not reentrant. Caller must ensure safety. */ SSL_library_init(); SSL_load_error_strings(); } mprGlobalUnlock(); return 0; }
MprXml *mprXmlOpen(ssize initialSize, ssize maxSize) { MprXml *xp; xp = mprAllocObj(MprXml, manageXml); xp->inBuf = mprCreateBuf(MPR_XML_BUFSIZE, MPR_XML_BUFSIZE); xp->tokBuf = mprCreateBuf(initialSize, maxSize); return xp; }
PUBLIC HttpStage *httpCloneStage(HttpStage *stage) { HttpStage *clone; if ((clone = mprAllocObj(HttpStage, manageStage)) == 0) { return 0; } *clone = *stage; return clone; }
/* Create and queue a new event for service. Period is used as the delay before running the event and as the period between events for continuous events. */ PUBLIC MprEvent *mprCreateEventQueue() { MprEvent *queue; if ((queue = mprAllocObj(MprEvent, manageEvent)) == 0) { return 0; } initEventQ(queue, "eventq"); return queue; }
PUBLIC HttpAuth *httpCreateAuth() { HttpAuth *auth; if ((auth = mprAllocObj(HttpAuth, manageAuth)) == 0) { return 0; } auth->realm = MPR->emptyString; return auth; }
static Dir *allocDir(HttpRoute *route) { Dir *dir; if ((dir = mprAllocObj(Dir, manageDir)) == 0) { return 0; } httpSetRouteData(route, DIR_NAME, dir); return dir; }
// TODO - where to move this? EjsName *ejsAllocName(MprCtx ctx, cchar *name, cchar *space) { EjsName *np; np = mprAllocObj(ctx, EjsName); if (np) { np->name = mprStrdup(np, name); np->space = mprStrdup(np, space); } return np; }
PUBLIC MprCmdService *mprCreateCmdService() { MprCmdService *cs; if ((cs = (MprCmdService*) mprAllocObj(MprCmd, manageCmdService)) == 0) { return 0; } cs->cmds = mprCreateList(0, 0); cs->mutex = mprCreateLock(); return cs; }
PUBLIC HttpQueue *httpCreateQueueHead(HttpConn *conn, cchar *name) { HttpQueue *q; if ((q = mprAllocObj(HttpQueue, manageQueue)) == 0) { return 0; } httpInitQueue(conn, q, name); httpInitSchedulerQueue(q); return q; }
PUBLIC MprWaitHandler *mprCreateWaitHandler(int fd, int mask, MprDispatcher *dispatcher, void *proc, void *data, int flags) { MprWaitHandler *wp; assert(fd >= 0); if ((wp = mprAllocObj(MprWaitHandler, manageWaitHandler)) == 0) { return 0; } return initWaitHandler(wp, fd, mask, dispatcher, proc, data, flags); }
PUBLIC HttpUri *httpCloneUri(HttpUri *base, int flags) { HttpUri *up; char *path, *cp, *tok; if ((up = mprAllocObj(HttpUri, manageUri)) == 0) { return 0; } if (base->scheme) { up->scheme = sclone(base->scheme); } else if (flags & HTTP_COMPLETE_URI) { up->scheme = sclone("http"); } up->secure = (smatch(up->scheme, "https") || smatch(up->scheme, "wss")); up->webSockets = (smatch(up->scheme, "ws") || smatch(up->scheme, "wss")); if (base->host) { up->host = sclone(base->host); } else if (flags & HTTP_COMPLETE_URI) { up->host = sclone("localhost"); } if (base->port) { up->port = base->port; } else if (flags & HTTP_COMPLETE_URI) { up->port = (smatch(up->scheme, "https") || smatch(up->scheme, "wss"))? 443 : 80; } path = base->path; if (path) { while (path[0] == '/' && path[1] == '/') { path++; } up->path = sclone(path); } if (flags & (HTTP_COMPLETE_URI | HTTP_COMPLETE_URI_PATH)) { if (up->path == 0 || *up->path == '\0') { up->path = sclone("/"); } } if (base->reference) { up->reference = sclone(base->reference); } if (base->query) { up->query = sclone(base->query); } if (up->path && (tok = srchr(up->path, '.')) != 0) { if ((cp = srchr(up->path, '/')) != 0) { if (cp <= tok) { up->ext = sclone(&tok[1]); } } else { up->ext = sclone(&tok[1]); } } return up; }
static MprDispatcher *createQhead(cchar *name) { MprDispatcher *dispatcher; if ((dispatcher = mprAllocObj(MprDispatcher, manageDispatcher)) == 0) { return 0; } dispatcher->service = MPR->eventService; dispatcher->name = name; initDispatcher(dispatcher); return dispatcher; }
MprSignalService *mprCreateSignalService() { MprSignalService *ssp; if ((ssp = mprAllocObj(MprSignalService, manageSignalService)) == 0) { return 0; } ssp->mutex = mprCreateLock(); ssp->signals = mprAllocZeroed(sizeof(MprSignal*) * MPR_MAX_SIGNALS); ssp->standard = mprCreateList(-1, 0); return ssp; }
EdiService *ediCreateService() { EdiService *es; if ((es = mprAllocObj(EdiService, manageEdiService)) == 0) { return 0; } MPR->ediService = es; es->providers = mprCreateHash(0, MPR_HASH_STATIC_VALUES); addValidations(); return es; }
PUBLIC HttpRange *httpCreateRange(HttpStream *stream, MprOff start, MprOff end) { HttpRange *range; if ((range = mprAllocObj(HttpRange, manageRange)) == 0) { return 0; } range->start = start; range->end = end; range->len = end - start; return range; }
MAIN(httpMain, int argc, char **argv, char **envp) { MprTime start; double elapsed; if (mprCreate(argc, argv, MPR_USER_EVENTS_THREAD) == 0) { return MPR_ERR_MEMORY; } if ((app = mprAllocObj(App, manageApp)) == 0) { return MPR_ERR_MEMORY; } mprAddRoot(app); mprAddStandardSignals(); initSettings(); if (parseArgs(argc, argv) < 0) { return MPR_ERR_BAD_ARGS; } mprSetMaxWorkers(app->workers); if (mprStart() < 0) { mprError("Cannot start MPR for %s", mprGetAppTitle()); exit(2); } start = mprGetTime(); app->http = httpCreate(HTTP_CLIENT_SIDE); httpEaseLimits(app->http->clientLimits); #if BIT_STATIC && BIT_PACK_SSL extern MprModuleEntry mprSslInit; mprNop(mprSslInit); #endif processing(); mprServiceEvents(-1, 0); if (app->benchmark) { elapsed = (double) (mprGetTime() - start); if (app->fetchCount == 0) { elapsed = 0; app->fetchCount = 1; } mprPrintf("\nRequest Count: %13d\n", app->fetchCount); mprPrintf("Time elapsed: %13.4f sec\n", elapsed / 1000.0); mprPrintf("Time per request: %13.4f sec\n", elapsed / 1000.0 / app->fetchCount); mprPrintf("Requests per second: %13.4f\n", app->fetchCount * 1.0 / (elapsed / 1000.0)); mprPrintf("Load threads: %13d\n", app->loadThreads); mprPrintf("Worker threads: %13d\n", app->workers); } if (!app->success && app->verbose) { mprError("Request failed"); } mprDestroy(MPR_EXIT_DEFAULT); return (app->success) ? 0 : 255; }
MAIN(httpMain, int argc, char **argv, char **envp) { MprTime start; double elapsed; int success; if (mprCreate(argc, argv, MPR_USER_EVENTS_THREAD) == 0) { return MPR_ERR_MEMORY; } if ((app = mprAllocObj(App, manageApp)) == 0) { return MPR_ERR_MEMORY; } mprAddRoot(app); mprAddStandardSignals(); initSettings(); if ((app->http = httpCreate(HTTP_CLIENT_SIDE)) == 0) { return MPR_ERR_MEMORY; } if (parseArgs(argc, argv) < 0) { return MPR_ERR_BAD_ARGS; } mprSetMaxWorkers(app->workers); if (mprStart() < 0) { mprLog("error http", 0, "Cannot start MPR for %s", mprGetAppTitle()); exit(2); } start = mprGetTime(); processing(); mprServiceEvents(-1, 0); if (app->benchmark) { elapsed = (double) (mprGetTime() - start); if (app->fetchCount == 0) { elapsed = 0; app->fetchCount = 1; } mprPrintf("\nRequest Count: %13d\n", app->fetchCount); mprPrintf("Time elapsed: %13.4f sec\n", elapsed / 1000.0); mprPrintf("Time per request: %13.4f sec\n", elapsed / 1000.0 / app->fetchCount); mprPrintf("Requests per second: %13.4f\n", app->fetchCount * 1.0 / (elapsed / 1000.0)); mprPrintf("Load threads: %13d\n", app->loadThreads); mprPrintf("Worker threads: %13d\n", app->workers); } if (!app->success && app->verbose) { mprLog("error http", 0, "Request failed"); } success = app->success; mprDestroy(); return success ? 0 : 255; }
/* Open the module service */ PUBLIC MprModuleService *mprCreateModuleService() { MprModuleService *ms; if ((ms = mprAllocObj(MprModuleService, manageModuleService)) == 0) { return 0; } ms->modules = mprCreateList(-1, 0); ms->mutex = mprCreateLock(); MPR->moduleService = ms; mprSetModuleSearchPath(NULL); return ms; }