Exemple #1
0
static int join(Ejs *ejs, EjsObj *workers, int timeout)
{
    MprTicks    mark;
    int         result, remaining;

    mprTrace(5, "Worker.join: joining %d", ejs->joining);
    
    mark = mprGetTicks();
    remaining = timeout;
    do {
        ejs->joining = !reapJoins(ejs, workers);
        if (!ejs->joining) {
            break;
        }
        if (mprShouldAbortRequests()) {
            ejsThrowStateError(ejs, "Program instructed to exit");
            break;
        }
        mprWaitForEvent(ejs->dispatcher, remaining);
        remaining = (int) mprGetRemainingTicks(mark, timeout);
    } while (remaining > 0 && !ejs->exception);

    if (ejs->exception) {
        return 0;
    }
    result = (ejs->joining) ? MPR_ERR_TIMEOUT: 0;
    ejs->joining = 0;
    mprTrace(7, "Worker.join: result %d", result);
    return result;
}
Exemple #2
0
/*  
    static function run(timeout: Number = -1, oneEvent: Boolean = false): Boolean
 */
static EjsObj *app_run(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    MprTicks    mark, remaining;
    int64       dispatcherMark;
    int         rc, oneEvent, timeout;

    timeout = (argc > 0) ? ejsGetInt(ejs, argv[0]) : MAXINT;
    oneEvent = (argc > 1) ? ejsGetInt(ejs, argv[1]) : 0;

    if (ejs->hosted) {
        return ESV(true);
    }
    if (timeout < 0) {
        timeout = MAXINT;
    }
    mark = mprGetTicks();
    remaining = timeout;
    dispatcherMark = mprGetEventMark(ejs->dispatcher);
    do {
        rc = mprWaitForEvent(ejs->dispatcher, remaining, dispatcherMark); 
        remaining = mprGetRemainingTicks(mark, timeout);
        dispatcherMark = mprGetEventMark(ejs->dispatcher);
    } while (!ejs->exception && !oneEvent && !ejs->exiting && remaining > 0 && !mprIsStopping());
    return (rc == 0) ? ESV(true) : ESV(false);
}
Exemple #3
0
/*
    function waitForMessage(timeout: Number = -1): Boolean
 */
static EjsBoolean *workerWaitForMessage(Ejs *ejs, EjsWorker *worker, int argc, EjsObj **argv)
{
    MprTicks    mark, remaining;
    int         timeout;

    timeout = (argc > 0) ? ejsGetInt(ejs, argv[0]): MAXINT;
    if (timeout < 0) {
        timeout = MAXINT;
    }
    mark = mprGetTicks();
    remaining = timeout;

    worker->gotMessage = 0;
    do {
        mprWaitForEvent(ejs->dispatcher, (int) remaining);
        remaining = mprGetRemainingTicks(mark, timeout);
    } while (!worker->gotMessage && remaining > 0 && !ejs->exception);

    if (worker->gotMessage) {
        worker->gotMessage = 0;
        return ESV(true);
    } else {
        return ESV(true);
    }
}
Exemple #4
0
/*  
    function run(): Void
 */
static EjsVoid *hs_run(Ejs *ejs, EjsHttpServer *sp, int argc, EjsObj **argv)
{
    if (!sp->hosted) {
        while (!ejs->exiting && !mprIsStopping()) {
            mprWaitForEvent(ejs->dispatcher, MAXINT); 
        }
    }
    return 0;
}
Exemple #5
0
/*
    function run(): Void
 */
static EjsVoid *hs_run(Ejs *ejs, EjsHttpServer *sp, int argc, EjsObj **argv)
{
    int64   dispatcherMark;

    if (!sp->hosted) {
        dispatcherMark = mprGetEventMark(ejs->dispatcher);
        while (!ejs->exiting && !mprIsStopping()) {
            mprWaitForEvent(ejs->dispatcher, MPR_MAX_TIMEOUT, dispatcherMark);
            dispatcherMark = mprGetEventMark(ejs->dispatcher);
        }
    }
    return 0;
}
Exemple #6
0
/*  
    Pause the application. This services events while asleep.
    static function sleep(delay: Number = -1): void
    MOB - sleep currently throws if an exception is generated in an event callback (worker).
    It should not.
 */
static EjsObj *app_sleep(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    MprTicks    mark, remaining;
    int         timeout;

    timeout = (argc > 0) ? ejsGetInt(ejs, argv[0]) : MAXINT;
    if (timeout < 0) {
        timeout = MAXINT;
    }
    mark = mprGetTicks();
    remaining = timeout;
    do {
        mprWaitForEvent(ejs->dispatcher, (int) remaining); 
        remaining = mprGetRemainingTicks(mark, timeout);
    } while (!ejs->exiting && remaining > 0 && !mprIsStopping());
    return 0;
}
Exemple #7
0
/*
    Wait for an event to complete signified by the 'completion' flag being set.
    This will wait for events on the dispatcher.
    The completion flag will be reset on return.
 */
