Skip to content

Commit cf0dfcc

Browse files
author
zhengshuxin
committed
Fixed bugs for fiber_mutex and fiber_cond module that the FILE_EVENT maybe freed when using it.
1 parent b77010f commit cf0dfcc

File tree

7 files changed

+125
-6
lines changed

7 files changed

+125
-6
lines changed

lib_fiber/c/src/fiber_io.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -863,8 +863,16 @@ FILE_EVENT *fiber_file_cache_get(socket_t fd)
863863

864864
void fiber_file_cache_put(FILE_EVENT *fe)
865865
{
866-
fiber_file_del(fe, fe->fd);
867-
fe->fd = INVALID_SOCKET;
866+
// If the fe is being refered by more than one fibers, don't put it
867+
// back to cache or free it, because the fe is still aliving now.
868+
if (fe->refer > 1) {
869+
return;
870+
}
871+
872+
if (fe->fd != INVALID_SOCKET) {
873+
fiber_file_del(fe, fe->fd);
874+
fe->fd = INVALID_SOCKET;
875+
}
868876

869877
if (array_size(__thread_fiber->cache) < __thread_fiber->cache_max) {
870878
if (!(fe->status & STATUS_BUFFED)) {

lib_fiber/c/src/sync/sync_timer.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,8 @@ void sync_timer_wakeup(SYNC_TIMER *timer, SYNC_OBJ *obj)
179179
fe->mbox_wsem = acl_fiber_sem_create(1);
180180
}
181181
} else if (fe->mbox_wsem == NULL) {
182-
msg_fatal("%s(%d): fe's mbox_wsem NULL, out=%d",
183-
__FUNCTION__, __LINE__, (int) out);
182+
msg_fatal("%s(%d): mbox_wsem NULL, out=%d, fd=%d, refer=%d",
183+
__FUNCTION__, __LINE__, (int) out, fe->fd, fe->refer);
184184
}
185185

186186
file_event_refer(fe);
@@ -190,11 +190,29 @@ void sync_timer_wakeup(SYNC_TIMER *timer, SYNC_OBJ *obj)
190190
acl_fiber_sem_wait(fe->mbox_wsem);
191191

192192
fe->mask |= EVENT_SYSIO;
193+
194+
// The fe maybe be used again in mbox_send->acl_fiber_write
195+
// ->fiber_file_open->fiber_file_get.
193196
mbox_send(timer->box, msg);
194197

198+
#ifdef DEBUG
199+
FILE_EVENT *f = fiber_file_get(out);
200+
if (f == NULL) {
201+
msg_fatal("%s(%d): fiber_file_get NULL, fe=%p, out=%d",
202+
__FUNCTION__, __LINE__, fe, out);
203+
} else if (f->mbox_wsem == NULL) {
204+
msg_fatal("%s(%d): mbox_wsem NULL, f=%p, fe=%p, out=%d",
205+
__FUNCTION__, __LINE__, f, fe, out);
206+
} else if (f != fe) {
207+
msg_fatal("%s(%d): invalid f=%p, fe=%p, out=%d",
208+
__FUNCTION__, __LINE__, f, fe, out);
209+
}
210+
#endif
211+
195212
if (acl_fiber_sem_post(fe->mbox_wsem) == 1) {
196213
fiber_file_cache_put(fe);
197214
}
215+
198216
file_event_unrefer(fe);
199217
} else {
200218
// If the current notifier is a fiber in the same thread with

lib_fiber/c/src/sync/sync_waiter.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ void sync_waiter_wakeup(SYNC_WAITER *waiter, ACL_FIBER *fb)
124124
fe->mbox_wsem = acl_fiber_sem_create(1);
125125
}
126126
} else if (fe->mbox_wsem == NULL) {
127-
msg_fatal("%s(%d): fe's mbox_wsem NULL, out=%d",
128-
__FUNCTION__, __LINE__, (int) out);
127+
msg_fatal("%s(%d): mbox_wsem NULL, out=%d, fd=%d, refer=%d",
128+
__FUNCTION__, __LINE__, (int) out, fe->fd, fe->refer);
129129
}
130130

