diff --git a/docs/ares_init_options.3 b/docs/ares_init_options.3 index a27e6e08..637c17eb 100644 --- a/docs/ares_init_options.3 +++ b/docs/ares_init_options.3 @@ -227,8 +227,9 @@ The value of .I sock_state_cb_data will be passed as the .I data -argument. Since this may be called cross-thread, a channel lock is NOT held -when this callback is called. +argument. The channel lock is held during this callback, if calling +cross-thread care must be taken to ensure no other c-ares functions are +called from this callback. Cannot be used with \fBARES_OPT_EVENT_THREAD\fP. .TP 18 diff --git a/src/lib/ares_event_thread.c b/src/lib/ares_event_thread.c index e87313f6..21896d45 100644 --- a/src/lib/ares_event_thread.c +++ b/src/lib/ares_event_thread.c @@ -274,16 +274,19 @@ static void *ares_event_thread(void *arg) const struct timeval *tvout; unsigned long timeout_ms = 0; /* 0 = unlimited */ + ares_event_process_updates(e); + + /* Don't hold a mutex while waiting on events or calling into anything + * that might require a c-ares channel lock since a callback could be + * triggered cross-thread */ + ares__thread_mutex_unlock(e->mutex); + tvout = ares_timeout(e->channel, NULL, &tv); if (tvout != NULL) { timeout_ms = (unsigned long)((tvout->tv_sec * 1000) + (tvout->tv_usec / 1000) + 1); } - ares_event_process_updates(e); - - /* Don't hold a mutex while waiting on events */ - ares__thread_mutex_unlock(e->mutex); e->ev_sys->wait(e, timeout_ms); /* Each iteration should do timeout processing */ diff --git a/src/lib/ares_private.h b/src/lib/ares_private.h index a03522ef..bff73561 100644 --- a/src/lib/ares_private.h +++ b/src/lib/ares_private.h @@ -639,9 +639,7 @@ void ares_queue_notify_empty(ares_channel_t *channel); #define SOCK_STATE_CALLBACK(c, s, r, w) \ do { \ if ((c)->sock_state_cb) { \ - ares__channel_unlock((c)); \ (c)->sock_state_cb((c)->sock_state_cb_data, (s), (r), (w)); \ - ares__channel_lock((c)); \ } \ } while (0)