LCOV - code coverage report
Current view: top level - gi - toggle.h (source / functions) Hit Total Coverage
Test: gjs- Code Coverage Lines: 11 11 100.0 %
Date: 2023-09-17 02:39:54 Functions: 7 7 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 3 4 75.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
       2                 :            : // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
       3                 :            : // SPDX-FileCopyrightText: 2017 Endless Mobile, Inc.
       4                 :            : // SPDX-FileCopyrightText: 2021 Canonical Ltd.
       5                 :            : // SPDX-FileContributor: Authored by: Philip Chimento <philip@endlessm.com>
       6                 :            : // SPDX-FileContributor: Philip Chimento <philip.chimento@gmail.com>
       7                 :            : // SPDX-FileContributor: Marco Trevisan <marco.trevisan@canonical.com>
       8                 :            : 
       9                 :            : #ifndef GI_TOGGLE_H_
      10                 :            : #define GI_TOGGLE_H_
      11                 :            : 
      12                 :            : #include <glib.h>  // for gboolean
      13                 :            : 
      14                 :            : #include <atomic>
      15                 :            : #include <deque>
      16                 :            : #include <thread>
      17                 :            : #include <utility>  // for pair
      18                 :            : 
      19                 :            : class ObjectInstance;
      20                 :            : namespace Gjs {
      21                 :            : namespace Test {
      22                 :            : struct ToggleQueue;
      23                 :            : }
      24                 :            : }
      25                 :            : 
      26                 :            : /* Thread-safe queue for enqueueing toggle-up or toggle-down events on GObjects
      27                 :            :  * from any thread. For more information, see object.cpp, comments near
      28                 :            :  * wrapped_gobj_toggle_notify(). */
      29                 :            : class ToggleQueue {
      30                 :            : public:
      31                 :            :     enum Direction {
      32                 :            :         DOWN,
      33                 :            :         UP
      34                 :            :     };
      35                 :            : 
      36                 :            :     using Handler = void (*)(ObjectInstance*, Direction);
      37                 :            : 
      38                 :            :  private:
      39                 :            :     friend Gjs::Test::ToggleQueue;
      40                 :            :     struct Item {
      41                 :            :         Item() {}
      42                 :         61 :         Item(ObjectInstance* o, Direction d) : object(o), direction(d) {}
      43                 :            :         ObjectInstance* object;
      44                 :            :         ToggleQueue::Direction direction;
      45                 :            :     };
      46                 :            : 
      47                 :            :     struct Locked {
      48                 :       7177 :         explicit Locked(ToggleQueue* queue) { queue->lock(); }
      49                 :       7177 :         ~Locked() { get_default_unlocked().maybe_unlock(); }
      50                 :       7159 :         ToggleQueue* operator->() { return &get_default_unlocked(); }
      51                 :            :     };
      52                 :            : 
      53                 :            :     std::deque<Item> q;
      54                 :            :     std::atomic_bool m_shutdown = ATOMIC_VAR_INIT(false);
      55                 :            : 
      56                 :            :     unsigned m_idle_id = 0;
      57                 :            :     Handler m_toggle_handler = nullptr;
      58                 :            :     std::atomic<std::thread::id> m_holder = std::thread::id();
      59                 :            :     unsigned m_holder_ref_count = 0;
      60                 :            : 
      61                 :            :     void lock();
      62                 :            :     void maybe_unlock();
      63                 :            :     [[nodiscard]] bool is_locked() const {
      64                 :            :         return m_holder != std::thread::id();
      65                 :            :     }
      66                 :      14650 :     [[nodiscard]] bool owns_lock() const {
      67                 :      14650 :         return m_holder == std::this_thread::get_id();
      68                 :            :     }
      69                 :            : 
      70                 :            :     [[nodiscard]] std::deque<Item>::iterator find_operation_locked(
      71                 :            :         const ObjectInstance* obj, Direction direction);
      72                 :            : 
      73                 :            :     [[nodiscard]] std::deque<Item>::const_iterator find_operation_locked(
      74                 :            :         const ObjectInstance* obj, Direction direction) const;
      75                 :            : 
      76                 :            :     static gboolean idle_handle_toggle(void *data);
      77                 :            :     static void idle_destroy_notify(void *data);
      78                 :            : 
      79                 :      21460 :     [[nodiscard]] static ToggleQueue& get_default_unlocked() {
      80   [ +  +  +  - ]:      21460 :         static ToggleQueue the_singleton;
      81                 :      21460 :         return the_singleton;
      82                 :            :     }
      83                 :            : 
      84                 :            :  public:
      85                 :            :     /* These two functions return a pair DOWN, UP signifying whether toggles
      86                 :            :      * are / were queued. is_queued() just checks and does not modify. */
      87                 :            :     [[nodiscard]] std::pair<bool, bool> is_queued(ObjectInstance* obj) const;
      88                 :            :     /* Cancels pending toggles and returns whether any were queued. */
      89                 :            :     std::pair<bool, bool> cancel(ObjectInstance* obj);
      90                 :            : 
      91                 :            :     /* Pops a toggle from the queue and processes it. Call this if you don't
      92                 :            :      * want to wait for it to be processed in idle time. Returns false if queue
      93                 :            :      * is empty. */
      94                 :            :     bool handle_toggle(Handler handler);
      95                 :            :     void handle_all_toggles(Handler handler);
      96                 :            : 
      97                 :            :     /* After calling this, the toggle queue won't accept any more toggles. Only
      98                 :            :      * intended for use when destroying the JSContext and breaking the
      99                 :            :      * associations between C and JS objects. */
     100                 :            :     void shutdown(void);
     101                 :            : 
     102                 :            :     /* Queues a toggle to be processed in idle time. */
     103                 :            :     void enqueue(ObjectInstance* obj, Direction direction, Handler handler);
     104                 :            : 
     105                 :       7124 :     [[nodiscard]] static Locked get_default() {
     106                 :       7124 :         return Locked(&get_default_unlocked());
     107                 :            :     }
     108                 :            : };
     109                 :            : 
     110                 :            : #endif  // GI_TOGGLE_H_

Generated by: LCOV version 1.14