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

             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 <config.h>
      13                 :             : 
      14                 :             : #include <atomic>
      15                 :             : #include <deque>
      16                 :             : #include <thread>
      17                 :             : #include <utility>  // for pair
      18                 :             : 
      19                 :             : #include <glib.h>  // for gboolean
      20                 :             : 
      21                 :             : class ObjectInstance;
      22                 :             : namespace Gjs {
      23                 :             : namespace Test {
      24                 :             : struct ToggleQueue;
      25                 :             : }
      26                 :             : }
      27                 :             : 
      28                 :             : /* Thread-safe queue for enqueueing toggle-up or toggle-down events on GObjects
      29                 :             :  * from any thread. For more information, see object.cpp, comments near
      30                 :             :  * wrapped_gobj_toggle_notify(). */
      31                 :             : class ToggleQueue {
      32                 :             : public:
      33                 :             :     enum Direction {
      34                 :             :         DOWN,
      35                 :             :         UP
      36                 :             :     };
      37                 :             : 
      38                 :             :     using Handler = void (*)(ObjectInstance*, Direction);
      39                 :             : 
      40                 :             :  private:
      41                 :             :     friend Gjs::Test::ToggleQueue;
      42                 :             :     struct Item {
      43                 :             :         Item() {}
      44                 :          61 :         Item(ObjectInstance* o, Direction d) : object(o), direction(d) {}
      45                 :             :         ObjectInstance* object;
      46                 :             :         ToggleQueue::Direction direction;
      47                 :             :     };
      48                 :             : 
      49                 :             :     struct Locked {
      50                 :        8462 :         explicit Locked(ToggleQueue* queue) { queue->lock(); }
      51                 :        8462 :         ~Locked() { get_default_unlocked().maybe_unlock(); }
      52                 :        8426 :         ToggleQueue* operator->() { return &get_default_unlocked(); }
      53                 :             :     };
      54                 :             : 
      55                 :             :     std::deque<Item> q;
      56                 :             :     std::atomic_bool m_shutdown = ATOMIC_VAR_INIT(false);
      57                 :             : 
      58                 :             :     unsigned m_idle_id = 0;
      59                 :             :     Handler m_toggle_handler = nullptr;
      60                 :             :     std::atomic<std::thread::id> m_holder = std::thread::id();
      61                 :             :     unsigned m_holder_ref_count = 0;
      62                 :             : 
      63                 :             :     void lock();
      64                 :             :     void maybe_unlock();
      65                 :             :     [[nodiscard]] bool is_locked() const {
      66                 :             :         return m_holder != std::thread::id();
      67                 :             :     }
      68                 :       17218 :     [[nodiscard]] bool owns_lock() const {
      69                 :       17218 :         return m_holder == std::this_thread::get_id();
      70                 :             :     }
      71                 :             : 
      72                 :             :     [[nodiscard]] std::deque<Item>::iterator find_operation_locked(
      73                 :             :         const ObjectInstance* obj, Direction direction);
      74                 :             : 
      75                 :             :     [[nodiscard]] std::deque<Item>::const_iterator find_operation_locked(
      76                 :             :         const ObjectInstance* obj, Direction direction) const;
      77                 :             : 
      78                 :             :     static gboolean idle_handle_toggle(void *data);
      79                 :             :     static void idle_destroy_notify(void *data);
      80                 :             : 
      81                 :       25297 :     [[nodiscard]] static ToggleQueue& get_default_unlocked() {
      82   [ +  +  +  - ]:       25297 :         static ToggleQueue the_singleton;
      83                 :       25297 :         return the_singleton;
      84                 :             :     }
      85                 :             : 
      86                 :             :  public:
      87                 :             :     /* These two functions return a pair DOWN, UP signifying whether toggles
      88                 :             :      * are / were queued. is_queued() just checks and does not modify. */
      89                 :             :     [[nodiscard]] std::pair<bool, bool> is_queued(ObjectInstance* obj) const;
      90                 :             :     /* Cancels pending toggles and returns whether any were queued. */
      91                 :             :     std::pair<bool, bool> cancel(ObjectInstance* obj);
      92                 :             : 
      93                 :             :     /* Pops a toggle from the queue and processes it. Call this if you don't
      94                 :             :      * want to wait for it to be processed in idle time. Returns false if queue
      95                 :             :      * is empty. */
      96                 :             :     bool handle_toggle(Handler handler);
      97                 :             :     void handle_all_toggles(Handler handler);
      98                 :             : 
      99                 :             :     /* After calling this, the toggle queue won't accept any more toggles. Only
     100                 :             :      * intended for use when destroying the JSContext and breaking the
     101                 :             :      * associations between C and JS objects. */
     102                 :             :     void shutdown(void);
     103                 :             : 
     104                 :             :     /* Queues a toggle to be processed in idle time. */
     105                 :             :     void enqueue(ObjectInstance* obj, Direction direction, Handler handler);
     106                 :             : 
     107                 :        8409 :     [[nodiscard]] static Locked get_default() {
     108                 :        8409 :         return Locked(&get_default_unlocked());
     109                 :             :     }
     110                 :             : };
     111                 :             : 
     112                 :             : #endif  // GI_TOGGLE_H_
        

Generated by: LCOV version 2.0-1