PUBLIC bool mprWaitForCompletion(MprDispatcher *dispatcher, MprTicks timeout)
{
    MprTicks    mark;
    bool        success;

    assert(timeout >= 0);

    if (dispatcher == 0) {
        dispatcher = MPR->dispatcher;
    }
    if (mprGetDebugMode()) {
        timeout *= 100;
    }
    for (mark = mprGetTicks(); !(dispatcher->flags & MPR_DISPATCHER_COMPLETE) && mprGetElapsedTicks(mark) < timeout; ) {
        mprWaitForEvent(dispatcher, 10, -1);
    }
    success = (dispatcher->flags & MPR_DISPATCHER_COMPLETE) ? 1 : 0;
    dispatcher->flags &= ~MPR_DISPATCHER_COMPLETE;
    return success;
}
Exemple #8
0
/*
    Wait for a command to complete. Return 0 if the command completed, otherwise it will return MPR_ERR_TIMEOUT.
 */
PUBLIC int mprWaitForCmd(MprCmd *cmd, MprTicks timeout)
{
    MprTicks    expires, remaining, delay;
    int64       dispatcherMark;

    assert(cmd);
    if (timeout < 0) {
        timeout = MAXINT;
    }
    if (mprGetDebugMode()) {
        timeout = MAXINT;
    }
    if (cmd->stopped) {
        timeout = 0;
    }
    expires = mprGetTicks() + timeout;
    remaining = timeout;

    /* Add root to allow callers to use mprRunCmd without first managing the cmd */
    mprAddRoot(cmd);
    dispatcherMark = mprGetEventMark(cmd->dispatcher);

    while (!cmd->complete && remaining > 0) {
        if (mprShouldAbortRequests()) {
            break;
        }
        delay = (cmd->eofCount >= cmd->requiredEof) ? 10 : remaining;
        if (!MPR->eventing) {
            mprServiceEvents(delay, MPR_SERVICE_NO_BLOCK);
            delay = 0;
        }
        mprWaitForEvent(cmd->dispatcher, delay, dispatcherMark);
        remaining = (expires - mprGetTicks());
        dispatcherMark = mprGetEventMark(cmd->dispatcher);
    }
    mprRemoveRoot(cmd);
    if (cmd->pid) {
        return MPR_ERR_TIMEOUT;
    }
    return 0;
}
Exemple #9
0
/*
    Wait for the connection to reach a given state.
    Should only be used on the client side.
    @param state Desired state. Set to zero if you want to wait for one I/O event.
    @param timeout Timeout in msec. If timeout is zero, wait forever. If timeout is < 0, use default inactivity
        and duration timeouts.
 */
PUBLIC int httpWait(HttpConn *conn, int state, MprTicks timeout)
{
    HttpLimits  *limits;
    MprTicks    delay, start;
    int64       dispatcherMark;
    int         justOne;

    limits = conn->limits;
    if (conn->endpoint) {
        assert(!conn->endpoint);
        return MPR_ERR_BAD_STATE;
    }
    if (conn->state <= HTTP_STATE_BEGIN) {
        return MPR_ERR_BAD_STATE;
    }
    if (state == 0) {
        /* Wait for just one I/O event */
        state = HTTP_STATE_FINALIZED;
        justOne = 1;
    } else {
        justOne = 0;
    }
    if (conn->error) {
        if (conn->state >= state) {
            return 0;
        }
        return MPR_ERR_BAD_STATE;
    }
    if (timeout < 0) {
        timeout = limits->requestTimeout;
    } else if (timeout == 0) {
        timeout = MPR_MAX_TIMEOUT;
    }
    if (state > HTTP_STATE_CONTENT) {
        httpFinalizeOutput(conn);
    }
    start = conn->http->now;
    dispatcherMark = mprGetEventMark(conn->dispatcher);
    while (conn->state < state && !conn->error && !mprIsSocketEof(conn->sock)) {
        if (httpRequestExpired(conn, -1)) {
            return MPR_ERR_TIMEOUT;
        }
        httpEnableConnEvents(conn);
        delay = min(limits->inactivityTimeout, mprGetRemainingTicks(start, timeout));
        delay = max(delay, 0);
        mprWaitForEvent(conn->dispatcher, delay, dispatcherMark);
        if (justOne || (mprGetRemainingTicks(start, timeout) <= 0)) {
            break;
        }
        dispatcherMark = mprGetEventMark(conn->dispatcher);
    }
    if (conn->error) {
        return MPR_ERR_NOT_READY;
    }
    if (conn->state < state) {
        if (mprGetRemainingTicks(start, timeout) <= 0) {
            return MPR_ERR_TIMEOUT;
        }
        if (!justOne) {
            return MPR_ERR_CANT_READ;
        }
    }
    conn->lastActivity = conn->http->now;
    return 0;
}
Exemple #10
0
/*
    Read data. If sync mode, this will block. If async, will never block.
    Will return what data is available up to the requested size.
    Timeout in milliseconds to wait. Set to -1 to use the default inactivity timeout. Set to zero to wait forever.
    Returns a count of bytes read. Returns zero if no data. EOF if returns zero and conn->state is > HTTP_STATE_CONTENT.
 */
