Skip to content

Commit de74163

Browse files
author
郑树新
committed
Fixed bugs in windows for pthread_xxx_ wrappers.
1 parent c3f86c3 commit de74163

10 files changed

Lines changed: 240 additions & 211 deletions

File tree

acl_cpp_vc2022.sln

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,63 +42,70 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fiber_cpp", "fiber_cpp", "{
4242
EndProject
4343
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "master_fiber", "lib_fiber\samples-c++\master_fiber\master_fiber_vc2022.vcxproj", "{3E725148-0807-4CBA-8FC1-7FCA46F605F3}"
4444
ProjectSection(ProjectDependencies) = postProject
45-
{F2479E2C-7267-436C-A1F1-A63B39E7CB30} = {F2479E2C-7267-436C-A1F1-A63B39E7CB30}
4645
{6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC} = {6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC}
4746
{AD99B75A-40BF-46DC-844B-23417FDC8690} = {AD99B75A-40BF-46DC-844B-23417FDC8690}
4847
{B40213C2-507C-4C7F-A6E1-B850C9BDC27B} = {B40213C2-507C-4C7F-A6E1-B850C9BDC27B}
48+
{F2479E2C-7267-436C-A1F1-A63B39E7CB30} = {F2479E2C-7267-436C-A1F1-A63B39E7CB30}
4949
{FE724EF7-3763-4E78-BDF5-BCBC075719FD} = {FE724EF7-3763-4E78-BDF5-BCBC075719FD}
5050
EndProjectSection
5151
EndProject
5252
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinFiber", "lib_fiber\samples-gui\WinFiber\WinFiber_vc2022.vcxproj", "{141DDEA4-DDEF-4D7E-9FE1-5FEFE0D95222}"
5353
ProjectSection(ProjectDependencies) = postProject
54-
{F2479E2C-7267-436C-A1F1-A63B39E7CB30} = {F2479E2C-7267-436C-A1F1-A63B39E7CB30}
5554
{6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC} = {6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC}
5655
{AD99B75A-40BF-46DC-844B-23417FDC8690} = {AD99B75A-40BF-46DC-844B-23417FDC8690}
5756
{B40213C2-507C-4C7F-A6E1-B850C9BDC27B} = {B40213C2-507C-4C7F-A6E1-B850C9BDC27B}
57+
{F2479E2C-7267-436C-A1F1-A63B39E7CB30} = {F2479E2C-7267-436C-A1F1-A63B39E7CB30}
5858
{FE724EF7-3763-4E78-BDF5-BCBC075719FD} = {FE724EF7-3763-4E78-BDF5-BCBC075719FD}
5959
EndProjectSection
6060
EndProject
6161
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fiber_gui", "fiber_gui", "{1CB30F2E-2587-43E7-A3CF-787783FB6924}"
6262
EndProject
6363
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HttpGet", "lib_fiber\samples-gui\HttpGet\HttpGet_vc2022.vcxproj", "{FE7E9F00-7F46-4072-8B29-A4E915259CDE}"
6464
ProjectSection(ProjectDependencies) = postProject
65-
{F2479E2C-7267-436C-A1F1-A63B39E7CB30} = {F2479E2C-7267-436C-A1F1-A63B39E7CB30}
6665
{6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC} = {6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC}
6766
{AD99B75A-40BF-46DC-844B-23417FDC8690} = {AD99B75A-40BF-46DC-844B-23417FDC8690}
6867
{B40213C2-507C-4C7F-A6E1-B850C9BDC27B} = {B40213C2-507C-4C7F-A6E1-B850C9BDC27B}
68+
{F2479E2C-7267-436C-A1F1-A63B39E7CB30} = {F2479E2C-7267-436C-A1F1-A63B39E7CB30}
6969
{FE724EF7-3763-4E78-BDF5-BCBC075719FD} = {FE724EF7-3763-4E78-BDF5-BCBC075719FD}
7070
EndProjectSection
7171
EndProject
7272
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EchoServer", "lib_fiber\samples-gui\EchoServer\EchoServer_vc2022.vcxproj", "{30A882E6-CF13-494F-9132-CE15E040B9DE}"
7373
ProjectSection(ProjectDependencies) = postProject
74-
{F2479E2C-7267-436C-A1F1-A63B39E7CB30} = {F2479E2C-7267-436C-A1F1-A63B39E7CB30}
7574
{6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC} = {6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC}
7675
{AD99B75A-40BF-46DC-844B-23417FDC8690} = {AD99B75A-40BF-46DC-844B-23417FDC8690}
7776
{B40213C2-507C-4C7F-A6E1-B850C9BDC27B} = {B40213C2-507C-4C7F-A6E1-B850C9BDC27B}
77+
{F2479E2C-7267-436C-A1F1-A63B39E7CB30} = {F2479E2C-7267-436C-A1F1-A63B39E7CB30}
7878
{FE724EF7-3763-4E78-BDF5-BCBC075719FD} = {FE724EF7-3763-4E78-BDF5-BCBC075719FD}
7979
EndProjectSection
8080
EndProject
8181
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client", "lib_fiber\samples-c++1x\client\client_vc2022.vcxproj", "{2F80A939-E4BD-4ED7-B512-95FC2B563036}"
8282
ProjectSection(ProjectDependencies) = postProject
83-
{F2479E2C-7267-436C-A1F1-A63B39E7CB30} = {F2479E2C-7267-436C-A1F1-A63B39E7CB30}
8483
{6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC} = {6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC}
8584
{AD99B75A-40BF-46DC-844B-23417FDC8690} = {AD99B75A-40BF-46DC-844B-23417FDC8690}
8685
{B40213C2-507C-4C7F-A6E1-B850C9BDC27B} = {B40213C2-507C-4C7F-A6E1-B850C9BDC27B}
86+
{F2479E2C-7267-436C-A1F1-A63B39E7CB30} = {F2479E2C-7267-436C-A1F1-A63B39E7CB30}
8787
{FE724EF7-3763-4E78-BDF5-BCBC075719FD} = {FE724EF7-3763-4E78-BDF5-BCBC075719FD}
8888
EndProjectSection
8989
EndProject
9090
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server-threads", "lib_fiber\samples-c++1x\server-threads\server-threads_vc2022.vcxproj", "{EE518BE5-94B2-4F8E-82CC-C08503BBD6B3}"
9191
ProjectSection(ProjectDependencies) = postProject
92-
{F2479E2C-7267-436C-A1F1-A63B39E7CB30} = {F2479E2C-7267-436C-A1F1-A63B39E7CB30}
9392
{6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC} = {6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC}
9493
{AD99B75A-40BF-46DC-844B-23417FDC8690} = {AD99B75A-40BF-46DC-844B-23417FDC8690}
9594
{B40213C2-507C-4C7F-A6E1-B850C9BDC27B} = {B40213C2-507C-4C7F-A6E1-B850C9BDC27B}
95+
{F2479E2C-7267-436C-A1F1-A63B39E7CB30} = {F2479E2C-7267-436C-A1F1-A63B39E7CB30}
9696
{FE724EF7-3763-4E78-BDF5-BCBC075719FD} = {FE724EF7-3763-4E78-BDF5-BCBC075719FD}
9797
EndProjectSection
9898
EndProject
9999
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "httpd", "lib_fiber\samples-c++1x\httpd\httpd_vc2022.vcxproj", "{2F80A939-E4BD-4ED7-B512-95FC2B563009}"
100100
EndProject
101101
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "httpc", "lib_fiber\samples-c++1x\httpc\httpc_vc2022.vcxproj", "{2F80A939-E4BD-4ED7-B512-95FC2B563099}"
102+
ProjectSection(ProjectDependencies) = postProject
103+
{6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC} = {6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC}
104+
{AD99B75A-40BF-46DC-844B-23417FDC8690} = {AD99B75A-40BF-46DC-844B-23417FDC8690}
105+
{B40213C2-507C-4C7F-A6E1-B850C9BDC27B} = {B40213C2-507C-4C7F-A6E1-B850C9BDC27B}
106+
{F2479E2C-7267-436C-A1F1-A63B39E7CB30} = {F2479E2C-7267-436C-A1F1-A63B39E7CB30}
107+
{FE724EF7-3763-4E78-BDF5-BCBC075719FD} = {FE724EF7-3763-4E78-BDF5-BCBC075719FD}
108+
EndProjectSection
102109
EndProject
103110
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "redis_list", "lib_acl_cpp\samples\redis\redis_list\redis_list_vc2022.vcxproj", "{1D669177-07FD-4DDD-A13E-52A7DF19CA62}"
104111
EndProject

lib_fiber/c/src/common/pthread_patch.c

Lines changed: 133 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -7,108 +7,74 @@
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+
11278
int 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+
155172
int 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

182216
int 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 */
228235
int pthread_mutex_destroy(pthread_mutex_t *mutex)
229236
{

0 commit comments

Comments
 (0)