bugfixed: MUST set stage to SF_NIO_STAGE_NONE first for re-entry

connection_manager
YuQing 2021-02-10 21:38:45 +08:00
parent 3a4a7069b9
commit 67b412fb88
2 changed files with 15 additions and 11 deletions

View File

@ -32,18 +32,17 @@
typedef struct idempotency_request_result { typedef struct idempotency_request_result {
short rsize; //response size defined by application short rsize; //response size defined by application
short flags; //for application short flags; //for application
int result; volatile int result;
void *response; void * volatile response;
} IdempotencyRequestResult; } IdempotencyRequestResult;
typedef struct idempotency_request { typedef struct idempotency_request {
uint64_t req_id; uint64_t req_id;
volatile int ref_count; volatile int ref_count;
volatile bool finished; volatile char finished;
IdempotencyRequestResult output; IdempotencyRequestResult output;
struct fast_mblock_man *allocator; //for free struct fast_mblock_man *allocator; //for free
struct idempotency_request *next; struct idempotency_request *next;
struct fast_task_info *task; //for debug
} IdempotencyRequest; } IdempotencyRequest;
typedef struct idempotency_request_htable { typedef struct idempotency_request_htable {

View File

@ -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 result;
int stage;
stage = __sync_add_and_fetch(&task->nio_stages.notify, 0);
switch (stage) { 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;
@ -295,8 +293,6 @@ 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;
} }
@ -396,10 +392,19 @@ void sf_recv_notify_read(int sock, short event, void *arg)
task = current; task = current;
current = current->next; current = current->next;
stage = __sync_add_and_fetch(&task->nio_stages.notify, 0);
if (!task->canceled) { 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 { } else {
stage = __sync_add_and_fetch(&task->nio_stages.notify, 0);
if (stage != SF_NIO_STAGE_NONE) { if (stage != SF_NIO_STAGE_NONE) {
if (stage == SF_NIO_STAGE_CONTINUE) { if (stage == SF_NIO_STAGE_CONTINUE) {
if (task->continue_callback != NULL) { if (task->continue_callback != NULL) {