Example #1
0
/*
 *  Start the host timer. This may create multiple timers -- no worry. maAddConn does its best to only schedule one.
 */
static void startTimer(MaHost *host)
{
    if (mprGetDebugMode(host)) {
        return;
    }
    mprCreateTimerEvent(host, (MprEventProc) hostTimer, MA_TIMER_PERIOD, MPR_NORMAL_PRIORITY, host, MPR_EVENT_CONTINUOUS);
}
Example #2
0
/*
    This clones a database to give a private view per user.
 */
static int cloneDatabase(HttpConn *conn)
{
    Esp         *esp;
    EspRoute    *eroute;
    EspReq      *req;
    cchar       *id;

    req = conn->reqData;
    eroute = conn->rx->route->eroute;
    assert(eroute->edi);
    assert(eroute->edi->flags & EDI_PRIVATE);

    esp = req->esp;
    if (!esp->databases) {
        lock(esp);
        if (!esp->databases) {
            esp->databases = mprCreateHash(0, 0);
            esp->databasesTimer = mprCreateTimerEvent(NULL, "esp-databases", 60 * 1000, pruneDatabases, esp, 0);
        }
        unlock(esp);
    }
    /*
        If the user is logging in or out, this will create a redundant session here.
     */
    httpGetSession(conn, 1);
    id = httpGetSessionID(conn);
    if ((req->edi = mprLookupKey(esp->databases, id)) == 0) {
        if ((req->edi = ediClone(eroute->edi)) == 0) {
            mprLog("error esp", 0, "Cannot clone database: %s", eroute->edi->path);
            return MPR_ERR_CANT_OPEN;
        }
        mprAddKey(esp->databases, id, req->edi);
    }
    return 0;
}
Example #3
0
PUBLIC void httpSetTimestamp(MprTicks period)
{
    Http    *http;

    http = HTTP;
    if (period < (10 * TPS)) {
        period = (10 * TPS);
    }
    if (http->timestamp) {
        mprRemoveEvent(http->timestamp);
    }
    if (period > 0) {
        http->timestamp = mprCreateTimerEvent(NULL, "httpTimestamp", period, timestamp, NULL, 
            MPR_EVENT_CONTINUOUS | MPR_EVENT_QUICK);
    }
}
Example #4
0
PUBLIC void httpAddConn(HttpConn *conn)
{
    Http    *http;

    http = HTTP;
    http->now = mprGetTicks();
    assert(http->now >= 0);
    conn->started = http->now;
    mprAddItem(http->connections, conn);
    updateCurrentDate();

    lock(http);
    conn->seqno = (int) ++http->totalConnections;
    if (!http->timer) {
#if ME_DEBUG
        if (!mprGetDebugMode())
#endif
        {
            http->timer = mprCreateTimerEvent(NULL, "httpTimer", HTTP_TIMER_PERIOD, httpTimer, http, 
                MPR_EVENT_CONTINUOUS | MPR_EVENT_QUICK);
        }
    }
    unlock(http);
}
Example #5
0
File: cmd.c Project: embedthis/mpr
/*
    Start the command to run (stdIn and stdOut are named from the client's perspective). This is the lower-level way to
    run a command. The caller needs to do code like mprRunCmd() themselves to wait for completion and to send/receive data.
    The routine does not wait. Callers must call mprWaitForCmd to wait for the command to complete.
 */
