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