131131
file_event_refer(fe);
@@ -139,10 +139,25 @@ void sync_waiter_wakeup(SYNC_WAITER *waiter, ACL_FIBER *fb)
139139
// ->fiber_file_open->fiber_file_get.
140140
mbox_send(waiter->box, fb);
141141

142+
#ifdef DEBUG
143+
FILE_EVENT *f = fiber_file_get(out);
144+
if (f == NULL) {
145+
msg_fatal("%s(%d): fiber_file_get NULL, fe=%p, out=%d",
146+
__FUNCTION__, __LINE__, fe, out);
147+
} else if (f->mbox_wsem == NULL) {
148+
msg_fatal("%s(%d): mbox_wsem NULL, f=%p, fe=%p, out=%d",
149+
__FUNCTION__, __LINE__, f, fe, out);
150+
} else if (f != fe) {
151+
msg_fatal("%s(%d): invalid f=%p, fe=%p, out=%d",
152+
__FUNCTION__, __LINE__, f, fe, out);
153+
}
154+
#endif
155+
142156
// If no other fiber is suspended by the sem, then release it.
143157
if (acl_fiber_sem_post(fe->mbox_wsem) == 1) {
144158
fiber_file_cache_put(fe);
145159
}
160+
146161
file_event_unrefer(fe);
147162
} else {
148163
// If the current notifier is a fiber in the same thread with
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
include ../Makefile_cpp.in
2+
CFLAGS += -std=c++11
3+
PROG = fiber_mutex
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include "stdafx.h"
2+
#include <vector>
3+
#include <thread>
4+
#include <iostream>
5+
6+
int main() {
7+
std::vector<std::thread*> threads;
8+
std::vector<acl::fiber_mutex*> locks;
9+
std::vector<long long*> cnts;
10+
size_t number = 2;
11+
12+
for (size_t i = 0; i < number; i++) {
13+
auto* lock = new acl::fiber_mutex;
14+
locks.push_back(lock);
15+
auto* cnt = new long long;
16+
*cnt = 0;
17+
cnts.push_back(cnt);
18+
}
19+
20+
acl::fiber::stdout_open(true);
21+
22+
for (size_t i = 0; i < 10; i++) {
23+
auto* thr = new std::thread([&] {
24+
for (size_t j = 0; j < 100; j++) {
25+
go[&] {
26+
acl::fiber::delay(5);
27+
for (size_t m = 0; m < 100; m++) {
28+
size_t k = m % number;
29+
locks[k]->lock();
30+
*cnts[k] += 1;
31+
acl::fiber::yield();
32+
locks[k]->unlock();
33+
}
34+
};
35+
}
36+
37+
acl::fiber::schedule();
38+
});
39+
threads.push_back(thr);
40+
}
41+
42+
for (auto it : threads) {
43+
it->join();
44+
delete it;
45+
}
46+
47+
for (size_t i = 0; i < number; i++) {
48+
printf("cnts[%zd]=%lld\r\n", i, *cnts[i]);
49+
delete cnts[i];
50+
delete locks[i];
51+
}
52+
53+
printf("All over!\r\n");
54+
return 0;
55+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "stdafx.h"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// stdafx.h : 标准系统包含文件的包含文件,
2+
// 或是常用但不常更改的项目特定的包含文件
3+
//
4+
5+
#pragma once
6+
7+
8+
// TODO: 在此处引用程序要求的附加头文件
9+
10+
#include "lib_acl.h"
11+
#include "acl_cpp/lib_acl.hpp"
12+
#include "fiber/libfiber.hpp"
13+
14+
#include "fiber/go_fiber.hpp"
15+
16+
#ifdef WIN32
17+
#define snprintf _snprintf
18+
#endif
19+

0 commit comments

Comments
 (0)