Use thread-local storage to block event_queue recursion.

This commit is contained in:
Nick Mathewson
2015-08-12 10:49:19 -04:00
parent e2a6a7ec61
commit 9ec94f1d22
5 changed files with 104 additions and 24 deletions
+27
View File
@@ -275,6 +275,33 @@ tor_cond_signal_all(tor_cond_t *cond)
pthread_cond_broadcast(&cond->cond);
}
int
tor_threadlocal_init(tor_threadlocal_t *threadlocal)
{
int err = pthread_key_create(&threadlocal->key, NULL);
return err ? -1 : 0;
}
void
tor_threadlocal_destroy(tor_threadlocal_t *threadlocal)
{
pthread_key_delete(threadlocal->key);
memset(threadlocal, 0, sizeof(tor_threadlocal_t));
}
void *
tor_threadlocal_get(tor_threadlocal_t *threadlocal)
{
return pthread_getspecific(threadlocal->key);
}
void
tor_threadlocal_set(tor_threadlocal_t *threadlocal, void *value)
{
int err = pthread_setspecific(threadlocal->key, value);
tor_assert(err == 0);
}
/** Set up common structures for use by threading. */
void
tor_threads_init(void)
+13
View File
@@ -111,5 +111,18 @@ typedef struct alert_sockets_s {
int alert_sockets_create(alert_sockets_t *socks_out, uint32_t flags);
void alert_sockets_close(alert_sockets_t *socks);
typedef struct tor_threadlocal_s {
#ifdef _WIN32
DWORD index;
#else
pthread_key_t key;
#endif
} tor_threadlocal_t;
int tor_threadlocal_init(tor_threadlocal_t *threadlocal);
void tor_threadlocal_destroy(tor_threadlocal_t *threadlocal);
void *tor_threadlocal_get(tor_threadlocal_t *threadlocal);
void tor_threadlocal_set(tor_threadlocal_t *threadlocal, void *value);
#endif
+27
View File
@@ -122,6 +122,33 @@ tor_cond_signal_all(tor_cond_t *cond)
tor_cond_signal_impl(cond, 1);
}
int
tor_threadlocal_init(tor_threadlocal_t *threadlocal)
{
threadlocal->index = TlsAlloc();
return (threadlocal->index == TLS_OUT_OF_INDEXES) ? -1 : 0;
}
void
tor_threadlocal_destroy(tor_threadlocal_t *threadlocal)
{
TlsFree(threadlocal->index);
memset(threadlocal, 0, sizeof(tor_threadlocal_t));
}
void *
tor_threadlocal_get(tor_threadlocal_t *threadlocal)
{
return TlsGetValue(threadlocal->index);
}
void
tor_threadlocal_set(tor_threadlocal_t *threadlocal, void *value)
{
BOOL ok = TlsSetValue(threadlocal->index, value);
tor_assert(ok);
}
int
tor_cond_wait(tor_cond_t *cond, tor_mutex_t *lock_, const struct timeval *tv)
{