|
| 1 | +#include "../include/thread_pool.h" |
| 2 | + |
| 3 | +// Initializes thread pool and spins up the requested number of threads |
| 4 | +ThreadPool::ThreadPool(int numberOfThreads) { |
| 5 | + uv_mutex_init(&queueMutex); |
| 6 | + uv_sem_init(&threadSemaphore, 0); |
| 7 | + uv_async_init(uv_default_loop(), &keepNodeAlive, NULL); |
| 8 | + uv_unref((uv_handle_t *)&keepNodeAlive); |
| 9 | + |
| 10 | + for(int i=0; i<numberOfThreads; i++) { |
| 11 | + uv_thread_t thread; |
| 12 | + uv_thread_create(&thread, RunEventQueue, this); |
| 13 | + } |
| 14 | +} |
| 15 | + |
| 16 | +// Queues work on the thread pool |
| 17 | +void ThreadPool::QueueWork(Callback callback, void *data) { |
| 18 | + uv_mutex_lock(&queueMutex); |
| 19 | + if(handleState == CLOSED) { |
| 20 | + // there is work on the thread pool - reference the handle so |
| 21 | + // node doesn't terminate |
| 22 | + uv_ref((uv_handle_t *)&keepNodeAlive); |
| 23 | + handleState = OPEN; |
| 24 | + } |
| 25 | + queue.push(Work(callback, data)); |
| 26 | + uv_mutex_unlock(&queueMutex); |
| 27 | + uv_sem_post(&threadSemaphore); |
| 28 | +} |
| 29 | + |
| 30 | +void ThreadPool::RunEventQueue(void *threadPool) { |
| 31 | + static_cast<ThreadPool *>(threadPool)->RunEventQueue(); |
| 32 | +} |
| 33 | + |
| 34 | +void ThreadPool::RunEventQueue() { |
| 35 | + for ( ; ; ) { |
| 36 | + // wait until there is work to do |
| 37 | + uv_sem_wait(&threadSemaphore); |
| 38 | + uv_mutex_lock(&queueMutex); |
| 39 | + // the semaphore should guarantee that queue is not empty |
| 40 | + Work work = queue.front(); |
| 41 | + queue.pop(); |
| 42 | + uv_mutex_unlock(&queueMutex); |
| 43 | + |
| 44 | + // perform the queued work |
| 45 | + (*work.callback)(work.data); |
| 46 | + |
| 47 | + uv_mutex_lock(&queueMutex); |
| 48 | + if(queue.empty() && handleState == OPEN) { |
| 49 | + // the queue is empty - unreference the handle so node can terminate |
| 50 | + uv_unref((uv_handle_t *)&keepNodeAlive); |
| 51 | + handleState = CLOSED; |
| 52 | + } |
| 53 | + uv_mutex_unlock(&queueMutex); |
| 54 | + } |
| 55 | +} |
0 commit comments