* thread pool, it remembers running requests and gathers replies. A single work queue
* should not be used by multiple threads simultaneously.
*
+ * Requests can have priorities. Requests with the highest priority are served first.
+ * Requests of priority 0 are guaranteed to be served on first-come-first-served
+ * basis, requests of higher priorities are unordered.
+ *
* When a thread pool is initialized, new_thread() is called for every thread first,
* allocating struct worker_thread (and user-defined thread context following it) for
* each thread. Then the threads are fired and each of them executes the init_thread()
struct raw_queue { // Generic queue with locking
pthread_mutex_t queue_mutex;
- clist queue;
+ clist pri0_queue; // Ordinary queue for requests with priority=0
+ struct work **pri_heap; // A heap for request with priority>0
+ uns heap_cnt, heap_max;
sem_t *queue_sem; // Number of requests queued
};
struct worker_pool {
struct raw_queue requests;
uns num_threads;
- uns stack_size;
+ uns stack_size; // 0 for default
struct worker_thread *(*new_thread)(void); // default: xmalloc the struct
void (*free_thread)(struct worker_thread *t); // default: xfree
void (*init_thread)(struct worker_thread *t); // default: empty
struct work { // A single request
cnode n;
+ uns priority;
struct work_queue *reply_to; // Where to queue the request when it's finished
void (*go)(struct worker_thread *t, struct work *w); // Called inside the worker thread
- void (*returned)(struct work_queue *q, struct work *w); // Called when returned back, NULL if work_wait should return
};
void worker_pool_init(struct worker_pool *p);