Пример #1
0
/*
 *  function preload(path: Path): String
 *  NOTE: this blocks. 
 */
static EjsVar *workerPreload(Ejs *ejs, EjsWorker *worker, int argc, EjsVar **argv)
{
    Ejs         *inside;
    EjsWorker   *insideWorker;
    EjsVar      *result;

    mprAssert(argc > 0 && ejsIsPath(argv[0]));
    mprAssert(!worker->inside);

    if (worker->state > EJS_WORKER_BEGIN) {
        ejsThrowStateError(ejs, "Worker has already started");
        return 0;
    }
    insideWorker = worker->pair;
    inside = insideWorker->ejs;

    loadFile(worker->pair, ((EjsPath*) argv[0])->path);
    if (inside->exception) {
        handleError(ejs, worker, inside->exception);
        return 0;
    }
    result = ejsSerialize(ejs, inside->result, -1, 0, 0);
    if (result == 0) {
        return ejs->nullValue;
    }
    return ejsDeserialize(ejs, (EjsString*) result);
}
Пример #2
0
/*
 *  Post a message to this worker. Note: the worker is the destination worker which may be the parent.
 *
 *  function postMessage(data: Object, ports: Array = null): Void
 */
static EjsVar *workerPostMessage(Ejs *ejs, EjsWorker *worker, int argc, EjsVar **argv)
{
    EjsVar          *data;
    EjsWorker       *target;
    MprDispatcher   *dispatcher;
    Message         *msg;

    if (worker->state >= EJS_WORKER_CLOSED) {
        ejsThrowStateError(ejs, "Worker has completed");
        return 0;
    }

    /*
     *  Create the event with serialized data in the originating interpreter. It owns the data.
     */
    if ((data = ejsSerialize(ejs, argv[0], -1, 0, 0)) == 0) {
        ejsThrowArgError(ejs, "Can't serialize message data");
        return 0;
    }
    if ((msg = mprAllocObjZeroed(ejs, Message)) == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    target = worker->pair;
    msg->data = mprStrdup(target->ejs, ejsGetString(data));
    msg->worker = target;
    msg->callback = "onmessage";
    msg->callbackSlot = ES_ejs_sys_Worker_onmessage;

    dispatcher = target->ejs->dispatcher;
    mprCreateEvent(dispatcher, (MprEventProc) doMessage, 0, MPR_NORMAL_PRIORITY, msg, 0);
    mprSignalCond(dispatcher->cond);
    return 0;
}
Пример #3
0
/*  
    Interpret from the console or from a literal command
 */
static int interpretCommands(EcCompiler *cp, cchar *cmd)
{
    Ejs         *ejs;
    EjsString   *result;
    char        *tmpArgv[1];
    int         err;

    ejs = cp->ejs;
    cp->interactive = 1;

    if (ecOpenConsoleStream(cp, (cmd) ? commandGets: consoleGets, cmd) < 0) {
        mprError("Cannot open input");
        return EJS_ERR;
    }
    tmpArgv[0] = EC_INPUT_STREAM;

    while (!cp->stream->eof && !mprIsStopping()) {
        err = 0;
        cp->uid = 0;
        ejs->result = ESV(undefined);
        if (ecCompile(cp, 1, tmpArgv) < 0) {
            mprRawLog(0, "%s", cp->errorMsg);
            ejs->result = ESV(undefined);
            err++;
        }
        if (!err && cp->errorCount == 0) {
            if (ejsRunProgram(ejs, NULL, NULL) < 0) {
                ejsReportError(ejs, "Error in script");
            }
        }
        if (!ejs->exception && ejs->result != ESV(undefined)) {
            if (ejsIs(ejs, ejs->result, Date) /* MOB || ejsIsType(ejs, ejs->result) */) {
                if ((result = (EjsString*) ejsToString(ejs, ejs->result)) != 0) {
                    mprPrintf("%@\n", result);
                }
            } else if (ejs->result != ESV(null)) {
                if ((result = (EjsString*) ejsSerialize(ejs, ejs->result, EJS_JSON_SHOW_PRETTY)) != 0) {
                    mprPrintf("%@\n", result);
                }
            }
        }
        ecResetInput(cp);
        cp->errorCount = 0;
        cp->fatalError = 0;
    }
    ecCloseStream(cp);
    return 0;
}
Пример #4
0
/*
    WARNING: the inside interpreter owns the exception object. Must fully extract all fields
 */
static void handleError(Ejs *ejs, EjsWorker *worker, EjsObj *exception, int throwOutside)
{
    Ejs             *inside;
    EjsObj          *e;
    MprDispatcher   *dispatcher;
    Message         *msg;

    assert(!worker->inside);
    assert(exception);
    assert(ejs == worker->ejs);

    ejsBlockGC(ejs);
    if ((msg = createMessage()) == 0) {
        ejsThrowMemoryError(ejs);
        return;
    }
    msg->worker = worker;
    msg->callback = "onerror";
    msg->callbackSlot = ES_Worker_onerror;
    inside = worker->pair->ejs;
    
    inside->exception = 0;
    e = ejsDeserialize(ejs, ejsSerialize(inside, exception, 0));
    inside->exception = exception;

    /*
        Inside interpreter owns the exception object, so must fully extract all exception. 
        Allocate into the outside worker's interpreter.
     */
    if (ejsIsError(inside, exception)) {
        msg->message = ejsGetPropertyByName(ejs, e, EN("message"));
        msg->stack = ejsGetPropertyByName(ejs, e, EN("stack"));
    } else {
        msg->message = e;
        msg->stack = 0;
    }
    if (throwOutside) {
        if (msg->stack) {
            ejsThrowStateError(ejs, "%@\n%@", ejsToString(ejs, msg->message), ejsToString(ejs, msg->stack));
        } else {
            ejsThrowStateError(ejs, "%@", ejsToString(ejs, msg->message));
        }
    }
    dispatcher = ejs->dispatcher;
    mprCreateEvent(dispatcher, "doMessage-error", 0, (MprEventProc) doMessage, msg, 0);
}
Пример #5
0
/*
 *  Start a worker thread. This is called by eval() and load(). Not by preload() or by Worker()
 *  It always joins.
 */
static EjsVar *startWorker(Ejs *ejs, EjsWorker *worker, int timeout)
{
    Ejs     *inside;
    EjsVar  *result;

    mprAssert(ejs);
    mprAssert(worker);
    mprAssert(worker->state == EJS_WORKER_BEGIN);

    if (worker->state > EJS_WORKER_BEGIN) {
        ejsThrowStateError(ejs, "Worker has already started");
        return 0;
    }
    mprAssert(worker->pair->state == EJS_WORKER_BEGIN);

    addWorker(ejs, worker);
    worker->state = EJS_WORKER_STARTED;

    worker->obj.var.permanent = 1;
    if (mprStartWorker(ejs, (MprWorkerProc) workerMain, (void*) worker, MPR_NORMAL_PRIORITY) < 0) {
        ejsThrowStateError(ejs, "Can't start worker");
        worker->obj.var.permanent = 0;
        return 0;
    }
    if (timeout == 0) {
        return ejs->undefinedValue;
    } 
    if (timeout < 0) {
        timeout = MAXINT;
    }
    if (join(ejs, (EjsVar*) worker, timeout) < 0) {
        ejsThrowStateError(ejs, "Timeout (%d)", timeout);
        return ejs->undefinedValue;
    }
    mprAssert(worker->pair);
    mprAssert(worker->pair->ejs);
    inside = worker->pair->ejs;
    result = ejsSerialize(ejs, inside->result, -1, 0, 0);
    if (result == 0) {
        return ejs->nullValue;
    }
    return ejsDeserialize(ejs, (EjsString*) result);
}