diff --git a/src/idempotency/server/server_types.h b/src/idempotency/server/server_types.h index 9d6b3d3..89ebffa 100644 --- a/src/idempotency/server/server_types.h +++ b/src/idempotency/server/server_types.h @@ -32,18 +32,17 @@ typedef struct idempotency_request_result { short rsize; //response size defined by application short flags; //for application - int result; - void *response; + volatile int result; + void * volatile response; } IdempotencyRequestResult; typedef struct idempotency_request { uint64_t req_id; volatile int ref_count; - volatile bool finished; + volatile char finished; IdempotencyRequestResult output; struct fast_mblock_man *allocator; //for free struct idempotency_request *next; - struct fast_task_info *task; //for debug } IdempotencyRequest; typedef struct idempotency_request_htable { diff --git a/src/sf_nio.c b/src/sf_nio.c index de26b1d..c2b2f67 100644 --- a/src/sf_nio.c +++ b/src/sf_nio.c @@ -245,12 +245,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, const int stage) { int result; - int stage; - 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; @@ -295,8 +293,6 @@ 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; } @@ -396,10 +392,19 @@ void sf_recv_notify_read(int sock, short event, void *arg) task = current; current = current->next; + stage = __sync_add_and_fetch(&task->nio_stages.notify, 0); if (!task->canceled) { - sf_nio_deal_task(task); + if (stage == SF_NIO_STAGE_CONTINUE) { + /* MUST set to SF_NIO_STAGE_NONE first for re-entry */ + __sync_bool_compare_and_swap(&task->nio_stages.notify, + stage, SF_NIO_STAGE_NONE); + sf_nio_deal_task(task, stage); + } else { + sf_nio_deal_task(task, stage); + __sync_bool_compare_and_swap(&task->nio_stages.notify, + stage, SF_NIO_STAGE_NONE); + } } else { - stage = __sync_add_and_fetch(&task->nio_stages.notify, 0); if (stage != SF_NIO_STAGE_NONE) { if (stage == SF_NIO_STAGE_CONTINUE) { if (task->continue_callback != NULL) {