Skip to content

Commit ece6b8d

Browse files
gdamoreJaylinYu
authored andcommitted
aio: task_abort was a mistake (fixes #2208)
The use of task_abort to prematurely fail an aio at scheduling time was a mistake, because it could have led to duplicate calls to nng_aio_finish(). We do need to ensure that we leave an indicator so that nni_aio_schedule can return the abort status to caller, in the case that abort is called between the nni_aio_begin and nni_aio_schedule calls. This is more or less the same changes for main in commit 3ca7bcc0edd0f26c33264d32e7b6f07276e72e3c but backported to stable. (A hand backport was needed.)
1 parent 015c189 commit ece6b8d

File tree

2 files changed

+14
-8
lines changed

2 files changed

+14
-8
lines changed

src/core/aio.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,6 @@ nni_aio_stop(nni_aio *aio)
201201

202202
if (fn != NULL) {
203203
fn(aio, arg, NNG_ECANCELED);
204-
} else {
205-
nni_task_abort(&aio->a_task);
206204
}
207205

208206
nni_aio_wait(aio);
@@ -228,8 +226,6 @@ nni_aio_close(nni_aio *aio)
228226

229227
if (fn != NULL) {
230228
fn(aio, arg, NNG_ECLOSED);
231-
} else {
232-
nni_task_abort(&aio->a_task);
233229
}
234230
}
235231
}
@@ -347,6 +343,7 @@ nni_aio_begin(nni_aio *aio)
347343
aio->a_result = 0;
348344
aio->a_count = 0;
349345
aio->a_cancel_fn = NULL;
346+
aio->a_abort = false;
350347

351348
// We should not reschedule anything at this point.
352349
if (aio->a_stop) {
@@ -373,7 +370,6 @@ nni_aio_schedule(nni_aio *aio, nni_aio_cancel_fn cancel, void *data)
373370
// Convert the relative timeout to an absolute timeout.
374371
switch (aio->a_timeout) {
375372
case NNG_DURATION_ZERO:
376-
nni_task_abort(&aio->a_task);
377373
return (NNG_ETIMEDOUT);
378374
case NNG_DURATION_INFINITE:
379375
case NNG_DURATION_DEFAULT:
@@ -386,8 +382,13 @@ nni_aio_schedule(nni_aio *aio, nni_aio_cancel_fn cancel, void *data)
386382
}
387383

388384
nni_mtx_lock(&eq->eq_mtx);
385+
if (aio->a_abort) {
386+
int rv = aio->a_result;
387+
nni_mtx_unlock(&eq->eq_mtx);
388+
return (rv);
389+
}
390+
389391
if (aio->a_stop) {
390-
nni_task_abort(&aio->a_task);
391392
nni_mtx_unlock(&eq->eq_mtx);
392393
return (NNG_ECLOSED);
393394
}
@@ -419,13 +420,17 @@ nni_aio_abort(nni_aio *aio, int rv)
419420
arg = aio->a_cancel_arg;
420421
aio->a_cancel_fn = NULL;
421422
aio->a_cancel_arg = NULL;
423+
if (fn == NULL) {
424+
// We haven't been scheduled yet,
425+
// so make sure that the schedule will abort.
426+
aio->a_abort = true;
427+
aio->a_result = rv;
428+
}
422429
nni_mtx_unlock(&eq->eq_mtx);
423430

424431
// Stop any I/O at the provider level.
425432
if (fn != NULL) {
426433
fn(aio, arg, rv);
427-
} else {
428-
nni_task_abort(&aio->a_task);
429434
}
430435
}
431436

src/core/aio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ struct nng_aio {
223223
bool a_expire_ok; // Expire from sleep is ok
224224
bool a_expiring; // Expiration in progress
225225
bool a_use_expire; // Use expire instead of timeout
226+
bool a_abort; // Abort the operation.
226227
nni_task a_task;
227228

228229
// Read/write operations.

0 commit comments

Comments
 (0)