Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / platform / Linux / bluez / MainLoop.h
1 /*
2  *    Copyright (c) 2021 Project CHIP Authors
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16
17 #pragma once
18
19 #include <core/CHIPError.h>
20 #include <platform/CHIPDeviceLayer.h>
21
22 #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
23
24 #include <glib.h>
25 #include <semaphore.h>
26
27 namespace chip {
28 namespace DeviceLayer {
29 namespace Internal {
30
31 /// The main loop provides a thread-based implementation that runs
32 /// the GLib main loop.
33 ///
34 /// The main loop is used execute callbacks (e.g. dbus notifications).
35 class MainLoop
36 {
37 public:
38     /// Ensure that a thread with g_main_loop_run is executing.
39     CHIP_ERROR EnsureStarted();
40
41     /// Executes a callback on the underlying main loop.
42     ///
43     /// The main loop MUST have been started already.
44     bool RunOnBluezThread(GSourceFunc closure, void * arg);
45
46     /// Executes a callback on the underlying main loop and waits for
47     /// the method to complete.
48     ///
49     /// The main loop MUST have been started already.
50     bool RunOnBluezThreadAndWait(GSourceFunc closure, void * arg);
51
52     /// Convenience method to require less casts to void*
53     template <class T>
54     bool Schedule(int (*callback)(T *), T * value)
55     {
56         return RunOnBluezThread(G_SOURCE_FUNC(callback), value);
57     }
58
59     /// Convenience method to require less casts to void*
60     template <class T>
61     bool ScheduleAndWait(int (*callback)(T *), T * value)
62     {
63         return RunOnBluezThreadAndWait(G_SOURCE_FUNC(callback), value);
64     }
65
66     /// Schedules a method to be executed after the main loop has finished
67     ///
68     /// A single cleanup method can exist and the main loop has to be running
69     /// to set a cleanup method.
70     template <class T>
71     bool SetCleanupFunction(int (*callback)(T *), T * value)
72     {
73         if (mCleanup != nullptr)
74         {
75             return false;
76         }
77
78         if ((mBluezMainLoop == nullptr) || !g_main_loop_is_running(mBluezMainLoop))
79         {
80             return false;
81         }
82
83         mCleanup         = G_SOURCE_FUNC(callback);
84         mCleanupArgument = static_cast<void *>(value);
85
86         return true;
87     }
88
89     static MainLoop & Instance();
90
91 private:
92     MainLoop() {}
93
94     static void * Thread(void * self);
95
96     GMainLoop * mBluezMainLoop = nullptr;
97     pthread_t mThread          = 0;
98
99     // allow a single cleanup method
100     GSourceFunc mCleanup    = nullptr;
101     void * mCleanupArgument = nullptr;
102 };
103
104 } // namespace Internal
105 } // namespace DeviceLayer
106 } // namespace chip
107
108 #endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE