Revision 19d092cf thread-pool.c
b/thread-pool.c | ||
---|---|---|
39 | 39 |
BlockDriverAIOCB common; |
40 | 40 |
ThreadPoolFunc *func; |
41 | 41 |
void *arg; |
42 |
|
|
43 |
/* Moving state out of THREAD_QUEUED is protected by lock. After |
|
44 |
* that, only the worker thread can write to it. Reads and writes |
|
45 |
* of state and ret are ordered with memory barriers. |
|
46 |
*/ |
|
42 | 47 |
enum ThreadState state; |
43 | 48 |
int ret; |
44 | 49 |
|
... | ... | |
95 | 100 |
|
96 | 101 |
ret = req->func(req->arg); |
97 | 102 |
|
98 |
qemu_mutex_lock(&lock); |
|
99 |
req->state = THREAD_DONE; |
|
100 | 103 |
req->ret = ret; |
104 |
/* Write ret before state. */ |
|
105 |
smp_wmb(); |
|
106 |
req->state = THREAD_DONE; |
|
107 |
|
|
108 |
qemu_mutex_lock(&lock); |
|
101 | 109 |
if (pending_cancellations) { |
102 | 110 |
qemu_cond_broadcast(&check_cancel); |
103 | 111 |
} |
... | ... | |
162 | 170 |
trace_thread_pool_complete(elem, elem->common.opaque, elem->ret); |
163 | 171 |
} |
164 | 172 |
if (elem->state == THREAD_DONE && elem->common.cb) { |
165 |
qemu_mutex_lock(&lock); |
|
166 |
int ret = elem->ret; |
|
167 |
qemu_mutex_unlock(&lock); |
|
168 | 173 |
QLIST_REMOVE(elem, all); |
169 |
elem->common.cb(elem->common.opaque, ret); |
|
174 |
/* Read state before ret. */ |
|
175 |
smp_rmb(); |
|
176 |
elem->common.cb(elem->common.opaque, elem->ret); |
|
170 | 177 |
qemu_aio_release(elem); |
171 | 178 |
goto restart; |
172 | 179 |
} else { |
Also available in: Unified diff