PUBLIC int mprStartCmd(MprCmd *cmd, int argc, cchar **argv, cchar **envp, int flags)
{
    MprPath     info;
    cchar       *pair;
    int         rc, next, i;

    assert(cmd);
    assert(argv);

    if (argc <= 0 || argv == NULL || argv[0] == NULL) {
        return MPR_ERR_BAD_ARGS;
    }
    resetCmd(cmd, 0);

    cmd->flags = flags;
    cmd->argc = argc;
    cmd->argv = mprAlloc((argc + 1) * sizeof(char*));
    for (i = 0; i < argc; i++) {
        cmd->argv[i] = sclone(argv[i]);
    }
    cmd->argv[i] = 0;

    prepWinProgram(cmd);

    if ((cmd->program = mprSearchPath(cmd->argv[0], MPR_SEARCH_EXE, cmd->searchPath, NULL)) == 0) {
        mprLog("error mpr cmd", 0, "Cannot access %s, errno %d", cmd->argv[0], mprGetOsError());
        return MPR_ERR_CANT_ACCESS;
    }
    if (mprGetPathInfo(cmd->program, &info) == 0 && info.isDir) {
        mprLog("error mpr cmd", 0, "Program \"%s\", is a directory", cmd->program);
        return MPR_ERR_CANT_ACCESS;
    }
    mprLog("info mpr cmd", 6, "Program: %s", cmd->program);
    cmd->argv[0] = cmd->program;

    prepWinCommand(cmd);

    if (envp == 0) {
        envp = cmd->defaultEnv;
    }
    if (blendEnv(cmd, envp, flags) < 0) {
        return MPR_ERR_MEMORY;
    }
    for (i = 0; i < cmd->argc; i++) {
        mprLog("info mpr cmd", 6, "    arg[%d]: %s", i, cmd->argv[i]);
    }
    for (ITERATE_ITEMS(cmd->env, pair, next)) {
        mprLog("info mpr cmd", 6, "    env[%d]: %s", next, pair);
    }
    slock(cmd);
    if (makeCmdIO(cmd) < 0) {
        sunlock(cmd);
        return MPR_ERR_CANT_OPEN;
    }
    /*
        Determine how many end-of-files will be seen when the child dies
     */
    cmd->requiredEof = 0;
    if (cmd->flags & MPR_CMD_OUT) {
        cmd->requiredEof++;
    }
    if (cmd->flags & MPR_CMD_ERR) {
        cmd->requiredEof++;
    }
    if (addCmdHandlers(cmd) < 0) {
        mprLog("error mpr cmd", 0, "Cannot open command handlers - insufficient I/O handles");
        return MPR_ERR_CANT_OPEN;
    }
    rc = startProcess(cmd);

    cmd->originalPid = cmd->pid;
    mprAddItem(MPR->cmdService->cmds, cmd);
    sunlock(cmd);
#if ME_WIN_LIKE
    if (!rc) {
        mprCreateTimerEvent(cmd->dispatcher, "pollWinTimer", 10, pollWinTimer, cmd, 0);
    }
#endif
    return rc;
}
Example #6
0
/*
    Do a performance benchmark
 */ 
