diff options
Diffstat (limited to 'tss/impl/win32.h')
-rw-r--r-- | tss/impl/win32.h | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/tss/impl/win32.h b/tss/impl/win32.h index f73588a..6adc02c 100644 --- a/tss/impl/win32.h +++ b/tss/impl/win32.h @@ -40,9 +40,12 @@ #define WIN32_LEAN_AND_MEAN #include <windows.h> +#include <stdlib.h> + +#include "simpleops/mtx.h" typedef struct _simpleops_tss { - struct _simpleops_tss *prev; + struct _simpleops_tss **prev; struct _simpleops_tss *next; DWORD idx; simpleops_tss_dtor_t dtor; @@ -52,46 +55,53 @@ typedef struct _simpleops_tss { #define _SIMPLEOPS_TSS_HEAD SIMPLEOPS_ADD_PREFIX (_simpleops_tss_head) extern simpleops_mtx_t _SIMPLEOPS_TSS_MTX; -extern simpleops_tss_t *_SIMPLEOPS_TSS_HEAD; +extern simpleops_tss_t _SIMPLEOPS_TSS_HEAD; static simpleops_always_inline int simpleops_tss_create (simpleops_tss_t *key, simpleops_tss_dtor_t dtor) { - *key = malloc (sizeof (*key)); - if (SIMPLEOPS_UNLIKELY (key == NULL)) + simpleops_tss_t tss; + + *key = NULL; + tss = malloc (sizeof (*tss)); + if (SIMPLEOPS_UNLIKELY (tss == NULL)) return simpleops_thrd_error; - simpleops_mtx_lock (&SIMPLEOPS_TSS_MTX); + simpleops_mtx_lock (&_SIMPLEOPS_TSS_MTX); - key->link = &SIMPLEOPS_TSS_HEAD; - key->next = SIMPLEOPS_TSS_HEAD; - key->idx = TlsAlloc (); - key->dtor = dtor; + tss->prev = &_SIMPLEOPS_TSS_HEAD; + tss->next = _SIMPLEOPS_TSS_HEAD; + tss->idx = TlsAlloc (); + tss->dtor = dtor; - if (SIMPLEOPS_UNLIKELY (key->idx == TLS_OUT_OF_INDEXES)) { - simpleops_mtx_unlock (&SIMPLEOPS_TSS_MTX); - free (key); - *key = NULL; + if (SIMPLEOPS_UNLIKELY (tss->idx == TLS_OUT_OF_INDEXES)) { + simpleops_mtx_unlock (&_SIMPLEOPS_TSS_MTX); + free (tss); return simpleops_thrd_error; } - SIMPLEOPS_TSS_HEAD->link = &key->next; - SIMPLEOPS_TSS_HEAD = key; + if (tss->next != NULL) + tss->next->prev = &tss->next; + *tss->prev = tss; - simpleops_mtx_unlock (&SIMPLEOPS_TSS_MTX); + simpleops_mtx_unlock (&_SIMPLEOPS_TSS_MTX); + *key = tss; return simpleops_thrd_success; } static simpleops_always_inline void simpleops_tss_delete (simpleops_tss_t key) { - simpleops_mtx_lock (&SIMPLEOPS_TSS_MTX); + simpleops_mtx_lock (&_SIMPLEOPS_TSS_MTX); + + if (key->next != NULL) + key->next->prev = key->prev; + *key->prev = key->next; - *key->link = key->next; TlsFree (key->idx); - simpleops_mtx_unlock (&SIMPLEOPS_TSS_MTX); + simpleops_mtx_unlock (&_SIMPLEOPS_TSS_MTX); free (key); } |