Skip to content

Commit 2feb0e1

Browse files
zhengshuxinzhengshuxin
authored andcommitted
Merge from acl/libfiber.
1 parent 4341b52 commit 2feb0e1

25 files changed

+699
-400
lines changed

c/include/fiber/fiber_sem.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ typedef struct ACL_FIBER_SEM ACL_FIBER_SEM;
2121
FIBER_API ACL_FIBER_SEM* acl_fiber_sem_create2(int num, unsigned flags);
2222
#define ACL_FIBER_SEM_F_ASYNC (1 << 0) /* If notifying in async mode */
2323

24+
/**
25+
* Create one fiber semaphore with the specified buff count and flags.
26+
* @param num {int} the initial value of the semaphore, must >= 0
27+
* @param buf {int} the buffed count before signal the waiters.
28+
* @param flags {unsigned} the flags defined as ACL_FIBER_SEM_F_XXX
29+
*/
30+
FIBER_API ACL_FIBER_SEM* acl_fiber_sem_create3(int num, int buf, unsigned flags);
31+
2432
FIBER_API ACL_FIBER_SEM* acl_fiber_sem_create(int num);
2533

2634
/**
@@ -65,9 +73,17 @@ FIBER_API int acl_fiber_sem_wait(ACL_FIBER_SEM* sem);
6573
*/
6674
FIBER_API int acl_fiber_sem_trywait(ACL_FIBER_SEM* sem);
6775

76+
/**
77+
* Wait for semaphore until > 0 or the timer arriving.
78+
* @param sem {ACL_FIBER_SEM *} created by acl_fiber_sem_create
79+
* @param milliseconds {int} specify the timeout to wait
80+
* @return {int} return >= 0 if waiting successfully, or -1 if waiting timed out.
81+
*/
82+
FIBER_API int acl_fiber_sem_timed_wait(ACL_FIBER_SEM *sem, int milliseconds);
83+
6884
/**
6985
* Add 1 to the semaphore, if there are other fibers waiting for semaphore,
70-
* one waiter will be wakeuped
86+
* one waiter will be wakeup
7187
* @param sem {ACL_FIBER_SEM *} created by acl_fiber_sem_create
7288
* @return {int} the current semaphore value returned, -1 returned if the
7389
* current thread ID is not same as the semaphore's owner ID

c/src/fiber.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ struct SYNC_WAITER;
3535
struct ACL_FIBER {
3636
FIBER_BASE *base;
3737
RING me;
38+
RING me2;
3839
long tid;
3940
unsigned fid;
4041
unsigned slot;

c/src/sync/fiber_cond.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ static int fiber_cond_timedwait(ACL_FIBER_COND *cond, ACL_FIBER_MUTEX *mutex,
159159
UNLOCK_COND(cond);
160160

161161
if (fiber->flag & FIBER_F_TIMER) {
162+
acl_fiber_set_errno(fiber, FIBER_EAGAIN);
163+
acl_fiber_set_error(FIBER_EAGAIN);
162164
// The obj has been deleted in sync_timer.c when timeout.
163165
fiber->flag &= ~FIBER_F_TIMER;
164166
sync_obj_unrefer(obj);

c/src/sync/fiber_sem.c

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
struct ACL_FIBER_SEM {
88
int num;
9+
int buf;
910
unsigned flags;
1011
RING waiting;
1112
unsigned long tid;
@@ -17,11 +18,18 @@ ACL_FIBER_SEM *acl_fiber_sem_create(int num)
1718
}
1819

1920
ACL_FIBER_SEM *acl_fiber_sem_create2(int num, unsigned flags)
21+
{
22+
int buf = (flags & ACL_FIBER_SEM_F_ASYNC) ? 50000000 : 0;
23+
return acl_fiber_sem_create3(num, buf, flags);
24+
}
25+
26+
ACL_FIBER_SEM *acl_fiber_sem_create3(int num, int buf, unsigned flags)
2027
{
2128
ACL_FIBER_SEM *sem = (ACL_FIBER_SEM *) mem_malloc(sizeof(ACL_FIBER_SEM));
2229

2330
sem->tid = 0;
2431
sem->num = num;
32+
sem->buf = buf;
2533
sem->flags = flags;
2634
ring_init(&sem->waiting);
2735
return sem;
@@ -58,21 +66,14 @@ int acl_fiber_sem_waiters_num(ACL_FIBER_SEM *sem)
5866
return ring_size(&sem->waiting);
5967
}
6068

61-
int acl_fiber_sem_wait(ACL_FIBER_SEM *sem)
69+
int acl_fiber_sem_timed_wait(ACL_FIBER_SEM *sem, int milliseconds)
6270
{
6371
ACL_FIBER *curr;
6472
EVENT *ev;
6573

6674
if (sem->tid == 0) {
6775
sem->tid = thread_self();
6876
}
69-
#if 0
70-
else if (sem->tid != (unsigned long) thread_self()) {
71-
msg_error("%s(%d): current tid=%lu, sem tid=%lu",
72-
__FUNCTION__, __LINE__, thread_self(), sem->tid);
73-
return -1;
74-
}
75-
#endif
7677

7778
if (sem->num > 0) {
7879
sem->num--;
@@ -84,35 +85,55 @@ int acl_fiber_sem_wait(ACL_FIBER_SEM *sem)
8485
return -1;
8586
}
8687

87-
// Sanity check befor suspending.
88+
if (milliseconds == 0) {
89+
acl_fiber_set_errno(curr, FIBER_EAGAIN);
90+
acl_fiber_set_error(FIBER_EAGAIN);
91+
return -1;
92+
}
93+
94+
// Sanity check before suspending.
8895
if (acl_fiber_canceled(curr)) {
8996
acl_fiber_set_error(curr->errnum);
90-
//msg_info("%s(%d): fiber-%d be killed",
91-
// __FUNCTION__, __LINE__, acl_fiber_id(curr));
9297
return -1;
9398
}
9499

95-
ring_prepend(&sem->waiting, &curr->me);
100+
ring_prepend(&sem->waiting, &curr->me2);
96101

97102
curr->wstatus |= FIBER_WAIT_SEM;
98103

104+
if (milliseconds > 0) {
105+
fiber_timer_add(curr, (size_t) milliseconds);
106+
}
107+
108+
// Make sure to start wakeup_timers in fiber_io.c by the following:
109+
// fiber_io_event -> fiber_io_check -> fiber_io_loop -> wakeup_timers.
99110
ev = fiber_io_event();
100111
WAITER_INC(ev); // Just for avoiding fiber_io_loop to exit
101112
acl_fiber_switch();
102113
WAITER_DEC(ev);
103114

115+
if (milliseconds > 0) {
116+
fiber_timer_del(curr);
117+
}
118+
104119
curr->wstatus &= ~FIBER_WAIT_SEM;
105120

106121
/* If switch to me because other killed me, I should detach myself;
107-
* else if because other unlock, I'll be detached twice which is
108-
* hamless because RIGN can deal with it.
122+
* else if because other unlock, I'll be detached twice which is
123+
* harmless because RING can deal with it.
109124
*/
110125
ring_detach(&curr->me);
126+
ring_detach(&curr->me2);
111127

