Skip to content

Commit 2486695

Browse files
committed
Fixed one bug in fiber_mutex module where some resouce collision maybe happen.
1 parent 3b4c518 commit 2486695

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

lib_fiber/c/src/event.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,11 @@ struct FILE_EVENT {
294294
struct __kernel_timespec wts;
295295
int r_timeout;
296296
int w_timeout;
297+
297298
#endif
298299

300+
ACL_FIBER_SEM* mbox_wsem; // Used in sync_waiter_wakeup.c
301+
299302
#ifdef HAS_IOCP
300303
char packet[512]; // Just for UDP packet
301304
char *rbuf;

lib_fiber/c/src/file_event.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ FILE_EVENT *file_event_alloc(socket_t fd)
5959

6060
static void file_event_free(FILE_EVENT *fe)
6161
{
62+
if (fe->mbox_wsem) {
63+
acl_fiber_sem_free(fe->mbox_wsem);
64+
}
65+
6266
memset(fe, 0, sizeof(*fe));
6367
mem_free(fe);
6468
}

lib_fiber/c/src/sync/sync_waiter.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,40 @@ void sync_waiter_wakeup(SYNC_WAITER *waiter, ACL_FIBER *fb)
102102
// to send data, because the fd is shared by multiple threads
103103
// and which can't use io_uring directly, so we set the mask
104104
// as EVENT_SYSIO to use system write API.
105+
105106
socket_t out = mbox_out(waiter->box);
106-
FILE_EVENT *fe = fiber_file_cache_get(out);
107+
108+
// If the FILE_EVENT got from fiber_file_get() isn't NULL,
109+
// there must be one fiber suspended due to write waiting
110+
// with the waiter->box fd. And the current fiber must
111+
// wait for the previous fiber to return and release the sem.
112+
113+
FILE_EVENT *fe = fiber_file_get(out);
114+
115+
if (fe == NULL) {
116+
fe = fiber_file_cache_get(out);
117+
// COW(Copy on write) to avoid unnecessary waste:
118+
// alloc sem binding the fe if necessary.
119+
if (fe->mbox_wsem == NULL) {
120+
fe->mbox_wsem = acl_fiber_sem_create(1);
121+
}
122+
} else {
123+
assert(fe->mbox_wsem);
124+
}
125+
126+
// Reduce the sem number and maybe be suspended if sem is 0.
127+
acl_fiber_sem_wait(fe->mbox_wsem);
107128

108129
fe->mask |= EVENT_SYSIO;
109130

131+
// The fe mabye be used again in mbox_send->acl_fiber_write
132+
// ->fiber_file_open_write->fiber_file_get.
110133
mbox_send(waiter->box, fb);
111-
fiber_file_cache_put(fe);
134+
135+
// If no other fiber is suspended by the sem, then release it.
136+
if (acl_fiber_sem_post(fe->mbox_wsem) == 1) {
137+
fiber_file_cache_put(fe);
138+
}
112139
} else {
113140
mbox_send(waiter->box, fb);
114141
}

0 commit comments

Comments
 (0)