static void doBenchmark(void *thread)
{
    MprTime         start;
    MprList         *list;
    int             count, i;
    MprMutex        *lock;
    MprSpin         *spin;

    mprPrintf("Group\t%-30s\t%13s\t%12s\n", "Benchmark", "Microsec", "Elapsed-sec");

    testMalloc();

    if (!app->testAllocOnly) {
        /*
            Locking primitives
         */
        mprPrintf("Lock Benchmarks\n");
        lock = mprCreateLock();
        count = 5000000 * app->iterations;
        start = startMark();
        for (i = 0; i < count; i++) {
            mprLock(lock);
            mprUnlock(lock);
        }
        endMark(start, count, "Mutex lock|unlock");
        
        /*
            Locking primitives
         */
        mprPrintf("Lock Benchmarks\n");
        spin = mprCreateSpinLock();
        count = 5000000 * app->iterations;
        start = startMark();
        for (i = 0; i < count; i++) {
            mprSpinLock(spin);
            mprSpinUnlock(spin);
        }
        endMark(start, count, "Spin lock|unlock");
        
        /*
            Condition signal / wait
         */
        mprPrintf("Cond Benchmarks\n");
        count = 1000000 * app->iterations;
        start = startMark();
        mprResetCond(app->complete);
        for (i = 0; i < count; i++) {
            mprSignalCond(app->complete);
            mprWaitForCond(app->complete, -1);
        }
        endMark(start, count, "Cond signal|wait");
        
        /*
            List
         */
        mprPrintf("List Benchmarks\n");
        count = 2000000 * app->iterations;
        list = mprCreateList(count, 0);
        start = startMark();
        for (i = 0; i < count; i++) {
            mprAddItem(list, (void*) (long) i);
            mprRemoveItem(list, (void*) (long) i);
        }
        endMark(start, count, "Link insert|remove");

        /*
            Events
         */
        mprPrintf("Event Benchmarks\n");
        mprResetCond(app->complete);
        count = 30000 * app->iterations;
        app->markCount = count;
        start = startMark();
        for (i = 0; i < count; i++) {
            mprCreateEvent(NULL, "eventBenchmark", 0, eventCallback, ITOP(i), MPR_EVENT_QUICK);
        }
        mprWaitForCond(app->complete, -1);
        endMark(start, count, "Event (create|run|delete)");

        /*
            Test timer creation, run and remove
            These create a new dispatcher and run a worker thread.
         */
        mprPrintf("Timer\n");
        mprResetCond(app->complete);
        count = 20000 * app->iterations;
        app->markCount = count;
        start = startMark();
        for (i = 0; i < count; i++) {
            mprCreateTimerEvent(NULL, "timerBenchmark", 0, timerCallback, (void*) (long) i, 0);
        }
        mprWaitForCond(app->complete, -1);
        endMark(start, count, "Timer (create|delete)");

        /*
            Alloc (1K)
         */
        mprPrintf("Alloc 1K Benchmarks\n");
        count = 2000000 * app->iterations;
        start = startMark();
        for (i = 0; i < count; i++) {
            mprAlloc(1024);
            if ((i % 128) == 0) {
                mprGC(0);
            }
        }
        endMark(start, count, "Alloc mprAlloc(1K)");
    }
    testComplete = 1;
}
Example #7
0
ssize mprWriteCache(MprCache *cache, cchar *key, cchar *value, MprTime modified, MprTime lifespan, 
    int64 version, int options)
{
    CacheItem   *item;
    MprKey      *kp;
    ssize       len, oldLen;
    int         exists, add, set, prepend, append, throw;

    mprAssert(cache);
    mprAssert(key && *key);
    mprAssert(value);

    if (cache->shared) {
        cache = cache->shared;
        mprAssert(cache == shared);
    }
    exists = add = prepend = append = throw = 0;
    add = options & MPR_CACHE_ADD;
    append = options & MPR_CACHE_APPEND;
    prepend = options & MPR_CACHE_PREPEND;
    set = options & MPR_CACHE_SET;
    if ((add + append + prepend) == 0) {
        set = 1;
    }
    lock(cache);
    if ((kp = mprLookupKeyEntry(cache->store, key)) != 0) {
        exists++;
        item = (CacheItem*) kp->data;
        if (version) {
            if (item->version != version) {
                unlock(cache);
                return MPR_ERR_BAD_STATE;
            }
        }
    } else {
        if ((item = mprAllocObj(CacheItem, manageCacheItem)) == 0) {
            unlock(cache);
            return 0;
        }
        mprAddKey(cache->store, key, item);
        item->key = sclone(key);
        set = 1;
    }
    oldLen = (item->data) ? (slen(item->key) + slen(item->data)) : 0;
    if (set) {
        item->data = sclone(value);
    } else if (add) {
        if (exists) {
            return 0;
        }
        item->data = sclone(value);
    } else if (append) {
        item->data = sjoin(item->data, value, NULL);
    } else if (prepend) {
        item->data = sjoin(value, item->data, NULL);
    }
    if (lifespan >= 0) {
        item->lifespan = lifespan;
    }
    item->lastAccessed = mprGetTime();
    item->lastAccessed = item->lastModified = modified ? modified : item->lastAccessed;
    item->expires = item->lastAccessed + item->lifespan;
    item->version++;
    len = slen(item->key) + slen(item->data);
    cache->usedMem += (len - oldLen);

    if (cache->timer == 0) {
        mprLog(5, "Start Cache pruner with resolution %d", cache->resolution);
        /* 
            Use the MPR dispatcher incase this VM is destroyed 
         */
        cache->timer = mprCreateTimerEvent(MPR->dispatcher, "localCacheTimer", cache->resolution, pruneCache, cache, 
            MPR_EVENT_STATIC_DATA); 
    }
    unlock(cache);
    return len;
}
Example #8
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;
}
Example #9
0
/*
 *  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);
}