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_MIN_BUFF_SIZE (64 * 1024)
#define SF_DEF_MAX_BUFF_SIZE (64 * 1024) #define SF_DEF_MAX_BUFF_SIZE (64 * 1024)
#define SF_NIO_STAGE_INIT 0 //set ioevent #define SF_NIO_STAGE_NONE 0
#define SF_NIO_STAGE_CONNECT 1 //do connect (client only) #define SF_NIO_STAGE_INIT 1 //set ioevent
#define SF_NIO_STAGE_HANDSHAKE 2 //notify the thread to handshake (client only) #define SF_NIO_STAGE_CONNECT 2 //do connect (client only)
#define SF_NIO_STAGE_RECV 3 //do recv #define SF_NIO_STAGE_HANDSHAKE 3 //notify the thread to handshake (client only)
#define SF_NIO_STAGE_SEND 4 //do send #define SF_NIO_STAGE_RECV 4 //do recv
#define SF_NIO_STAGE_FORWARDED 5 //deal the forwarded request #define SF_NIO_STAGE_SEND 5 //do send
#define SF_NIO_STAGE_CONTINUE 6 //notify the thread continue deal #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_STAGE_CLOSE 127 //cleanup the task
#define SF_NIO_TASK_STAGE_FETCH(task) task->nio_stages.current #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) static int sf_nio_deal_task(struct fast_task_info *task)
{ {
int result; 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: case SF_NIO_STAGE_INIT:
task->nio_stages.current = SF_NIO_STAGE_RECV; task->nio_stages.current = SF_NIO_STAGE_RECV;
result = sf_nio_init(task); result = sf_nio_init(task);
@ -283,7 +285,7 @@ static int sf_nio_deal_task(struct fast_task_info *task)
default: default:
logError("file: "__FILE__", line: %d, " logError("file: "__FILE__", line: %d, "
"client ip: %s, invalid notify stage: %d", "client ip: %s, invalid notify stage: %d",
__LINE__, task->client_ip, task->nio_stages.notify); __LINE__, task->client_ip, stage);
result = -EINVAL; result = -EINVAL;
break; break;
} }
@ -292,6 +294,8 @@ static int sf_nio_deal_task(struct fast_task_info *task)
ioevent_add_to_deleted_list(task); ioevent_add_to_deleted_list(task);
} }
__sync_bool_compare_and_swap(&task->nio_stages.notify,
stage, SF_NIO_STAGE_NONE);
return result; return result;
} }
@ -301,8 +305,13 @@ int sf_nio_notify(struct fast_task_info *task, const int stage)
int result; int result;
bool notify; 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); PTHREAD_MUTEX_LOCK(&task->thread_data->waiting_queue.lock);
task->nio_stages.notify = stage;
task->next = NULL; task->next = NULL;
if (task->thread_data->waiting_queue.tail == NULL) { if (task->thread_data->waiting_queue.tail == NULL) {