112128
if (acl_fiber_canceled(curr)) {
113129
acl_fiber_set_error(curr->errnum);
114-
//msg_info("%s(%d): fiber-%d be killed",
115-
// __FUNCTION__, __LINE__, acl_fiber_id(curr));
130+
return -1;
131+
} else if (curr->flag & FIBER_F_TIMER) {
132+
// Clear FIBER_F_TIMER flag been set in wakeup_timers.
133+
curr->flag &= ~FIBER_F_TIMER;
134+
135+
acl_fiber_set_errno(curr, FIBER_EAGAIN);
136+
acl_fiber_set_error(FIBER_EAGAIN);
116137
return -1;
117138
}
118139

@@ -122,18 +143,16 @@ int acl_fiber_sem_wait(ACL_FIBER_SEM *sem)
122143
return sem->num;
123144
}
124145

146+
int acl_fiber_sem_wait(ACL_FIBER_SEM *sem)
147+
{
148+
return acl_fiber_sem_timed_wait(sem, -1);
149+
}
150+
125151
int acl_fiber_sem_trywait(ACL_FIBER_SEM *sem)
126152
{
127153
if (sem->tid == 0) {
128154
sem->tid = thread_self();
129155
}
130-
#if 0
131-
else if (sem->tid != thread_self()) {
132-
msg_error("%s(%d): current tid=%lu, sem tid=%lu",
133-
__FUNCTION__, __LINE__, thread_self(), sem->tid);
134-
return -1;
135-
}
136-
#endif
137156

138157
if (sem->num > 0) {
139158
sem->num--;
@@ -144,7 +163,7 @@ int acl_fiber_sem_trywait(ACL_FIBER_SEM *sem)
144163
}
145164

146165
#define RING_TO_FIBER(r) \
147-
((ACL_FIBER *) ((char *) (r) - offsetof(ACL_FIBER, me)))
166+
((ACL_FIBER *) ((char *) (r) - offsetof(ACL_FIBER, me2)))
148167

149168
#define FIRST_FIBER(head) \
150169
(ring_succ(head) != (head) ? RING_TO_FIBER(ring_succ(head)) : 0)
@@ -168,16 +187,19 @@ int acl_fiber_sem_post(ACL_FIBER_SEM *sem)
168187
sem->num++;
169188

170189
if ((ready = FIRST_FIBER(&sem->waiting)) == NULL) {
190+
if (sem->num >= sem->buf) {
191+
acl_fiber_yield();
192+
}
171193
return sem->num;
172194
}
173195

174-
ring_detach(&ready->me);
196+
ring_detach(&ready->me2);
175197
FIBER_READY(ready);
176198

177199
/* Help the fiber to be wakeup to decrease the sem number. */
178200
num = sem->num--;
179201

180-
if (!(sem->flags & ACL_FIBER_SEM_F_ASYNC)) {
202+
if (num >= sem->buf) {
181203
acl_fiber_yield();
182204
}
183205

cpp/include/fiber/channel.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#pragma once
1+
#pragma once
22

33
#include "fiber_cpp_define.hpp"
44

@@ -14,11 +14,11 @@ int channel_recv(ACL_CHANNEL *c, void *v);
1414
template <typename T>
1515
class channel {
1616
public:
17-
channel(void) {
17+
channel() {
1818
chan_ = channel_create(sizeof(T), 100);
1919
}
2020

21-
~channel(void) {
21+
~channel() {
2222
channel_free(chan_);
2323
}
2424

0 commit comments

Comments
 (0)