From 3b2af4bb1409beacffa58ee68590b2eeba1e66d6 Mon Sep 17 00:00:00 2001 From: John Doty Date: Thu, 29 Jun 2023 10:14:10 -0700 Subject: [PATCH] Comments and a bug fix --- oden-js/src/context.rs | 19 +++++-------------- oden-js/src/promise.rs | 7 ++++++- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/oden-js/src/context.rs b/oden-js/src/context.rs index d939dd08..7ce96641 100644 --- a/oden-js/src/context.rs +++ b/oden-js/src/context.rs @@ -278,7 +278,10 @@ impl ContextRef { Value::from_raw(v, self) } - /// Construct a new promise. + /// Construct a new promise. The resulting Value is the promise object + /// that can be returned to script and awaited. The Promise object is the + /// one that you can use for completions. Note that if you drop the + /// promise before completing it you *will* panic. pub fn new_promise(&self) -> Result<(Value, Promise)> { self.get_runtime().new_promise(self) } @@ -362,19 +365,7 @@ impl ContextRef { /// Process all pending async jobs. This includes all promise resolutions. pub fn process_all_jobs(&self) -> Result<()> { - // TODO: SAFETY - // This is unsafe because multiple contexts can be sharing the same runtime and cause - // a race condition on the underlying runtime. - loop { - let mut ctx1: *mut sys::JSContext = std::ptr::null_mut(); - let err = unsafe { sys::JS_ExecutePendingJob(sys::JS_GetRuntime(self.ctx), &mut ctx1) }; - if err == 0 { - break; - } else if err < 0 { - return Err(ContextRef::from_raw(ctx1).exception_error()); - } - } - Ok(()) + self.get_runtime().process_all_jobs() } } diff --git a/oden-js/src/promise.rs b/oden-js/src/promise.rs index f071e6b8..0bf846cc 100644 --- a/oden-js/src/promise.rs +++ b/oden-js/src/promise.rs @@ -21,7 +21,12 @@ pub(crate) enum PromiseEvent { /// A Promise is a small, thread-safe marker which represents a pending /// promise inside the JS runtime. This is how you complete the promise: you -/// must either call `resolve` or `reject` before you drop the promise. +/// must either call `resolve` or `reject` before you drop the promise. If +/// you drop the promise without calling either `resolve` or `reject` then it +/// will panic. +/// +/// In order to actually *process* the completion, someone must call +/// process_all_jobs on a context or the underlying runtime itself. #[derive(Debug)] pub struct Promise { complete: bool,