[gjs: 1/2] context: Correctly restore idle handler when restoring saved job queue




commit 0c826fa899680292abbae35fd8edcbd48b55ea87
Author: Philip Chimento <philip chimento gmail com>
Date:   Thu Feb 18 23:00:19 2021 -0800

    context: Correctly restore idle handler when restoring saved job queue
    
    In the previous code, two separate things were confused: whether the
    context was actively emptying the job queue (m_draining_job_queue) and
    whether there was an idle function pending to empty the job queue. When
    saving the job queue, the former would be saved to a boolean value, but
    when restoring it, the saved value would control the latter.
    
    Since code coverage constantly pauses and resumes the job queue, running
    asynchronous code under code coverage would eventually cause the job
    queue's internal state to get messed up, so that either promises would
    never resolve, or assertions about the internal state would fail.
    
    To fix this problem, save and restore both of these things separately.
    
    Add a test to testself.js to ensure that promises do actually resolve.
    
    Closes: #349

 gjs/context.cpp                |  5 ++++-
 installed-tests/js/testself.js | 16 ++++++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)
---
diff --git a/gjs/context.cpp b/gjs/context.cpp
index d54ab6ef..13c05d1d 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -883,19 +883,22 @@ class GjsContextPrivate::SavedQueue : public JS::JobQueue::SavedJobQueue {
  private:
     GjsContextPrivate* m_gjs;
     JS::PersistentRooted<JobQueueStorage> m_queue;
+    bool m_idle_was_pending : 1;
     bool m_was_draining : 1;
 
  public:
     explicit SavedQueue(GjsContextPrivate* gjs)
         : m_gjs(gjs),
           m_queue(gjs->m_cx, std::move(gjs->m_job_queue)),
+          m_idle_was_pending(gjs->m_idle_drain_handler != 0),
           m_was_draining(gjs->m_draining_job_queue) {
         gjs->stop_draining_job_queue();
     }
 
     ~SavedQueue(void) {
         m_gjs->m_job_queue = std::move(m_queue.get());
-        if (m_was_draining)
+        m_gjs->m_draining_job_queue = m_was_draining;
+        if (m_idle_was_pending)
             m_gjs->start_draining_job_queue();
     }
 };
diff --git a/installed-tests/js/testself.js b/installed-tests/js/testself.js
index 39d9c567..85332e75 100644
--- a/installed-tests/js/testself.js
+++ b/installed-tests/js/testself.js
@@ -32,6 +32,22 @@ describe('Test harness internal consistency', function () {
         expect(() => expect(true).toThrow()).toThrow();
         expect(() => true).not.toThrow();
     });
+
+    describe('awaiting', function () {
+        it('a Promise resolves', async function () {
+            await Promise.resolve();
+            expect(true).toBe(true);
+        });
+
+        async function nested() {
+            await Promise.resolve();
+        }
+
+        it('a nested async function resolves', async function () {
+            await nested();
+            expect(true).toBe(true);
+        });
+    });
 });
 
 describe('SpiderMonkey features check', function () {


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