diff options
Diffstat (limited to 'gjs/mainloop.cpp')
-rw-r--r-- | gjs/mainloop.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/gjs/mainloop.cpp b/gjs/mainloop.cpp new file mode 100644 index 00000000..efe9d05a --- /dev/null +++ b/gjs/mainloop.cpp @@ -0,0 +1,55 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later +// SPDX-FileCopyrightText: 2021 Evan Welsh <contact@evanwelsh.com> + +#include <gio/gio.h> +#include <glib.h> + +#include "gjs/context-private.h" +#include "gjs/mainloop.h" + +namespace Gjs { + +MainLoop::MainLoop() { m_refcount = 0; } + +void MainLoop::ref() { m_refcount++; } + +bool MainLoop::unref() { + if (m_refcount == 0) + return false; + + m_refcount--; + return true; +} + +void MainLoop::spin(GjsContext* context) { + auto priv = GjsContextPrivate::from_object(context); + + // Check if System.exit() has been called. + if (priv->should_exit(nullptr)) + return; + + GjsAutoPointer<GMainContext, GMainContext, g_main_context_unref> + main_context(g_main_context_ref_thread_default()); + + do { + if (priv->should_exit(nullptr)) + break; + + // Allow the loop to block if the event loop is referenced. + bool can_block = m_refcount > 0; + // Only run the loop if there are pending jobs. + if (g_main_context_pending(main_context)) + g_main_context_iteration(main_context, can_block); + + // Check if System.exit() has been called. + if (priv->should_exit(nullptr)) + break; + } while ( + // If there are pending sources or the job queue is not empty + (m_refcount > 0 || !priv->empty()) && + // and System.exit() has not been called + // continue spinning the event loop. + !priv->should_exit(nullptr)); +} +}; // namespace Gjs |