Exemplo n.º 1
0
/*
    Wait for I/O on all registered descriptors. Timeout is in milliseconds. Return the number of events serviced.
    Should only be called by the thread that calls mprServiceEvents
 */
PUBLIC void mprWaitForIO(MprWaitService *ws, MprTicks timeout)
{
    MSG     msg;

    assert(ws->hwnd);

    if (timeout < 0 || timeout > MAXINT) {
        timeout = MAXINT;
    }
#if BIT_DEBUG
    if (mprGetDebugMode() && timeout > 30000) {
        timeout = 30000;
    }
#endif
    if (ws->needRecall) {
        mprDoWaitRecall(ws);
        return;
    }
    SetTimer(ws->hwnd, 0, (UINT) timeout, NULL);

    mprYield(MPR_YIELD_STICKY);
    if (GetMessage(&msg, NULL, 0, 0) == 0) {
        mprResetYield();
        mprTerminate(MPR_EXIT_DEFAULT, -1);
    } else {
        mprClearWaiting();
        mprResetYield();
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    ws->wakeRequested = 0;
}
Exemplo n.º 2
0
/*
    Wait for I/O on all registered file descriptors. Timeout is in milliseconds. Return the number of events detected.
 */
PUBLIC void mprWaitForIO(MprWaitService *ws, MprTicks timeout)
{
    struct epoll_event  events[ME_MAX_EVENTS];
    int                 nevents;

    if (timeout < 0 || timeout > MAXINT) {
        timeout = MAXINT;
    }
#if ME_DEBUG
    if (mprGetDebugMode() && timeout > 30000) {
        timeout = 30000;
    }
#endif
    if (ws->needRecall) {
        mprDoWaitRecall(ws);
        return;
    }
    mprYield(MPR_YIELD_STICKY);

    if ((nevents = epoll_wait(ws->epoll, events, sizeof(events) / sizeof(struct epoll_event), timeout)) < 0) {
        if (errno != EINTR) {
            mprLog("error mpr event", 0, "epoll returned %d, errno %d", nevents, mprGetOsError());
        }
    }
    mprClearWaiting();
    mprResetYield();

    if (nevents > 0) {
        serviceIO(ws, events, nevents);
    }
    ws->wakeRequested = 0;
}
Exemplo n.º 3
0
Arquivo: cmd.c Projeto: embedthis/mpr
/*
    Windows only routine to wait for I/O on the channels to the gateway and the child process.
    This will queue events on the dispatcher queue when I/O occurs or the process dies.
    NOTE: NamedPipes cannot use WaitForMultipleEvents, so we dedicate a thread to polling.
    WARNING: this should not be called from a dispatcher other than cmd->dispatcher.
 */
static void pollWinCmd(MprCmd *cmd, MprTicks timeout)
{
    MprTicks        mark, delay;
    MprWaitHandler  *wp;
    int             i, rc, nbytes;

    mark = mprGetTicks();
    if (cmd->stopped) {
        timeout = 0;
    }
    slock(cmd);
    for (i = MPR_CMD_STDOUT; i < MPR_CMD_MAX_PIPE; i++) {
        if (cmd->files[i].handle) {
            wp = cmd->handlers[i];
            if (wp && wp->desiredMask & MPR_READABLE) {
                rc = PeekNamedPipe(cmd->files[i].handle, NULL, 0, NULL, &nbytes, NULL);
                if (rc && nbytes > 0 || cmd->process == 0) {
                    wp->presentMask |= MPR_READABLE;
                    mprQueueIOEvent(wp);
                }
            }
        }
    }
    if (cmd->files[MPR_CMD_STDIN].handle) {
        wp = cmd->handlers[MPR_CMD_STDIN];
        if (wp && wp->desiredMask & MPR_WRITABLE) {
            wp->presentMask |= MPR_WRITABLE;
            mprQueueIOEvent(wp);
        }
    }
    if (cmd->process) {
        delay = (cmd->eofCount == cmd->requiredEof && cmd->files[MPR_CMD_STDIN].handle == 0) ? timeout : 0;
        do {
            mprYield(MPR_YIELD_STICKY);
            if (WaitForSingleObject(cmd->process, (DWORD) delay) == WAIT_OBJECT_0) {
                mprResetYield();
                reapCmd(cmd, 0);
                break;
            } else {
                mprResetYield();
            }
            delay = mprGetRemainingTicks(mark, timeout);
        } while (cmd->eofCount == cmd->requiredEof);
    }
    sunlock(cmd);
}
Exemplo n.º 4
0
/*
    Wait for an event to occur on the dispatcher and service the event. This is not called by mprServiceEvents.
    The dispatcher may be "started" and owned by the thread, or it may be unowned.
    WARNING: the event may have already happened by the time this API is invoked.
    WARNING: this will enable GC while sleeping.
 */
PUBLIC int mprWaitForEvent(MprDispatcher *dispatcher, MprTicks timeout, int64 mark)
{
    MprEventService     *es;
    MprTicks            expires, delay;
    int                 runEvents, changed;

    if (dispatcher == NULL) {
        dispatcher = MPR->dispatcher;
    }
    if (dispatcher->flags & MPR_DISPATCHER_DESTROYED) {
        return 0;
    }
    if ((runEvents = (dispatcher->owner == mprGetCurrentOsThread())) != 0) {
        /* Called from an event on a running dispatcher */
        assert(isRunning(dispatcher) || (dispatcher->flags & MPR_DISPATCHER_DESTROYED));
        if (dispatchEvents(dispatcher)) {
            return 0;
        }
    }
    es = MPR->eventService;
    es->now = mprGetTicks();
    expires = timeout < 0 ? MPR_MAX_TIMEOUT : (es->now + timeout);
    if (expires < 0) {
        expires = MPR_MAX_TIMEOUT;
    }
    delay = expires - es->now;

    lock(es);
    delay = getDispatcherIdleTicks(dispatcher, delay);
    dispatcher->flags |= MPR_DISPATCHER_WAITING;
    changed = dispatcher->mark != mark && mark != -1;
    unlock(es);

    if (changed) {
        return 0;
    }
    mprYield(MPR_YIELD_STICKY);
    mprWaitForCond(dispatcher->cond, delay);
    mprResetYield();
    es->now = mprGetTicks();

    lock(es);
    dispatcher->flags &= ~MPR_DISPATCHER_WAITING;
    unlock(es);

    if (runEvents) {
        dispatchEvents(dispatcher);
        assert(isRunning(dispatcher) || (dispatcher->flags & MPR_DISPATCHER_DESTROYED));
    }
    return 0;
}
Exemplo n.º 5
0
/*
    Wait for I/O on a single file descriptor. Return a mask of events found. Mask is the events of interest.
    timeout is in milliseconds.
 */
PUBLIC int mprWaitForSingleIO(int fd, int mask, MprTicks timeout)
{
    struct epoll_event  ev, events[2];
    int                 epfd, rc, result;

    if (timeout < 0 || timeout > MAXINT) {
        timeout = MAXINT;
    }
    memset(&ev, 0, sizeof(ev));
    memset(events, 0, sizeof(events));
    ev.data.fd = fd;
    if ((epfd = epoll_create(ME_MAX_EVENTS)) < 0) {
        mprLog("error mpr event", 0, "Epoll_create failed, errno=%d", errno);
        return MPR_ERR_CANT_INITIALIZE;
    }
    ev.events = 0;
    if (mask & MPR_READABLE) {
        ev.events = EPOLLIN | EPOLLHUP;
    }
    if (mask & MPR_WRITABLE) {
        ev.events = EPOLLOUT | EPOLLHUP;
    }
    if (ev.events) {
        epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
    }
    mprYield(MPR_YIELD_STICKY);
    rc = epoll_wait(epfd, events, sizeof(events) / sizeof(struct epoll_event), timeout);
    mprResetYield();
    close(epfd);

    result = 0;
    if (rc < 0) {
        mprLog("error mpr event", 0, "Epoll returned %d, errno %d", rc, errno);

    } else if (rc > 0) {
        if (rc > 0) {
            if ((events[0].events & (EPOLLIN | EPOLLERR | EPOLLHUP)) && (mask & MPR_READABLE)) {
                result |= MPR_READABLE;
            }
            if ((events[0].events & (EPOLLOUT | EPOLLHUP)) && (mask & MPR_WRITABLE)) {
                result |= MPR_WRITABLE;
            }
        }
    }
    return result;
}
Exemplo n.º 6
0
/*  
    Read input from the console (stdin)
 */
static int consoleGets(EcStream *stream)
{
    char    prompt[MPR_MAX_STRING], *line, *cp;
    int     level;

    if (stream->flags & EC_STREAM_EOL) {
        return 0;
    }
    level = stream->compiler->state ? stream->compiler->state->blockNestCount : 0;
    fmt(prompt, sizeof(prompt), "%s-%d> ", EJS_NAME, level);

    mprYield(MPR_YIELD_STICKY);
    line = readline(prompt);
    mprResetYield();
    if (line == NULL) {
        stream->eof = 1;
        mprPrintf("\n");
        return -1;
    }
    cp = strim(line, "\r\n", MPR_TRIM_BOTH);
    ecSetStreamBuf(stream, cp, slen(cp));
    stream->flags |= EC_STREAM_EOL;
    return (int) slen(cp);
}
Exemplo n.º 7
0
PUBLIC void mprSleep(MprTicks timeout)
{
    mprYield(MPR_YIELD_STICKY);
    mprNap(timeout);
    mprResetYield();
}