Skip to content

Commit

Permalink
BUGFIX memory leak
Browse files Browse the repository at this point in the history
Since pthread_once() is called only once in a process, also the destructor
in pthread_key_create() is the same for all threads. But we use dynamic
memory for threads and static memory for the main thread. Therefore, we
have to check in destructor (and we cannot use standard free()) for freeing
static memory if someone will use pthread_exit() in main().

Fixes #15
  • Loading branch information
rkrejci committed Feb 8, 2016
1 parent 214d7cf commit 1d7f8d2
Showing 1 changed file with 13 additions and 17 deletions.
30 changes: 13 additions & 17 deletions src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,29 +44,25 @@ static pthread_key_t ly_errno_key;
LY_ERR ly_errno_main = LY_SUCCESS;
#endif

static void
ly_errno_free(void *ptr)
{
/* in __linux__ we use static memory in the main thread,
* so this check is for programs terminating the main()
* function by pthread_exit() :)
*/
if (ptr != &ly_errno_main) {
free(ptr);
}
}

static void
ly_errno_createkey(void)
{
int r;
void (*destr) (void *);

#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(). */
destr = NULL;
} else {
#else
{
#endif /* __linux__ */
destr = free;
}

/* initiate */
while ((r = pthread_key_create(&ly_errno_key, destr)) == EAGAIN);
while ((r = pthread_key_create(&ly_errno_key, ly_errno_free)) == EAGAIN);
pthread_setspecific(ly_errno_key, NULL);
}

Expand Down

0 comments on commit 1d7f8d2

Please sign in to comment.