diff options
author | Shawn O. Pearce <spearce@spearce.org> | 2008-12-30 21:49:38 -0800 |
---|---|---|
committer | Shawn O. Pearce <spearce@spearce.org> | 2008-12-30 21:56:11 -0800 |
commit | a1d34bc000cee6d72c3b5e329faa58424641611f (patch) | |
tree | 89d3150640c0ed5b386bc8113ac8999b20371ece /src/errors.c | |
parent | d74679498086d0fc2293dceb59155c696b11b86c (diff) | |
download | libgit2-a1d34bc000cee6d72c3b5e329faa58424641611f.tar.gz |
Support building on Mac OS X by using pthread_getspecific for TLS
The Mach-O format does not permit gcc to implement the __thread
TLS specification, so we must instead emulate it using a single
int cell allocated from memory and stored inside of the thread
specific data associated with the current pthread.
What makes this tricky is git_errno must be a valid lvalue, so
we really need to return a pointer to the caller and deference it
as part of the git_errno macro.
The GCC-specific __attribute__((constructor)) extension is used
to ensure the pthread_key_t is allocated before any Git functions
are executed in the library, as this is necessary to access our
thread specific storage.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Diffstat (limited to 'src/errors.c')
-rw-r--r-- | src/errors.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/src/errors.c b/src/errors.c index b3e014dd4..75636f477 100644 --- a/src/errors.c +++ b/src/errors.c @@ -1,9 +1,32 @@ #include "common.h" #include "thread-utils.h" /* for GIT_TLS */ +#if defined(GIT_TLS) /* compile-time constant initialization required */ GIT_TLS int git_errno = 0; +#elif defined(GIT_HAS_PTHREAD) + +static pthread_key_t errno_key; + +static void init_errno(void) __attribute__((constructor)); +static void init_errno(void) +{ + pthread_key_create(&errno_key, free); +} + +int *git__errno_storage(void) +{ + int *e = pthread_getspecific(errno_key); + if (!e) { + e = calloc(1, sizeof(*e)); + pthread_setspecific(errno_key, e); + } + return e; +} + +#endif + static struct { int num; const char *str; |