use atomic operation to avoid reentrance

connection_manager
YuQing 2020-10-21 09:32:49 +08:00
parent 5c6cff1ea3
commit e0bba18a02
2 changed files with 20 additions and 10 deletions

View File

@ -26,13 +26,14 @@
#define SF_DEF_MIN_BUFF_SIZE (64 * 1024)
#define SF_DEF_MAX_BUFF_SIZE (64 * 1024)
#define SF_NIO_STAGE_INIT 0 //set ioevent
#define SF_NIO_STAGE_CONNECT 1 //do connect (client only)
#define SF_NIO_STAGE_HANDSHAKE 2 //notify the thread to handshake (client only)
#define SF_NIO_STAGE_RECV 3 //do recv
#define SF_NIO_STAGE_SEND 4 //do send
#define SF_NIO_STAGE_FORWARDED 5 //deal the forwarded request
#define SF_NIO_STAGE_CONTINUE 6 //notify the thread continue deal
#define SF_NIO_STAGE_NONE 0
#define SF_NIO_STAGE_INIT 1 //set ioevent
#define SF_NIO_STAGE_CONNECT 2 //do connect (client only)
#define SF_NIO_STAGE_HANDSHAKE 3 //notify the thread to handshake (client only)
#define SF_NIO_STAGE_RECV 4 //do recv
#define SF_NIO_STAGE_SEND 5 //do send
#define SF_NIO_STAGE_FORWARDED 6 //deal the forwarded request
#define SF_NIO_STAGE_CONTINUE 7 //notify the thread continue deal
#define SF_NIO_STAGE_CLOSE 127 //cleanup the task
#define SF_NIO_TASK_STAGE_FETCH(task) task->nio_stages.current

View File

@ -247,8 +247,10 @@ static int sf_connect_server(struct fast_task_info *task)
static int sf_nio_deal_task(struct fast_task_info *task)
{
int result;
int stage;
switch (task->nio_stages.notify) {
stage = __sync_add_and_fetch(&task->nio_stages.notify, 0);
switch (stage) {
case SF_NIO_STAGE_INIT:
task->nio_stages.current = SF_NIO_STAGE_RECV;
result = sf_nio_init(task);
@ -283,7 +285,7 @@ static int sf_nio_deal_task(struct fast_task_info *task)
default:
logError("file: "__FILE__", line: %d, "
"client ip: %s, invalid notify stage: %d",
__LINE__, task->client_ip, task->nio_stages.notify);
__LINE__, task->client_ip, stage);
result = -EINVAL;
break;
}
@ -292,6 +294,8 @@ static int sf_nio_deal_task(struct fast_task_info *task)
ioevent_add_to_deleted_list(task);
}
__sync_bool_compare_and_swap(&task->nio_stages.notify,
stage, SF_NIO_STAGE_NONE);
return result;
}
@ -301,8 +305,13 @@ int sf_nio_notify(struct fast_task_info *task, const int stage)
int result;
bool notify;
if (!__sync_bool_compare_and_swap(&task->nio_stages.notify,
SF_NIO_STAGE_NONE, stage))
{
return EAGAIN;
}
PTHREAD_MUTEX_LOCK(&task->thread_data->waiting_queue.lock);
task->nio_stages.notify = stage;
task->next = NULL;
if (task->thread_data->waiting_queue.tail == NULL) {