@@ -270,18 +270,18 @@ typedef struct _VipsThreadpool {
270
270
*/
271
271
int n_waiting ; // (atomic)
272
272
273
+ /* Increment this and the next worker will decrement and exit if needed
274
+ * (used to downsize the threadpool).
275
+ */
276
+ int exit ; // (atomic)
277
+
273
278
/* Set this to abort evaluation early with an error.
274
279
*/
275
280
gboolean error ;
276
281
277
282
/* Ask threads to exit, either set by allocate, or on free.
278
283
*/
279
284
gboolean stop ;
280
-
281
- /* Set this and the next worker to see it will clear the flag and exit
282
- * (used to downsize the threadpool).
283
- */
284
- gboolean exit ; // (atomic)
285
285
} VipsThreadpool ;
286
286
287
287
static int
@@ -325,14 +325,20 @@ vips_worker_work_unit(VipsWorker *worker)
325
325
326
326
/* Has a thread been asked to exit? Volunteer if yes.
327
327
*/
328
- if (g_atomic_int_compare_and_exchange (& pool -> exit , TRUE, FALSE) ) {
328
+ if (g_atomic_int_add (& pool -> exit , -1 ) > 0 ) {
329
329
/* A thread had been asked to exit, and we've grabbed the
330
330
* flag.
331
331
*/
332
332
worker -> stop = TRUE;
333
333
g_mutex_unlock (pool -> allocate_lock );
334
334
return ;
335
335
}
336
+ else {
337
+ /* No one had been asked to exit and we've mistakenly taken
338
+ * the exit count below zero. Put it back up again.
339
+ */
340
+ g_atomic_int_inc (& pool -> exit );
341
+ }
336
342
337
343
if (vips_worker_allocate (worker )) {
338
344
pool -> error = TRUE;
@@ -513,7 +519,7 @@ vips_threadpool_new(VipsImage *im)
513
519
vips_semaphore_init (& pool -> tick , 0 , "tick" );
514
520
pool -> error = FALSE;
515
521
pool -> stop = FALSE;
516
- pool -> exit = FALSE ;
522
+ pool -> exit = 0 ;
517
523
518
524
/* If this is a tiny image, we won't need all max_workers threads.
519
525
* Guess how
@@ -696,7 +702,7 @@ vips_threadpool_run(VipsImage *im,
696
702
if (n_waiting > 3 &&
697
703
n_working > 1 ) {
698
704
VIPS_DEBUG_MSG ("shrinking thread pool\n" );
699
- g_atomic_int_set (& pool -> exit , TRUE );
705
+ g_atomic_int_inc (& pool -> exit );
700
706
n_working -= 1 ;
701
707
}
702
708
else if (n_waiting < 2 &&
0 commit comments