/* * Service requests for a web server. */ int maServiceWebServer(MaHttp *http) { if (maStartHttp(http) < 0) { mprError(http, "Can't start the web server"); return MPR_ERR_CANT_CREATE; } mprServiceEvents(mprGetDispatcher(http), -1, MPR_SERVICE_EVENTS | MPR_SERVICE_IO); maStopHttp(http); return 0; }
/* Create a new connection object */ PUBLIC HttpConn *httpCreateConn(HttpEndpoint *endpoint, MprDispatcher *dispatcher) { HttpConn *conn; HttpHost *host; HttpRoute *route; if ((conn = mprAllocObj(HttpConn, manageConn)) == 0) { return 0; } conn->protocol = HTTP->protocol; conn->http = HTTP; conn->port = -1; conn->retries = HTTP_RETRIES; conn->endpoint = endpoint; conn->lastActivity = HTTP->now; conn->ioCallback = httpIOEvent; if (endpoint) { conn->notifier = endpoint->notifier; host = mprGetFirstItem(endpoint->hosts); if (host && (route = host->defaultRoute) != 0) { conn->limits = route->limits; conn->trace = route->trace; } else { conn->limits = HTTP->serverLimits; conn->trace = HTTP->trace; } } else { conn->limits = HTTP->clientLimits; conn->trace = HTTP->trace; } conn->keepAliveCount = conn->limits->keepAliveMax; conn->serviceq = httpCreateQueueHead(conn, "serviceq"); if (dispatcher) { conn->dispatcher = dispatcher; } else if (endpoint) { conn->dispatcher = endpoint->dispatcher; } else { conn->dispatcher = mprGetDispatcher(); } conn->rx = httpCreateRx(conn); conn->tx = httpCreateTx(conn, NULL); httpSetState(conn, HTTP_STATE_BEGIN); httpAddConn(conn); return conn; }
int maRunSimpleWebServer(cchar *ipAddr, int port, cchar *docRoot) { Mpr *mpr; MaHttp *http; MaServer *server; /* * Initialize and start the portable runtime services. */ if ((mpr = mprCreate(0, NULL, NULL)) == 0) { mprError(mpr, "Can't create the web server runtime"); return MPR_ERR_CANT_CREATE; } if (mprStart(mpr, 0) < 0) { mprError(mpr, "Can't start the web server runtime"); return MPR_ERR_CANT_INITIALIZE; } /* * Create the HTTP object. */ if ((http = maCreateHttp(mpr)) == 0) { mprError(mpr, "Can't create the web server http services"); return MPR_ERR_CANT_INITIALIZE; } /* * Create and start the HTTP server. Give the server a name of "default" and define "." as * the default serverRoot, ie. the directory with the server configuration files. */ server = maCreateServer(http, ipAddr, ".", ipAddr, port); if (server == 0) { mprError(mpr, "Can't create the web server"); return MPR_ERR_CANT_CREATE; } maSetDocumentRoot(server->defaultHost, docRoot); if (maStartHttp(http) < 0) { mprError(mpr, "Can't start the web server"); return MPR_ERR_CANT_CREATE; } mprServiceEvents(mprGetDispatcher(mpr), -1, MPR_SERVICE_EVENTS | MPR_SERVICE_IO); maStopHttp(http); mprFree(mpr); return 0; }
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); }
static void testCriticalSection(MprTestGroup *gp) { MprCond *cond; MprEvent *event; int rc; cond = mprCreateCond(gp); assert(cond != 0); mprAssert(cond->triggered == 0); /* * Create an event to signal the condition var in 10 msec */ event = mprCreateEvent(mprGetDispatcher(gp), callback, 0, 0, (void*) cond, 0); assert(event != 0); rc = mprWaitForCondWithService(cond, MPR_TEST_TIMEOUT); assert(rc == 0); mprFree(cond); mprFree(event); }
MAIN(httpMain, int argc, char *argv[]) { MprTime start; double elapsed; /* * Explicit initialization of globals for re-entrancy on Vxworks */ activeLoadThreads = benchmark = continueOnErrors = fetchCount = iterations = isBinary = httpVersion = 0; success = loadThreads = nextArg = noout = nofollow = showHeaders = printable = workers = 0; retries = singleStep = timeout = verbose = 0; chunkSize = host = method = password = ranges = 0; username = 0; mpr = 0; headers = 0; formData = 0; mpr = mprCreate(argc, argv, NULL); initSettings(mpr); if (!parseArgs(mpr, argc, argv)) { showUsage(mpr); return MPR_ERR_BAD_ARGS; } #if BLD_FEATURE_MULTITHREAD mprSetMaxWorkers(mpr, workers); #endif #if BLD_FEATURE_SSL if (!mprLoadSsl(mpr, 1)) { mprError(mpr, "Can't load SSL"); exit(1); } #endif /* * Start the Timer, Socket and Worker services */ if (mprStart(mpr, 0) < 0) { mprError(mpr, "Can't start MPR for %s", mprGetAppTitle(mpr)); exit(2); } start = mprGetTime(mpr); processing(); /* * Wait for all the threads to complete (simple but effective). Keep servicing events as we wind down. */ while (activeLoadThreads > 0) { mprServiceEvents(mprGetDispatcher(mpr), 250, MPR_SERVICE_EVENTS | MPR_SERVICE_IO); } if (benchmark) { elapsed = (double) (mprGetTime(mpr) - start); if (fetchCount == 0) { elapsed = 0; fetchCount = 1; } mprPrintf(mpr, "\nRequest Count: %13d\n", fetchCount); mprPrintf(mpr, "Time elapsed: %13.4f sec\n", elapsed / 1000.0); mprPrintf(mpr, "Time per request: %13.4f sec\n", elapsed / 1000.0 / fetchCount); mprPrintf(mpr, "Requests per second: %13.4f\n", fetchCount * 1.0 / (elapsed / 1000.0)); mprPrintf(mpr, "Load threads: %13d\n", loadThreads); mprPrintf(mpr, "Worker threads: %13d\n", workers); } if (!success && verbose) { mprError(mpr, "Request failed"); } return (success) ? 0 : 255; }
MAIN(benchMain, int argc, char *argv[]) { Mpr *mpr; char *argp; int err, i, nextArg; #if BLD_FEATURE_MULTITHREAD MprThread *tp; #endif mpr = mprCreate(argc, argv, 0); #if VXWORKS || WINCE /* * These platforms pass an arg string in via the argc value. Assumes 32-bit. */ mprMakeArgv(mpr, "http", (char*) argc, &argc, &argv); #endif 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 { iterations = atoi(argv[++nextArg]); } } else if (strcmp(argp, "--workers") == 0 || strcmp(argp, "-w") == 0) { if (nextArg >= argc) { err++; } else { i = atoi(argv[++nextArg]); if (i <= 0 || i > 100) { mprError(mpr, "%s: Bad number of worker threads (0-100)", mprGetAppName(mpr)); exit(2); } workers = i; } } else { err++; } } if (err) { mprPrintf(mpr, "usage: bench [-em] [-i iterations] [-t workers]\n"); mprRawLog(mpr, 0, "usage: %s [options]\n" " --iterations count # Number of iterations to run the test\n" " --workers count # Set maximum worker threads\n", mprGetAppName(mpr)); exit(2); } #if BLD_FEATURE_MULTITHREAD mutex = mprCreateLock(mpr); mprSetMaxWorkers(mpr, workers); #endif mprStart(mpr, 0); #if BLD_FEATURE_MULTITHREAD tp = mprCreateThread(mpr, "bench", (MprThreadProc) doBenchmark, (void*) mpr, MPR_NORMAL_PRIORITY, 0); mprStartThread(tp); while (!testComplete) { mprServiceEvents(mprGetDispatcher(mpr), 250, MPR_SERVICE_EVENTS | MPR_SERVICE_IO); } #else doBenchmark(mpr, NULL); #endif mprPrintf(mpr, "\n\n"); // mprFree(mpr); return 0; }
/* * Do a performance benchmark */ static void doBenchmark(Mpr *mpr, void *thread) { MprTime start; MprList *list; void *mp; int count, i; #if BLD_FEATURE_MULTITHREAD MprMutex *lock; #endif complete = mprCreateCond(mpr); mprPrintf(mpr, "Group\t%-30s\t%13s\t%12s\n", "Benchmark", "Microsec", "Elapsed-sec"); /* * Alloc (1K) */ mprPrintf(mpr, "Alloc Benchmarks\n"); count = 2000000 * iterations; start = startMark(mpr); for (i = 0; i < count; i++) { mp = mprAlloc(mpr, 1024); memset(mp, 0, 1024); mprFree(mp); } endMark(mpr, start, count, "Alloc mprAlloc(1K)|mprFree"); start = startMark(mpr); #if BLD_FEATURE_MULTITHREAD /* * Locking primitives */ mprPrintf(mpr, "Lock Benchmarks\n"); lock = mprCreateLock(mpr); count = 5000000 * iterations; start = startMark(mpr); for (i = 0; i < count; i++) { mprLock(lock); mprUnlock(lock); } endMark(mpr, start, count, "Mutex lock|unlock"); mprFree(lock); /* * Condition signal / wait */ mprPrintf(mpr, "Cond Benchmarks\n"); count = 1000000 * iterations; start = startMark(mpr); mprResetCond(complete); for (i = 0; i < count; i++) { mprSignalCond(complete); mprWaitForCond(complete, -1); } endMark(mpr, start, count, "Cond signal|wait"); #endif /* * List */ mprPrintf(mpr, "List Benchmarks\n"); count = 500000 * iterations; list = mprCreateList(mpr); start = startMark(mpr); for (i = 0; i < count; i++) { mprAddItem(list, (void*) (long) i); mprRemoveItem(list, (void*) (long) i); } endMark(mpr, start, count, "Link insert|remove"); mprFree(list);; /* * Events */ mprPrintf(mpr, "Event Benchmarks\n"); mprResetCond(complete); count = 200000 * iterations; markCount = count; start = startMark(mpr); for (i = 0; i < count; i++) { mprCreateEvent(mprGetDispatcher(mpr), eventCallback, 0, 0, (void*) (long) i, 0); } endMark(mpr, start, count, "Event (create)"); mprWaitForCondWithService(complete, -1); endMark(mpr, start, count, "Event (run|delete)"); /* * Test timer creation, run and delete (make a million timers!) */ mprPrintf(mpr, "Timer\n"); mprResetCond(complete); count = 50000 * iterations; markCount = count; start = startMark(mpr); for (i = 0; i < count; i++) { mprCreateTimerEvent(mprGetDispatcher(mpr), timerCallback, 0, 0, (void*) (long) i, 0); } endMark(mpr, start, count, "Timer (create)"); mprWaitForCondWithService(complete, -1); endMark(mpr, start, count, "Timer (delete)"); testComplete = 1; }
/* * Start the host timer. This may create multiple timers -- no worry. maAddConn does its best to only schedule one. */ static void startTimer(MaHost *host) { host->timer = mprCreateTimerEvent(mprGetDispatcher(host), (MprEventProc) hostTimer, MA_TIMER_PERIOD, MPR_NORMAL_PRIORITY, host, MPR_EVENT_CONTINUOUS); }