mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Merge branch 'decouple_controller_events_squashed'
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -111,5 +111,41 @@ 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;
|
||||
|
||||
/** Initialize a thread-local variable.
|
||||
*
|
||||
* After you call this function on a tor_threadlocal_t, you can call
|
||||
* tor_threadlocal_set to change the current value of this variable for the
|
||||
* current thread, and tor_threadlocal_get to retrieve the current value for
|
||||
* the current thread. Each thread has its own value.
|
||||
**/
|
||||
int tor_threadlocal_init(tor_threadlocal_t *threadlocal);
|
||||
/**
|
||||
* Release all resource associated with a thread-local variable.
|
||||
*/
|
||||
void tor_threadlocal_destroy(tor_threadlocal_t *threadlocal);
|
||||
/**
|
||||
* Return the current value of a thread-local variable for this thread.
|
||||
*
|
||||
* It's undefined behavior to use this function if the threadlocal hasn't
|
||||
* been initialized, or has been destroyed.
|
||||
*/
|
||||
void *tor_threadlocal_get(tor_threadlocal_t *threadlocal);
|
||||
/**
|
||||
* Change the current value of a thread-local variable for this thread to
|
||||
* <b>value</b>.
|
||||
*
|
||||
* It's undefined behavior to use this function if the threadlocal hasn't
|
||||
* been initialized, or has been destroyed.
|
||||
*/
|
||||
void tor_threadlocal_set(tor_threadlocal_t *threadlocal, void *value);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -124,6 +124,49 @@ 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)
|
||||
{
|
||||
void *value = TlsGetValue(threadlocal->index);
|
||||
if (value == NULL) {
|
||||
DWORD err = GetLastError();
|
||||
if (err != ERROR_SUCCESS) {
|
||||
char *msg = format_win32_error(err);
|
||||
log_err(LD_GENERAL, "Error retrieving thread-local value: %s", msg);
|
||||
tor_free(msg);
|
||||
tor_assert(err == ERROR_SUCCESS);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void
|
||||
tor_threadlocal_set(tor_threadlocal_t *threadlocal, void *value)
|
||||
{
|
||||
BOOL ok = TlsSetValue(threadlocal->index, value);
|
||||
if (!ok) {
|
||||
DWORD err = GetLastError();
|
||||
char *msg = format_win32_error(err);
|
||||
log_err(LD_GENERAL, "Error adjusting thread-local value: %s", msg);
|
||||
tor_free(msg);
|
||||
tor_assert(ok);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
tor_cond_wait(tor_cond_t *cond, tor_mutex_t *lock_, const struct timeval *tv)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user