Differences From Artifact [b1dffe2b41]:
- File
src/tlskey.m
— part of check-in
[acc67b0bb6]
at
2019-08-02 02:16:04
on branch trunk
— tlskey: Create OFMapTable lazily
of_tlskey_new() is called in constructors, but at that time, OFMapTable
might not be available yet. (user: js, size: 2249) [annotate] [blame] [check-ins using]
To Artifact [22af5740b4]:
- File src/tlskey.m — part of check-in [da383f4f03] at 2019-08-03 18:13:50 on branch trunk — Add threads for AmigaOS (user: js, size: 3244) [annotate] [blame] [check-ins using]
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | */ #include "config.h" #import "tlskey.h" #ifdef OF_AMIGAOS # import "OFMapTable.h" static const of_map_table_functions_t functions = { NULL }; #endif bool of_tlskey_new(of_tlskey_t *key) { #if defined(OF_HAVE_PTHREADS) return (pthread_key_create(key, NULL) == 0); #elif defined(OF_WINDOWS) return ((*key = TlsAlloc()) != TLS_OUT_OF_INDEXES); #elif defined(OF_AMIGAOS) | > > > > > > > > > > > > > > > > > > > | > > > | | > > > > > > > > > > > > > > > | | < < | | | < < | > > > > > > > > > > > > > > > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | */ #include "config.h" #import "tlskey.h" #ifdef OF_AMIGAOS # ifdef OF_AMIGAOS4 # define __USE_INLINE__ # define __NOLIBBASE__ # define __NOGLOBALIFACE__ # endif # include <exec/semaphores.h> # include <proto/exec.h> # import "OFMapTable.h" # import "OFList.h" # ifdef OF_AMIGAOS4 extern struct ExecIFace *IExec; # endif static const of_map_table_functions_t functions = { NULL }; static OFList *allKeys = nil; static struct SignalSemaphore semaphore; OF_CONSTRUCTOR() { InitSemaphore(&semaphore); } #endif bool of_tlskey_new(of_tlskey_t *key) { #if defined(OF_HAVE_PTHREADS) return (pthread_key_create(key, NULL) == 0); #elif defined(OF_WINDOWS) return ((*key = TlsAlloc()) != TLS_OUT_OF_INDEXES); #elif defined(OF_AMIGAOS) if ((*key = calloc(1, sizeof(**key))) == NULL) return false; /* * We create the map table lazily, as some TLS are created in * constructors, at which time OFMapTable is not available yet. */ return true; #endif } bool of_tlskey_free(of_tlskey_t key) { #if defined(OF_HAVE_PTHREADS) return (pthread_key_delete(key) == 0); #elif defined(OF_WINDOWS) return TlsFree(key); #elif defined(OF_AMIGAOS) ObtainSemaphore(&semaphore); @try { [allKeys removeListObject: key->listObject]; [key->mapTable release]; free(key); } @finally { ReleaseSemaphore(&semaphore); } return true; #endif } #ifdef OF_AMIGAOS static void unsafeCreateMapTable(of_tlskey_t key) { key->mapTable = [[OFMapTable alloc] initWithKeyFunctions: functions objectFunctions: functions]; if (allKeys == nil) allKeys = [[OFList alloc] init]; key->listObject = [allKeys appendObject: key->mapTable]; } void * of_tlskey_get(of_tlskey_t key) { void *ret; ObtainSemaphore(&semaphore); @try { if (key->mapTable == NULL) unsafeCreateMapTable(key); ret = [key->mapTable objectForKey: FindTask(NULL)]; } @finally { ReleaseSemaphore(&semaphore); } return ret; } bool of_tlskey_set(of_tlskey_t key, void *ptr) { ObtainSemaphore(&semaphore); @try { struct Task *task = FindTask(NULL); if (key->mapTable == NULL) unsafeCreateMapTable(key); if (ptr == NULL) [key->mapTable removeObjectForKey: task]; else [key->mapTable setObject: ptr forKey: task]; } @catch (id e) { return false; } @finally { ReleaseSemaphore(&semaphore); } return true; } void of_tlskey_thread_exited(void) { ObtainSemaphore(&semaphore); @try { struct Task *task = FindTask(NULL); for (of_list_object_t *iter = allKeys.firstListObject; iter != NULL; iter = iter->next) [iter->object removeObjectForKey: task]; } @finally { ReleaseSemaphore(&semaphore); } } #endif |