@@ -62,10 +62,10 @@ static void worker(void* arg) {
62
62
uv_sem_post ((uv_sem_t * ) arg );
63
63
arg = NULL ;
64
64
65
+ uv_mutex_lock (& mutex );
65
66
for (;;) {
66
- uv_mutex_lock ( & mutex );
67
+ /* ` mutex` should always be locked at this point. */
67
68
68
- wait_for_work :
69
69
/* Keep waiting while either no work is present or only slow I/O
70
70
and we're at the threshold for that. */
71
71
while (QUEUE_EMPTY (& wq ) ||
@@ -93,13 +93,13 @@ static void worker(void* arg) {
93
93
other work in the queue is done. */
94
94
if (slow_io_work_running >= slow_work_thread_threshold ()) {
95
95
QUEUE_INSERT_TAIL (& wq , q );
96
- goto wait_for_work ;
96
+ continue ;
97
97
}
98
98
99
99
/* If we encountered a request to run slow I/O work but there is none
100
100
to run, that means it's cancelled => Start over. */
101
101
if (QUEUE_EMPTY (& slow_io_pending_wq ))
102
- goto wait_for_work ;
102
+ continue ;
103
103
104
104
is_slow_work = 1 ;
105
105
slow_io_work_running ++ ;
@@ -122,13 +122,19 @@ static void worker(void* arg) {
122
122
w -> work (w );
123
123
124
124
uv_mutex_lock (& w -> loop -> wq_mutex );
125
- if (is_slow_work )
126
- slow_io_work_running -- ;
127
125
w -> work = NULL ; /* Signal uv_cancel() that the work req is done
128
126
executing. */
129
127
QUEUE_INSERT_TAIL (& w -> loop -> wq , & w -> wq );
130
128
uv_async_send (& w -> loop -> wq_async );
131
129
uv_mutex_unlock (& w -> loop -> wq_mutex );
130
+
131
+ /* Lock `mutex` since that is expected at the start of the next
132
+ * iteration. */
133
+ uv_mutex_lock (& mutex );
134
+ if (is_slow_work ) {
135
+ /* `slow_io_work_running` is protected by `mutex`. */
136
+ slow_io_work_running -- ;
137
+ }
132
138
}
133
139
}
134
140
0 commit comments