]> git.cworth.org Git - apitrace/blob - common/workqueue_posix.cpp
Implement and use os::thread.
[apitrace] / common / workqueue_posix.cpp
1 #include <queue>
2 #include <assert.h>
3
4 #include "os_workqueue.hpp"
5
6 namespace os
7 {
8
9 /**
10  * return 0 on batch complete, -1 on thread exit request.
11  */
12 int WorkQueue::run_tasks(void)
13 {
14     os::unique_lock<os::mutex> lock(mutex);
15
16     while (work_queue.empty() && !exit_workqueue) {
17         wake_cond.wait(lock);
18     }
19
20     if (exit_workqueue) {
21         return -1;
22     }
23
24     std::queue<WorkQueueWork *> batch;
25     std::swap(work_queue, batch);
26     busy = true;
27
28     lock.unlock();
29
30     assert(!batch.empty());
31     while (!batch.empty()) {
32         WorkQueueWork *task;
33
34         task = batch.front();
35         task->run();
36         batch.pop();
37         delete task;
38     }
39
40     lock.lock();
41
42     busy = false;
43     complete_cond.signal();
44
45     return 0;
46 }
47
48 /* Must be called with WorkQueue::lock held */
49 void WorkQueue::wake_up_thread(void)
50 {
51     wake_cond.signal();
52 }
53
54 void WorkQueue::queue_work(WorkQueueWork *task)
55 {
56     mutex.lock();
57     work_queue.push(task);
58     wake_up_thread();
59     mutex.unlock();
60 }
61
62 void WorkQueue::flush(void)
63 {
64     os::unique_lock<os::mutex> lock(mutex);
65     while (!work_queue.empty() || busy) {
66         complete_cond.wait(lock);
67     }
68 }
69
70 void WorkQueue::thread_entry(void)
71 {
72     int err;
73
74     do {
75         err = run_tasks();
76     } while (!err);
77 }
78
79 void WorkQueue::destroy(void)
80 {
81     mutex.lock();
82     exit_workqueue = true;
83     wake_up_thread();
84     mutex.unlock();
85 }
86
87 void *WorkQueue__entry_thunk(void *data)
88 {
89     WorkQueue *thread = static_cast<WorkQueue *>(data);
90
91     thread->thread_entry();
92
93     return NULL;
94 }
95
96 WorkQueue::WorkQueue(void) :
97     busy(false),
98     exit_workqueue(false),
99     thread(WorkQueue__entry_thunk, this)
100 {
101 }
102
103 WorkQueue::~WorkQueue(void)
104 {
105     thread.join();
106 }
107
108 }