77
88#ifdef SYS_WIN
99
10- typedef struct {
11- pthread_key_t key ;
12- void (* destructor )(void * );
13- } TLS_KEY ;
10+ //#define USE_FLS
1411
15- typedef struct {
16- TLS_KEY * tls_key ;
17- void * value ;
18- } TLS_VALUE ;
12+ #ifdef USE_FLS
1913
20- static int __thread_inited = 0 ;
21- static TLS_KEY __tls_key_list [PTHREAD_KEYS_MAX ];
22- static pthread_mutex_t __thread_lock ;
23- static pthread_key_t __tls_value_list_key = TLS_OUT_OF_INDEXES ;
24- static pthread_once_t __create_thread_control_once = PTHREAD_ONCE_INIT ;
14+ //#define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
2515
26- static void tls_value_list_free (void );
16+ typedef struct OnceWrapper
17+ {
18+ void (* init_routine )(void );
19+ } OnceWrapper ;
2720
28- void pthread_end (void )
21+ BOOL CALLBACK InitOnceCallback (
22+ PINIT_ONCE InitOnce ,
23+ PVOID Parameter ,
24+ PVOID * Context )
2925{
30- static int __thread_ended = 0 ;
31- int i ;
32-
33- if (__thread_ended )
34- return ;
35-
36- tls_value_list_free ();
37- __thread_ended = 1 ;
38- pthread_mutex_destroy (& __thread_lock );
39-
40- for (i = 0 ; i < PTHREAD_KEYS_MAX ; i ++ ) {
41- if (__tls_key_list [i ].key >= 0
42- && __tls_key_list [i ].key < PTHREAD_KEYS_MAX )
43- {
44- TlsFree (__tls_key_list [i ].key );
45- __tls_key_list [i ].key = TLS_OUT_OF_INDEXES ;
46- }
47- __tls_key_list [i ].destructor = NULL ;
48- }
26+ OnceWrapper * wrapper = (OnceWrapper * )Parameter ;
27+ wrapper -> init_routine ();
28+ return TRUE;
4929}
5030
51- /* 每个进程的唯一初始化函数 */
52-
53- static void pthread_init_once (void )
31+ int pthread_once (pthread_once_t * once_control , void (* init_routine )(void ))
5432{
55- const char * myname = "pthread_init_once" ;
56- int i ;
57-
58- pthread_mutex_init (& __thread_lock , NULL );
59- __thread_inited = 1 ;
60-
61- for (i = 0 ; i < PTHREAD_KEYS_MAX ; i ++ ) {
62- __tls_key_list [i ].destructor = NULL ;
63- __tls_key_list [i ].key = TLS_OUT_OF_INDEXES ;
64- }
33+ OnceWrapper wrapper ;
34+ wrapper .init_routine = init_routine ;
6535
66- __tls_value_list_key = TlsAlloc ();
67- if (__tls_value_list_key == TLS_OUT_OF_INDEXES )
68- msg_fatal ("%s(%d): TlsAlloc error(%s)" ,
69- myname , __LINE__ , last_serror ());
70- if (__tls_value_list_key < 0
71- || __tls_value_list_key >= PTHREAD_KEYS_MAX )
72- {
73- msg_fatal ("%s(%d): TlsAlloc error(%s), not in(%d, %d)" ,
74- myname , __LINE__ , last_serror (),
75- 0 , PTHREAD_KEYS_MAX );
76- }
36+ BOOL ok = InitOnceExecuteOnce (
37+ once_control ,
38+ InitOnceCallback ,
39+ & wrapper ,
40+ NULL );
7741
78- __tls_key_list [__tls_value_list_key ].destructor = NULL ;
79- __tls_key_list [__tls_value_list_key ].key = __tls_value_list_key ;
42+ return ok ? 0 : -1 ;
8043}
8144
82- /* 获得线程局部变量链表 */
83-
84- static FIFO * tls_value_list_get (void )
45+ int pthread_key_create (pthread_key_t * key , void (* destructor )(void * ))
8546{
86- FIFO * tls_value_list_ptr ;
47+ if (!key )
48+ return -1 ;
8749
88- tls_value_list_ptr = (FIFO * ) TlsGetValue (__tls_value_list_key );
89- if (tls_value_list_ptr == NULL ) {
90- tls_value_list_ptr = fifo_new ();
91- TlsSetValue (__tls_value_list_key , tls_value_list_ptr );
92- }
93- return tls_value_list_ptr ;
50+ DWORD k = FlsAlloc ((PFLS_CALLBACK_FUNCTION )destructor );
51+
52+ if (k == FLS_OUT_OF_INDEXES )
53+ return -1 ;
54+
55+ * key = k ;
56+ return 0 ;
9457}
9558
96- static void tls_value_list_on_free ( void * ctx )
59+ int pthread_setspecific ( pthread_key_t key , const void * value )
9760{
98- mem_free ( ctx ) ;
61+ return FlsSetValue ( key , ( PVOID ) value ) ? 0 : -1 ;
9962}
10063
101- static void tls_value_list_free ( void )
64+ void * pthread_getspecific ( pthread_key_t key )
10265{
103- FIFO * tls_value_list_ptr ;
66+ return FlsGetValue (key );
67+ }
10468
105- tls_value_list_ptr = (FIFO * ) TlsGetValue (__tls_value_list_key );
106- if (tls_value_list_ptr != NULL ) {
107- TlsSetValue (__tls_value_list_key , NULL );
108- fifo_free (tls_value_list_ptr , tls_value_list_on_free );
109- }
69+ int pthread_key_delete (pthread_key_t key )
70+ {
71+ return FlsFree (key ) ? 0 : -1 ;
11072}
11173
74+ #else
75+
76+ static pthread_once_t __control_once = PTHREAD_ONCE_INIT ;
77+
11278int pthread_once (pthread_once_t * once_control , void (* init_routine )(void ))
11379{
11480 int n = 0 ;
@@ -152,25 +118,93 @@ int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
152118 return 1 ; /* 不可达代码,避免编译器报警告 */
153119}
154120
121+ ///////////////////////////////////////////////////////////////////////////////
122+
123+ typedef struct {
124+ pthread_key_t tkey ;
125+ void (* destructor )(void * );
126+ FIFO * keys ;
127+ } TLS_KEY ;
128+
129+ static pthread_key_t __tls_key = TLS_OUT_OF_INDEXES ;
130+ static pthread_key_t __fls_key = FLS_OUT_OF_INDEXES ;
131+
132+ extern int acl_fiber_scheduled (void );
133+
134+ static void thread_exit (void * ctx )
135+ {
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+ }
152+
153+ destructor = tkey -> destructor ;
154+ context = TlsGetValue (tkey -> tkey );
155+
156+ fifo_free (tkey -> keys , mem_free );
157+ mem_free (tkey );
158+
159+ if (destructor ) {
160+ destructor (context );
161+ }
162+ }
163+
164+ /* 每个进程的唯一初始化函数 */
165+
166+ static void pthread_init_once (void )
167+ {
168+ __tls_key = TlsAlloc ();
169+ __fls_key = FlsAlloc (thread_exit );
170+ }
171+
155172int pthread_key_create (pthread_key_t * key_ptr , void (* destructor )(void * ))
156173{
157- const char * myname = "pthread_key_create" ;
158-
159- pthread_once (& __create_thread_control_once , pthread_init_once );
160-
161- * key_ptr = TlsAlloc ();
162- if (* key_ptr == TLS_OUT_OF_INDEXES ) {
163- return ENOMEM ;
164- } else if (* key_ptr >= PTHREAD_KEYS_MAX ) {
165- msg_error ("%s(%d): key(%d) > PTHREAD_KEYS_MAX(%d)" ,
166- myname , __LINE__ , * key_ptr , PTHREAD_KEYS_MAX );
167- TlsFree (* key_ptr );
168- * key_ptr = TLS_OUT_OF_INDEXES ;
169- return ENOMEM ;
174+ pthread_once (& __control_once , pthread_init_once );
175+
176+ if (* key_ptr <= 0 && * key_ptr != TLS_OUT_OF_INDEXES ) {
177+ * key_ptr = TlsAlloc ();
178+ assert (* key_ptr != TLS_OUT_OF_INDEXES );
179+ }
180+
181+ TLS_KEY * tkey = (TLS_KEY * ) mem_calloc (sizeof (TLS_KEY ), 1 ), * curr ;
182+ tkey -> tkey = * key_ptr ;
183+ tkey -> destructor = destructor ;
184+
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__ );
200+ }
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 );
170206 }
171207
172- __tls_key_list [* key_ptr ].destructor = destructor ;
173- __tls_key_list [* key_ptr ].key = * key_ptr ;
174208 return 0 ;
175209}
176210
@@ -181,49 +215,22 @@ void *pthread_getspecific(pthread_key_t key)
181215
182216int pthread_setspecific (pthread_key_t key , void * value )
183217{
184- const char * myname = "pthread_setspecific" ;
185- FIFO * tls_value_list_ptr = tls_value_list_get ();
186- //ITER iter;
187-
188- if (key < 0 || key >= PTHREAD_KEYS_MAX ) {
189- msg_error ("%s(%d): key(%d) invalid" , myname , __LINE__ , key );
190- return EINVAL ;
191- }
192- if (__tls_key_list [key ].key != key ) {
193- msg_error ("%s(%d): __tls_key_list[%d].key(%d) != key(%d)" ,
194- myname , __LINE__ , key , __tls_key_list [key ].key , key );
218+ if (key <= 0 || key == TLS_OUT_OF_INDEXES ) {
219+ msg_error ("%s(%d): key(%d) invalid" , __FUNCTION__ , __LINE__ , key );
195220 return EINVAL ;
196221 }
197222
198- #if 0
199- foreach (iter , tls_value_list_ptr ) {
200- TLS_VALUE * tls_value = (TLS_VALUE * ) iter .data ;
201- if (tls_value -> tls_key != NULL
202- && tls_value -> tls_key -> key == key ) {
203-
204- /* 如果相同的键存在则需要先释放旧数据 */
205- if (tls_value -> tls_key -> destructor && tls_value -> value )
206- tls_value -> tls_key -> destructor (tls_value -> value );
207- tls_value -> tls_key = NULL ;
208- tls_value -> value = NULL ;
209- break ;
210- }
211- }
212- #endif
213-
214223 if (TlsSetValue (key , value )) {
215- TLS_VALUE * tls_value = (TLS_VALUE * ) mem_malloc (sizeof (TLS_VALUE ));
216- tls_value -> tls_key = & __tls_key_list [key ];
217- tls_value -> value = value ;
218- fifo_push (tls_value_list_ptr , tls_value );
219224 return 0 ;
220225 } else {
221226 msg_error ("%s(%d): TlsSetValue(key=%d) error(%s)" ,
222- myname , __LINE__ , key , last_serror ());
227+ __FUNCTION__ , __LINE__ , key , last_serror ());
223228 return -1 ;
224229 }
225230}
226231
232+ #endif /* USE_FLS */
233+
227234/* Free the mutex */
228235int pthread_mutex_destroy (pthread_mutex_t * mutex )
229236{
0 commit comments