@@ -120,91 +120,104 @@ int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
120120
121121///////////////////////////////////////////////////////////////////////////////
122122
123- typedef struct {
124- pthread_key_t tkey ;
123+ #include "common/htable.h"
124+
125+ typedef struct FLS_KEY FLS_KEY ;
126+ typedef struct TLS_KEY TLS_KEY ;
127+
128+ struct FLS_KEY {
129+ HTABLE * keys ;
130+ };
131+
132+ struct TLS_KEY {
133+ pthread_key_t key ;
125134 void (* destructor )(void * );
126- FIFO * keys ;
127- } TLS_KEY ;
135+ FIFO * objs ;
136+ };
128137
129- static pthread_key_t __tls_key = TLS_OUT_OF_INDEXES ;
130- static pthread_key_t __fls_key = FLS_OUT_OF_INDEXES ;
138+ static pthread_key_t __tls_key = TLS_OUT_OF_INDEXES ;
139+ static pthread_key_t __fls_key = FLS_OUT_OF_INDEXES ;
131140
132141extern int acl_fiber_scheduled (void );
133142
134143static void thread_exit (void * ctx )
135144{
136- TLS_KEY * tkey = (TLS_KEY * ) ctx ;
137- void (* destructor )(void * );
138- void * context ;
139-
140- if (tkey -> keys ) {
141- TLS_KEY * iter ;
142- while ((iter = (TLS_KEY * ) tkey -> keys -> pop_back (tkey -> keys ))) {
143- if (iter -> destructor ) {
144- destructor = iter -> destructor ;
145- context = TlsGetValue (iter -> tkey );
146- mem_free (iter );
147-
148- destructor (context );
149- }
150- }
151- }
145+ FLS_KEY * fkey = (FLS_KEY * ) ctx ;
146+ void * ctx ;
152147
153- destructor = tkey -> destructor ;
154- context = TlsGetValue ( tkey -> tkey );
148+ assert ( fkey ) ;
149+ assert ( fkey -> keys );
155150
156- fifo_free (tkey -> keys , mem_free );
157- mem_free (tkey );
151+ ITER iter ;
152+ foreach (iter , fkey -> keys ) {
153+ TLS_KEY * tkey = (TLS_KEY * ) iter .data ;
154+ assert (tkey );
155+
156+ if (tkey -> destructor == NULL ) {
157+ continue ;
158+ }
158159
159- if (destructor ) {
160- destructor (context );
160+ while ((ctx = tkey -> objs -> pop_front (tkey -> objs ))) {
161+ tkey -> destructor (ctx );
162+ }
163+
164+ fifo_free (tkey -> objs , NULL );
161165 }
166+
167+ htable_free (tkey -> keys , mem_free );
168+ mem_free (tkey );
162169}
163170
164171/* 每个进程的唯一初始化函数 */
165172
166- static void pthread_init_once (void )
173+ static void thread_once (void )
167174{
168175 __tls_key = TlsAlloc ();
169176 __fls_key = FlsAlloc (thread_exit );
170177}
171178
179+ static void hash_key (pthread_key_t key , char * buf , size_t n )
180+ {
181+ assert (n > 10 );
182+ _snprintf (buf , n , "%d" , key );
183+ buf [n - 1 ] = '\0' ;
184+ }
185+
172186int pthread_key_create (pthread_key_t * key_ptr , void (* destructor )(void * ))
173187{
174- pthread_once (& __control_once , pthread_init_once );
188+ pthread_once (& __control_once , thread_once );
189+
190+ assert (__tls_key != TLS_OUT_OF_INDEXES );
191+ assert (__fls_key != FLS_OUT_OF_INDEXES );
175192
176193 if (* key_ptr <= 0 && * key_ptr != TLS_OUT_OF_INDEXES ) {
177194 * key_ptr = TlsAlloc ();
178195 assert (* key_ptr != TLS_OUT_OF_INDEXES );
179196 }
180197
181- TLS_KEY * tkey = (TLS_KEY * ) mem_calloc (sizeof (TLS_KEY ), 1 ), * curr ;
182- tkey -> tkey = * key_ptr ;
198+ TLS_KEY * tkey = (TLS_KEY * ) mem_calloc (sizeof (TLS_KEY ), 1 );
199+ tkey -> key = * key_ptr ;
183200 tkey -> destructor = destructor ;
201+ tkey -> objs = fifo_new ();
184202
185- if (acl_fiber_scheduled ()) {
186- curr = (TLS_KEY * ) TlsGetValue (__tls_key );
187- if (curr && curr -> keys ) {
188- curr -> keys -> push_back (curr -> keys , tkey );
189- } else {
190- msg_error ("%s(%d): no TLS_KEY for key=%d" ,
191- __FUNCTION__ , __LINE__ , __tls_key );
192- }
193- } else if (__tls_key == TLS_OUT_OF_INDEXES ) {
194- msg_error ("%s(%d): __tls_key is invalid" , __FUNCTION__ , __LINE__ );
195- } else if ((curr = TlsGetValue (__tls_key )) != NULL ) {
196- if (curr -> keys ) {
197- curr -> keys -> push_back (curr -> keys , tkey );
198- } else {
199- msg_error ("%s(%d): keys is null" , __FUNCTION__ , __LINE__ );
203+ char kbuf [32 ];
204+ hash_key (* key_ptr , kbuf , sizeof (kbuf ));
205+ FLS_KEY * fkey ;
206+
207+ if ((fkey = (FLS_KEY * ) TlsGetValue (__tls_key )) == NULL ) {
208+ if (acl_fiber_scheduled ()) {
209+ msg_fatal ("%s(%d): should be in thread mode" ,
210+ __FUNCTION__ , __LINE__ );
200211 }
201- } else {
202- assert (__fls_key != FLS_OUT_OF_INDEXES );
203- tkey -> keys = fifo_new ();
204- TlsSetValue (__tls_key , tkey );
205- FlsSetValue (__fls_key , tkey );
212+
213+ fkey = (FLS_KEY * ) mem_calloc (sizeof (FLS_KEY ), 1 );
214+ fkey -> keys = htable_create (10 );
215+
216+ TlsSetValue (__tls_key , fkey );
217+ FlsSetValue (__fls_key , fkey );
206218 }
207219
220+ htable_enter (fkey -> keys , kbuf , tkey );
208221 return 0 ;
209222}
210223
@@ -215,18 +228,36 @@ void *pthread_getspecific(pthread_key_t key)
215228
216229int pthread_setspecific (pthread_key_t key , void * value )
217230{
218- if (key <= 0 || key == TLS_OUT_OF_INDEXES ) {
231+ if (key < 0 || key == TLS_OUT_OF_INDEXES ) {
219232 msg_error ("%s(%d): key(%d) invalid" , __FUNCTION__ , __LINE__ , key );
220233 return EINVAL ;
221234 }
222235
223- if (TlsSetValue (key , value )) {
224- return 0 ;
225- } else {
236+ FLS_KEY * fkey = (FLS_KEY * ) TlsGetValue (__tls_key );
237+ if (fkey == NULL ) {
238+ msg_error ("%s(%d): no FLS_KEY for __tls_key=%d" ,
239+ __FUNCTION__ , __LINE__ , __fls_key );
240+ return EINVAL ;
241+ }
242+
243+ char kbuf [32 ];
244+ hash_key (key , kbuf , sizeof (kbuf ));
245+
246+ TLS_KEY * tkey = (TLS_KEY * ) htable_find (fkey -> keys , kbuf );
247+ if (tkey == NULL ) {
248+ msg_error ("%s(%d): no TLS_KEY for key=%d, __tls_key=%d" ,
249+ __FUNCTION__ , __LINE__ , key , __tls_key );
250+ return EINVAL ;
251+ }
252+
253+ if (!TlsSetValue (key , value )) {
226254 msg_error ("%s(%d): TlsSetValue(key=%d) error(%s)" ,
227255 __FUNCTION__ , __LINE__ , key , last_serror ());
228256 return -1 ;
229257 }
258+
259+ tkey -> objs -> push_back (tkey -> objs , value );
260+ return 0 ;
230261}
231262
232263#endif /* USE_FLS */
0 commit comments