@@ -331,9 +331,13 @@ kevent_copyin(struct kqueue *kq, const struct kevent changelist[], int nchanges,
331331
332332#ifndef _WIN32
333333static void
334- kevent_release_kq_mutex (void * kq )
334+ kevent_release_kq_mutex (void * arg )
335335{
336- kqueue_unlock ((struct kqueue * )kq );
336+ struct kqueue * kq = arg ;
337+ dbg_printf ("Unlocking kq=%p due to cancellation" , kq );
338+ tracing_mutex_lock (& kq_mtx ); /* keep tsan happy */
339+ kqueue_unlock (kq );
340+ tracing_mutex_unlock (& kq_mtx );
337341}
338342#endif
339343
@@ -367,7 +371,7 @@ kevent(int kqfd,
367371 if (!changelist ) changelist = null_kev ;
368372
369373#ifndef _WIN32
370- prev_cancel_state = pthread_setcancelstate (PTHREAD_CANCEL_DISABLE , NULL );
374+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE , & prev_cancel_state );
371375#endif
372376 /*
373377 * Grab the global mutex. This prevents
@@ -439,8 +443,10 @@ kevent(int kqfd,
439443 */
440444#ifndef _WIN32
441445 (void )pthread_setcancelstate (prev_cancel_state , NULL );
442- if (prev_cancel_state == PTHREAD_CANCEL_ENABLE )
446+ if (prev_cancel_state == PTHREAD_CANCEL_ENABLE ) {
447+ dbg_printf ("Checking for deferred cancellations" );
443448 pthread_testcancel ();
449+ }
444450#endif
445451 rv = kqops .kevent_wait (kq , nevents , timeout );
446452#ifndef _WIN32
@@ -482,16 +488,23 @@ kevent(int kqfd,
482488
483489out :
484490#ifndef _WIN32
485- pthread_cleanup_pop (0 );
491+ /*
492+ * Test for cancellations first, so we don't
493+ * double unlock the kqueue.
494+ */
495+ pthread_setcancelstate (prev_cancel_state , NULL );
496+ if (prev_cancel_state == PTHREAD_CANCEL_ENABLE ) {
497+ dbg_printf ("Checking for deferred cancellations" );
498+ pthread_testcancel ();
499+ }
486500#endif
487- kqueue_unlock (kq );
488- dbg_printf ("--- END kevent %u ret %d ---" , myid , rv );
489501
490502#ifndef _WIN32
491- pthread_setcancelstate (prev_cancel_state , NULL );
492- if (prev_cancel_state == PTHREAD_CANCEL_ENABLE )
493- pthread_testcancel ();
503+ pthread_cleanup_pop (0 );
494504#endif
495505
506+ kqueue_unlock (kq );
507+ dbg_printf ("--- END kevent %u ret %d ---" , myid , rv );
508+
496509 return (rv );
497510}
0 commit comments