optimize and test fiber_cond

This commit is contained in:
zhengshuxin 2022-11-21 11:51:31 +08:00
parent 96b6a74fbe
commit da61f288ae
3 changed files with 29 additions and 12 deletions

View File

@ -693,16 +693,10 @@ void fiber_file_close(FILE_EVENT *fe)
FILE_EVENT *fiber_file_cache_get(socket_t fd)
{
FILE_EVENT *fe;
int exist = 0;
fiber_io_check();
fe = fiber_file_get(fd);
if (fe == NULL) {
fe = (FILE_EVENT*) array_pop_back(__thread_fiber->cache);
} else { // Why? the fe wasn't removed by fiber_file_cache_put ?
exist = 1;
}
fe = (FILE_EVENT*) array_pop_back(__thread_fiber->cache);
if (fe == NULL) {
fe = file_event_alloc(fd);
} else {
@ -714,9 +708,7 @@ FILE_EVENT *fiber_file_cache_get(socket_t fd)
fe->mask |= EVENT_DIRECT;
}
#endif
if (!exist) {
fiber_file_set(fe);
}
fiber_file_set(fe);
return fe;
}

View File

@ -119,6 +119,9 @@ static int fiber_cond_timedwait(ACL_FIBER_COND *cond, ACL_FIBER_MUTEX *mutex,
static int thread_cond_timedwait(ACL_FIBER_COND *cond, ACL_FIBER_MUTEX *mutex,
int delay)
{
// Create one waiting object with the one reference added, which can
// be used by multiple threads, and will be released really when its
// refernece is zero.
SYNC_OBJ *obj = sync_obj_alloc(1);
obj->type = SYNC_OBJ_T_THREAD;
@ -206,20 +209,35 @@ int acl_fiber_cond_signal(ACL_FIBER_COND *cond)
UNLOCK_COND(cond);
// If the waiter is a fiber, we should use sync_timer_wakeup() to
// notify the fiber, or if it's a thread, we should use the
// fbase_event_wakeup() to notify it.
// That is to say, a fiber waiter is managed by the sync_timer, and
// the thread waiter uses a temporary IO to wait for a notice.
if (obj->type == SYNC_OBJ_T_FIBER) {
sync_timer_wakeup(obj->timer, obj);
} else if (obj->type == SYNC_OBJ_T_THREAD) {
if (var_hook_sys_api) {
socket_t out = obj->base->event_out;
FILE_EVENT *fe = fiber_file_open_write(out);
// The waiter is a thread, the out fd is temporaryly
// created by the thread waiter, so we just use one
// temporary FILE_EVENT to bind the out fd, and
// release it after notify the waiter thread.
FILE_EVENT *fe = fiber_file_cache_get(out);
fe->mask |= EVENT_SYSIO;
ret = fbase_event_wakeup(obj->base);
fiber_file_cache_put(fe);
} else {
ret = fbase_event_wakeup(obj->base);
}
ret = fbase_event_wakeup(obj->base);
} else {
msg_fatal("%s(%d): unknown type=%d",
__FUNCTION__, __LINE__, obj->type);
}
// Unrefer the waiter object, which will be really freed when its
// reference is zero. It's safely that the waiter object is used
// by multiple threads with using the reference way.
sync_obj_unrefer(obj);
return ret;
}

View File

@ -209,6 +209,13 @@ void sync_timer_wakeup(SYNC_TIMER *timer, SYNC_OBJ *obj)
FILE_EVENT *fe;
int same_thread;
// If the current fiber is in the same thread with the one
// to be noticed, the out fd is owned by the current thread
// and the FILE_EVENT with the out fd should be in long time
// status, so we use fiber_file_open_write to get it, or else
// the out fd we got is owned by the other thread, and
// we just need to get the temporary FILE_EVENT from cache to
// bind with the out fd, and release it after mbox_send.
if (__pthread_self() == timer->tid) {
fe = fiber_file_open_write(out);
same_thread = 1;