Пример #1
0
bool
ThreadPool::init()
{
#ifdef JS_THREADSAFE
    // Compute desired number of workers based on env var or # of CPUs.
    size_t numWorkers = 0;
    char *pathreads = getenv("PATHREADS");
    if (pathreads != NULL)
        numWorkers = strtol(pathreads, NULL, 10);
    else
        numWorkers = GetCPUCount() - 1;

    // Allocate workers array and then start the worker threads.
    // Ensure that the field numWorkers_ always tracks the number of
    // *successfully initialized* workers.
    for (size_t workerId = 0; workerId < numWorkers; workerId++) {
        ThreadPoolWorker *worker = js_new<ThreadPoolWorker>(workerId, this);
        if (!worker->init()) {
            js_delete(worker);
            return false;
        }
        if (!workers_.append(worker)) {
            js_delete(worker);
            return false;
        }
        if (!worker->start())
            return false;
    }
#endif

    return true;
}
Пример #2
0
bool
ThreadPool::lazyStartWorkers(JSContext *cx)
{
    // Starts the workers if they have not already been started.  If
    // something goes wrong, reports an error and ensures that all
    // partially started threads are terminated.  Therefore, upon exit
    // from this function, the workers array is either full (upon
    // success) or empty (upon failure).

#ifndef JS_THREADSAFE
    return true;
#else
    if (!workers_.empty()) {
        JS_ASSERT(workers_.length() == numWorkers());
        return true;
    }

    // Allocate workers array and then start the worker threads.
    // Note that numWorkers() is the number of *desired* workers,
    // but workers_.length() is the number of *successfully
    // initialized* workers.
    for (size_t workerId = 0; workerId < numWorkers(); workerId++) {
        ThreadPoolWorker *worker = js_new<ThreadPoolWorker>(workerId);
        if (!worker) {
            terminateWorkersAndReportOOM(cx);
            return false;
        }
        if (!worker->init() || !workers_.append(worker)) {
            js_delete(worker);
            terminateWorkersAndReportOOM(cx);
            return false;
        }
        if (!worker->start()) {
            // Note: do not delete worker here because it has been
            // added to the array and hence will be deleted by
            // |terminateWorkersAndReportOOM()|.
            terminateWorkersAndReportOOM(cx);
            return false;
        }
    }

    return true;
#endif
}