]> git.kaiwu.me - nginx.git/commitdiff
Thread pools: memory barriers in task completion notifications.
authorMaxim Dounin <mdounin@mdounin.ru>
Tue, 19 Apr 2016 14:18:28 +0000 (17:18 +0300)
committerMaxim Dounin <mdounin@mdounin.ru>
Tue, 19 Apr 2016 14:18:28 +0000 (17:18 +0300)
The ngx_thread_pool_done object isn't volatile, and at least some
compilers assume that it is permitted to reorder modifications of
volatile and non-volatile objects.  Added appropriate ngx_memory_barrier()
calls to make sure all modifications will happen before the lock is released.

Reported by Mindaugas Rasiukevicius,
http://mailman.nginx.org/pipermail/nginx-devel/2016-April/008160.html.

src/core/ngx_thread_pool.c

index 03530851adb902eb0752c1d8d8330897a2d1d8ca..f3655aa0bea1f1064150ccee2fe2837dcc27da25 100644 (file)
@@ -345,6 +345,8 @@ ngx_thread_pool_cycle(void *data)
         *ngx_thread_pool_done.last = task;
         ngx_thread_pool_done.last = &task->next;
 
+        ngx_memory_barrier();
+
         ngx_unlock(&ngx_thread_pool_done_lock);
 
         (void) ngx_notify(ngx_thread_pool_handler);
@@ -366,6 +368,8 @@ ngx_thread_pool_handler(ngx_event_t *ev)
     ngx_thread_pool_done.first = NULL;
     ngx_thread_pool_done.last = &ngx_thread_pool_done.first;
 
+    ngx_memory_barrier();
+
     ngx_unlock(&ngx_thread_pool_done_lock);
 
     while (task) {