Skip to content

Commit

Permalink
ly_errno BUGFIX pthread_once() is called once in process, not in each…
Browse files Browse the repository at this point in the history
… thread
  • Loading branch information
rkrejci committed Feb 8, 2016
1 parent 843f419 commit 2f83dc8
Showing 1 changed file with 20 additions and 12 deletions.
32 changes: 20 additions & 12 deletions src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,35 +46,27 @@ LY_ERR ly_errno_main = LY_SUCCESS;
static void
ly_errno_createkey(void)
{
LY_ERR *value;
int r;
void (*destr) (void *);

/* prepare ly_errno storage */
#ifdef __linux__
if (getpid() == syscall(SYS_gettid)) {
/* main thread - use global variable instead of thread-specific variable.
* This is mainly for valgrind, because in case of the main thread the
* destructor registered by pthread_key_create() is not called since
* the main thread is terminated rather by return or exit than by
* pthread_exit(). */
value = &ly_errno_main;
destr = NULL;
} else {
#else
{
{
#endif /* __linux__ */
destr = free;
value = calloc(1, sizeof *value);
}

/* initiate */
while ((r = pthread_key_create(&ly_errno_key, destr)) == EAGAIN);
if (r) {
LOGMEM;
return;
}
pthread_setspecific(ly_errno_key, value);
pthread_setspecific(ly_errno_key, NULL);
}

API LY_ERR *
Expand All @@ -85,8 +77,24 @@ ly_errno_location(void)
pthread_once(&ly_errno_once, ly_errno_createkey);
retval = pthread_getspecific(ly_errno_key);
if (!retval) {
/* error */
return &ly_errno_int;
/* prepare ly_errno storage */
#ifdef __linux__
if (getpid() == syscall(SYS_gettid)) {
/* main thread - use global variable instead of thread-specific variable. */
retval = &ly_errno_main;
} else {
#else
{
#endif /* __linux__ */
retval = calloc(1, sizeof *retval);
}

if (!retval) {
/* error */
return &ly_errno_int;
}

pthread_setspecific(ly_errno_key, retval);
}

return retval;
Expand Down

0 comments on commit 2f83dc8

Please sign in to comment.