[gjs/ewlsh/implicit-mainloop: 2/3] promise: Do not continue running the jobs if promise is cancelled




commit f27d5b9dea8863066028647f31d04a7e98d1db3c
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Tue Sep 28 19:30:22 2021 +0200

    promise: Do not continue running the jobs if promise is cancelled

 gjs/context-private.h |  5 ++++-
 gjs/context.cpp       | 14 ++++++++------
 gjs/promise.cpp       |  2 +-
 modules/console.cpp   |  2 +-
 4 files changed, 14 insertions(+), 9 deletions(-)
---
diff --git a/gjs/context-private.h b/gjs/context-private.h
index b8dffba2..ad24635c 100644
--- a/gjs/context-private.h
+++ b/gjs/context-private.h
@@ -17,6 +17,7 @@
 #include <utility>  // for pair
 #include <vector>
 
+#include <gio/gio.h>
 #include <glib-object.h>
 #include <glib.h>
 
@@ -236,11 +237,13 @@ class GjsContextPrivate : public JS::JobQueue {
                            JS::HandleObject allocation_site,
                            JS::HandleObject incumbent_global) override;
     void runJobs(JSContext* cx) override;
+    void runJobs(JSContext* cx, GCancellable* cancellable);
     [[nodiscard]] bool empty() const override { return m_job_queue.empty(); }
     js::UniquePtr<JS::JobQueue::SavedJobQueue> saveJobQueue(
         JSContext* cx) override;
 
-    GJS_JSAPI_RETURN_CONVENTION bool run_jobs_fallible(void);
+    GJS_JSAPI_RETURN_CONVENTION bool run_jobs_fallible(
+        GCancellable* cancellable);
     void register_unhandled_promise_rejection(uint64_t id, GjsAutoChar&& stack);
     void unregister_unhandled_promise_rejection(uint64_t id);
     void warn_about_unhandled_promise_rejections();
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 644f7f42..6c369073 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -943,10 +943,12 @@ bool GjsContextPrivate::enqueuePromiseJob(JSContext* cx [[maybe_unused]],
 
 // Override of JobQueue::runJobs(). Called by js::RunJobs(), and when execution
 // of the job queue was interrupted by the debugger and is resuming.
-void GjsContextPrivate::runJobs(JSContext* cx) {
+void GjsContextPrivate::runJobs(JSContext* cx) { runJobs(cx, nullptr); }
+
+void GjsContextPrivate::runJobs(JSContext* cx, GCancellable* cancellable) {
     g_assert(cx == m_cx);
     g_assert(from_cx(cx) == this);
-    if (!run_jobs_fallible())
+    if (!run_jobs_fallible(cancellable))
         gjs_log_exception(cx);
 }
 
@@ -962,7 +964,7 @@ void GjsContextPrivate::runJobs(JSContext* cx) {
  * Returns: false if one of the jobs threw an uncatchable exception;
  * otherwise true.
  */
-bool GjsContextPrivate::run_jobs_fallible(void) {
+bool GjsContextPrivate::run_jobs_fallible(GCancellable* cancellable) {
     bool retval = true;
 
     if (m_draining_job_queue || m_should_exit)
@@ -979,7 +981,7 @@ bool GjsContextPrivate::run_jobs_fallible(void) {
      * it's crucial to recheck the queue length during each iteration. */
     for (size_t ix = 0; ix < m_job_queue.length(); ix++) {
         /* A previous job might have set this flag. e.g., System.exit(). */
-        if (m_should_exit)
+        if (m_should_exit || g_cancellable_is_cancelled(cancellable))
             break;
 
         job = m_job_queue[ix];
@@ -1255,7 +1257,7 @@ bool GjsContextPrivate::eval(const char* script, ssize_t script_len,
      * uncaught exceptions have been reported since draining runs callbacks. */
     {
         JS::AutoSaveExceptionState saved_exc(m_cx);
-        ok = run_jobs_fallible() && ok;
+        ok = run_jobs_fallible(nullptr) && ok;
     }
 
     auto_profile_exit(auto_profile);
@@ -1314,7 +1316,7 @@ bool GjsContextPrivate::eval_module(const char* identifier,
      */
     {
         JS::AutoSaveExceptionState saved_exc(m_cx);
-        ok = run_jobs_fallible() && ok;
+        ok = run_jobs_fallible(nullptr) && ok;
     }
 
     auto_profile_exit(auto_profile);
diff --git a/gjs/promise.cpp b/gjs/promise.cpp
index 803c249b..af62f94e 100644
--- a/gjs/promise.cpp
+++ b/gjs/promise.cpp
@@ -69,7 +69,7 @@ class PromiseJobDispatcher::Source : public GSource {
         g_source_set_ready_time(this, -1);
 
         // Drain the job queue.
-        m_gjs->runJobs(m_gjs->context());
+        m_gjs->runJobs(m_gjs->context(), m_cancellable);
 
         return G_SOURCE_CONTINUE;
     }
diff --git a/modules/console.cpp b/modules/console.cpp
index 393aed59..99f5f698 100644
--- a/modules/console.cpp
+++ b/modules/console.cpp
@@ -256,7 +256,7 @@ gjs_console_interact(JSContext *context,
         exit_warning = false;
 
         GjsContextPrivate* gjs = GjsContextPrivate::from_cx(context);
-        ok = gjs->run_jobs_fallible() && ok;
+        ok = gjs->run_jobs_fallible(nullptr) && ok;
 
         if (!ok) {
             /* If this was an uncatchable exception, throw another uncatchable


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]