Пример #1
0
void ThreadPool::SubmitWork(const StringRef& name)
{
	RETURN_IF_EMPTY(name);
	ThreadPoolWork* work = FindWork(name);
	RETURN_IF_NULL(work);
	SubmitWork(*work);
}
Пример #2
0
/*
 * Function: depositWorkItem()
 *
 * Local function which deposits a WorkItem onto a work queue,
 * deciding in the process whether or not the thread pool needs
 * to be augmented with another thread to handle the new request.
 *
 */
static
int
depositWorkItem( unsigned int reqID,
                 WorkItem* wItem )
{
    EnterCriticalSection(&ioMan->manLock);

#if 0
    fprintf(stderr, "depositWorkItem: %d/%d\n",
            ioMan->workersIdle, ioMan->numWorkers);
    fflush(stderr);
#endif
    /* A new worker thread is created when there are fewer idle threads
     * than non-consumed queue requests. This ensures that requests will
     * be dealt with in a timely manner.
     *
     * [Long explanation of why the previous thread pool policy lead to
     * trouble]
     *
     * Previously, the thread pool was augmented iff no idle worker threads
     * were available. That strategy runs the risk of repeatedly adding to
     * the request queue without expanding the thread pool to handle this
     * sudden spike in queued requests.
     * [How? Assume workersIdle is 1, and addIORequest() is called. No new
     * thread is created and the request is simply queued. If addIORequest()
     * is called again _before the OS schedules a worker thread to pull the
     * request off the queue_, workersIdle is still 1 and another request is
     * simply added to the queue. Once the worker thread is run, only one
     * request is de-queued, leaving the 2nd request in the queue]
     *
     * Assuming none of the queued requests take an inordinate amount
     * of to complete, the request queue would eventually be
     * drained. But if that's not the case, the later requests will
     * end up languishing in the queue indefinitely. The non-timely
     * handling of requests may cause CH applications to misbehave /
     * hang; bad.
     *
     */
    ioMan->queueSize++;
    if ( (ioMan->workersIdle < ioMan->queueSize) ) {
        /* see if giving up our quantum ferrets out some idle threads.
         */
        LeaveCriticalSection(&ioMan->manLock);
        Sleep(0);
        EnterCriticalSection(&ioMan->manLock);
        if ( (ioMan->workersIdle < ioMan->queueSize) ) {
            /* No, go ahead and create another. */
            ioMan->numWorkers++;
            if (!NewIOWorkerThread(ioMan)) {
                ioMan->numWorkers--;
            }
        }
    }
    LeaveCriticalSection(&ioMan->manLock);

    if (SubmitWork(ioMan->workQueue,wItem)) {
        /* Note: the work item has potentially been consumed by a worker thread
         *       (and freed) at this point, so we cannot use wItem's requestID.
         */
        return reqID;
    } else {
        return 0;
    }
}