PUBLIC ssize httpReadBlock(HttpConn *conn, char *buf, ssize size, MprTicks timeout, int flags)
{
    HttpPacket  *packet;
    HttpQueue   *q;
    HttpLimits  *limits;
    MprBuf      *content;
    MprTicks    start, delay;
    ssize       nbytes, len;
    int64       dispatcherMark;

    q = conn->readq;
    assert(q->count >= 0);
    assert(size >= 0);
    limits = conn->limits;

    if (flags == 0) {
        flags = conn->async ? HTTP_NON_BLOCK : HTTP_BLOCK;
    }
    if (timeout < 0) {
        timeout = limits->inactivityTimeout;
    } else if (timeout == 0) {
        timeout = MPR_MAX_TIMEOUT;
    }
    if (flags & HTTP_BLOCK) {
        start = conn->http->now;
        dispatcherMark = mprGetEventMark(conn->dispatcher);
        while (q->count <= 0 && !conn->error && (conn->state <= HTTP_STATE_CONTENT)) {
            if (httpRequestExpired(conn, -1)) {
                break;
            }
            delay = min(limits->inactivityTimeout, mprGetRemainingTicks(start, timeout));
            httpEnableConnEvents(conn);
            mprWaitForEvent(conn->dispatcher, delay, dispatcherMark);
            if (mprGetRemainingTicks(start, timeout) <= 0) {
                break;
            }
            dispatcherMark = mprGetEventMark(conn->dispatcher);
        }
    }
    for (nbytes = 0; size > 0 && q->count > 0; ) {
        if ((packet = q->first) == 0) {
            break;
        }
        content = packet->content;
        len = mprGetBufLength(content);
        len = min(len, size);
        assert(len <= q->count);
        if (len > 0) {
            len = mprGetBlockFromBuf(content, buf, len);
            assert(len <= q->count);
        }
        buf += len;
        size -= len;
        q->count -= len;
        assert(q->count >= 0);
        nbytes += len;
        if (mprGetBufLength(content) == 0) {
            httpGetPacket(q);
        }
        if (flags & HTTP_NON_BLOCK) {
            break;
        }
    }
    assert(q->count >= 0);
    if (nbytes < size) {
        buf[nbytes] = '\0';
    }
    return nbytes;
}
Exemple #11
0
/*
    Wait for the connection to reach a given state.
    Should only be used on the client side.
    @param state Desired state. Set to zero if you want to wait for one I/O event.
    @param timeout Timeout in msec. If timeout is zero, wait forever. If timeout is < 0, use default inactivity
        and duration timeouts.
 */
PUBLIC int httpWait(HttpStream *stream, int state, MprTicks timeout)
{
    HttpLimits  *limits;
    MprTicks    delay, start;
    int64       dispatcherMark;
    int         justOne;

    limits = stream->limits;
    if (httpServerStream(stream)) {
        return MPR_ERR_BAD_STATE;
    }
    if (stream->state <= HTTP_STATE_BEGIN) {
        return MPR_ERR_BAD_STATE;
    }
    if (state == 0) {
        /* Wait for just one I/O event */
        state = HTTP_STATE_FINALIZED;
        justOne = 1;
    } else {
        justOne = 0;
    }
    if (stream->error) {
        if (stream->state >= state) {
            return 0;
        }
        return MPR_ERR_BAD_STATE;
    }
    if (timeout < 0) {
        timeout = limits->requestTimeout;
    } else if (timeout == 0) {
        timeout = MPR_MAX_TIMEOUT;
    }
    if (state > HTTP_STATE_CONTENT) {
        httpFinalizeOutput(stream);
    }
    start = stream->http->now;
    dispatcherMark = mprGetEventMark(stream->dispatcher);

    //  TODO - how does this work with http2?
    while (stream->state < state && !stream->error && !mprIsSocketEof(stream->sock)) {
        if (httpRequestExpired(stream, -1)) {
            return MPR_ERR_TIMEOUT;
        }
        //  TODO - review
        httpEnableNetEvents(stream->net);
        delay = min(limits->inactivityTimeout, mprGetRemainingTicks(start, timeout));
        delay = max(delay, 0);
        mprWaitForEvent(stream->dispatcher, delay, dispatcherMark);
        if (justOne || (mprGetRemainingTicks(start, timeout) <= 0)) {
            break;
        }
        dispatcherMark = mprGetEventMark(stream->dispatcher);
    }
    if (stream->error) {
        return MPR_ERR_NOT_READY;
    }
    if (stream->state < state) {
        if (mprGetRemainingTicks(start, timeout) <= 0) {
            return MPR_ERR_TIMEOUT;
        }
        if (!justOne) {
            return MPR_ERR_CANT_READ;
        }
    }
    stream->lastActivity = stream->http->now;
    return 0;
}