Skip to content

Commit

Permalink
pthread: Implement key destructors.
Browse files Browse the repository at this point in the history
Closes #182.


git-svn-id: http://svn.netlabs.org/repos/ports/pthread/trunk@2346 8d6eb4b1-0faa-de11-b929-00e081727c95
  • Loading branch information
dmik committed Mar 27, 2019
1 parent c3733f2 commit c485249
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 0 deletions.
61 changes: 61 additions & 0 deletions src/my_os2key.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,68 @@
#define INCL_EXAPIS_MAPPINGS
#include <os2emx.h>

#include <stdlib.h>

#include "pthread.h"
#include "tls.h"

struct pthread_key_pair_t_
{
pthread_key_t key;
void (*destructor)(void*);
struct pthread_key_pair_t_ *next;
};

typedef struct pthread_key_pair_t_ * pthread_key_pair_t;

static pthread_key_pair_t pair_start = NULL;

int pthread_key_create(pthread_key_t *key, void (*destructor)(void*))
{
pthread_key_pair_t new_pair;

new_pair = calloc(1, sizeof(*new_pair));
if (new_pair == NULL) {
errno = ENOMEM;
return -1;
}

if ((*(ULONG *)key = TlsAlloc()) != -1)
{
new_pair->key = *key;
new_pair->destructor = destructor;
new_pair->next = pair_start;

pair_start = new_pair;

return 0;
}

free(new_pair);

errno = EAGAIN;
return -1;
}

int pthread_key_delete(pthread_key_t key)
{
pthread_key_pair_t prev = NULL;
pthread_key_pair_t pair;

for (pair = pair_start; pair != NULL; pair = pair->next) {
if (pair->key == key) {
if (pair == pair_start)
pair_start = pair->next;
else
prev->next = pair->next;

free(pair);
break;
}

prev = pair;
}

if (TlsFree((ULONG)key))
return 0;
errno = EINVAL;
Expand All @@ -56,3 +104,16 @@ int pthread_setspecific(pthread_key_t key, const void *value)
return -1;
}

void pthread_key_destructor(void)
{
pthread_key_pair_t pair;

for (pair = pair_start; pair != NULL; pair = pair->next) {
void *value = pthread_getspecific(pair->key);

if (value != NULL && pair->destructor != NULL) {
pthread_setspecific(pair->key, NULL);
pair->destructor(value);
}
}
}
3 changes: 3 additions & 0 deletions src/my_os2thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ void pthread_exit(void *a)
pthread_setspecific(THR_self, NULL);
}

// call all available destructors associated with all keys
pthread_key_destructor();

// thread is joinable, pthread_join is supposed to be called from main thread


Expand Down
2 changes: 2 additions & 0 deletions src/pthread_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ struct pthread_rwlock_t_
pthread_t owner;
};

void pthread_key_destructor(void);

#ifdef __cplusplus
} // extern "C"
#endif
Expand Down

0 comments on commit c485249

Please sign in to comment.