On Thu, 15 May 2008, Andriy Gapon wrote:The example you gave indicates an incorrect mechanism being used for the GUI to communicate with this worker thread. For the behavior you desire, you need a common condition that lets both the GUI and the work item generator indicate that there is something for the worker to do, *and* you need seperate mechanisms for the GUI and work item generator to add to their respective queues. Something like this (could be made even better with a little effor): struct worker_queues_s { pthread_mutex_t work_mutex; struct work_queue_s work_queue; pthread_mutex_t gui_mutex; struct gui_queue_s gui_queue; pthread_mutex_t stuff_mutex; int stuff_todo; pthread_cond_t stuff_cond; }; struct worker_queue_s wq; int main(int argc, char *argv[]) { // blah blah init_worker_queue(&wq); // blah blah } void gui_callback(...) { // blah blah // Set up GUI message pthread_mutex_lock(&wq.gui_mutex); // Add GUI message to queue pthread_mutex_unlock(&wq.gui_mutex); pthread_mutex_lock(&wq.stuff_mutex); wq.stuff_todo++; pthread_cond_signal(&wq.stuff_cond); pthread_mutex_unlock(&wq.stuff_mutex); // blah blah } void* work_generator_thread(void*) { // blah blah while (1) { // Set up work to do pthread_mutex_lock(&wq.work_mutex); // Add work item to queue pthread_mutex_unlock(&wq.work_mutex); pthread_mutex_lock(&wq.stuff_mutex); wq.stuff_todo++; pthread_cond_signal(&wq.stuff_cond); pthread_mutex_unlock(&wq.stuff_mutex); } // blah blah } void* worker_thread(void* arg) { // blah blah while (1) { // Wait for there to be something to do pthread_mutex_lock(&wq.stuff_mutex); while (wq.stuff_todo < 1) { pthread_cond_wait(&wq.stuff_cond, &wq.stuff_mutex); } pthread_mutex_unlock(&wq.stuff_mutex); // Handle GUI messages pthread_mutex_lock(&wq.gui_mutex); while (!gui_queue_empty(&wq.gui_queue) { // dequeue and process GUI messages pthread_mutex_lock(&wq.stuff_mutex); wq.stuff_todo--; pthread_mutex_unlock(&wq.stuff_mutex); } pthread_mutex_unlock(&wq.gui_mutex); // Handle work items pthread_mutex_lock(&wq.work_mutex); while (!work_queue_empty(&wq.work_queue)) { // dequeue and process work item pthread_mutex_lock(&wq.stuff_mutex); wq.stuff_todo--; pthread_mutex_unlock(&wq.stuff_mutex); } pthread_mutex_unlock(&wq.work_mutex); } // blah blah } This should accomplish what you desire. Caution that I haven't compiled, run, or tested it, but I'm pretty sure it's a solid solution. The key here is unifying the two input sources (the GUI and work queues) without blocking on either one of them individually. The value of (wq.stuff_todo < 1) becomes a proxy for the value of (gui_queue_empty(...) && work_queue_empty(...)). I hope that helps, Brent -- Brent Casavant Dance like everybody should be watching. www.angeltread.org KD5EMB, EN34lv _______________________________________________ freebsd-threads@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-threads To unsubscribe, send any mail to "freebsd-threads-unsubscribe@freebsd.org"
| Joe Perches | [PATCH 010/148] include/asm-x86/bitops.h: checkpatch cleanups - formatting only |
| Con Kolivas | Re: [REPORT] cfs-v4 vs sd-0.44 |
| Randy Dunlap | Re: 2.6.25-rc2-mm1 (wakeup) |
| Greg Kroah-Hartman | [PATCH 006/196] Chinese: add translation of oops-tracing.txt |
git: | |
| Kevin Ballard | Re: git on MacOSX and files with decomposed utf-8 file names |
| Ingo Molnar | [OT] Your branch is ahead of the tracked remote branch 'origin/master' by 50 commi... |
| Mark Levedahl | rc4 - make quick-install-doc is broken |
| Dmitry Potapov | Re: I'm a total push-over.. |
| Richard Stallman | Real men don't attack straw men |
| GVG GVG | ssh_exchange_identification: Connection closed by remote host |
| Richard Stallman | Re: Real men don't attack straw men |
| David Newman | setting dscp or tos bits |
| Radu Rendec | Endianness problem with u32 classifier hash masks |
| Bruno Randolf | [PATCH] add macro for printing mac addresses |
| Jeff Kirsher | [NET-NEXT PATCH 0/9] e1000: update and cleanups |
| Andrew Morton | Re: [BUG] New Kernel Bugs |
