summaryrefslogtreecommitdiff
path: root/tss/impl/win32.h
diff options
context:
space:
mode:
Diffstat (limited to 'tss/impl/win32.h')
-rw-r--r--tss/impl/win32.h48
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);
}