Skip to content

Commit e488b92

Browse files
authored
Merge pull request #15 from NativeScript/fix/napi-async-work-after-free
fix(napi): don't touch async work after its complete callback
2 parents a3260c4 + ff782dc commit e488b92

1 file changed

Lines changed: 14 additions & 10 deletions

File tree

‎runtime/src/node_api.rs‎

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -577,18 +577,22 @@ struct AsyncWork {
577577
}
578578

579579
impl AsyncWork {
580-
/// JS thread.
580+
/// JS thread. `complete` may free the work (`napi_delete_async_work`), as Node allows and
581+
/// napi-rs does, so nothing reads `work` after calling it.
581582
unsafe fn complete(work: *mut AsyncWork) {
582-
let work = &*work;
583-
let status = if work.state.swap(WORK_IDLE, Ordering::AcqRel) == WORK_CANCELLED {
584-
NAPI_CANCELLED
585-
} else {
586-
NAPI_OK
583+
let (env, complete, data) = {
584+
let work = &*work;
585+
let status = if work.state.swap(WORK_IDLE, Ordering::AcqRel) == WORK_CANCELLED {
586+
NAPI_CANCELLED
587+
} else {
588+
NAPI_OK
589+
};
590+
(work.env, work.complete.map(|complete| (complete, status)), work.data)
587591
};
588-
if let Some(complete) = work.complete {
589-
let _scope = HandleScope::open(work.env);
590-
complete(work.env, status, work.data);
591-
report_pending(work.env);
592+
if let Some((complete, status)) = complete {
593+
let _scope = HandleScope::open(env);
594+
complete(env, status, data);
595+
report_pending(env);
592596
}
593597
}
594598
}

0 commit comments

Comments
 (0)