1 // Copyright 2015 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef LIBBRILLO_BRILLO_MESSAGE_LOOPS_GLIB_MESSAGE_LOOP_H_
6 #define LIBBRILLO_BRILLO_MESSAGE_LOOPS_GLIB_MESSAGE_LOOP_H_
7 
8 #include <map>
9 #include <memory>
10 
11 #include <base/location.h>
12 #include <base/time/time.h>
13 #include <glib.h>
14 
15 #include <brillo/brillo_export.h>
16 #include <brillo/message_loops/message_loop.h>
17 
18 namespace brillo {
19 
20 class BRILLO_EXPORT GlibMessageLoop : public MessageLoop {
21  public:
22   GlibMessageLoop();
23   ~GlibMessageLoop() override;
24 
25   // MessageLoop overrides.
26   TaskId PostDelayedTask(const tracked_objects::Location& from_here,
27                          const base::Closure& task,
28                          base::TimeDelta delay) override;
29   using MessageLoop::PostDelayedTask;
30   TaskId WatchFileDescriptor(const tracked_objects::Location& from_here,
31                              int fd,
32                              WatchMode mode,
33                              bool persistent,
34                              const base::Closure& task) override;
35   using MessageLoop::WatchFileDescriptor;
36   bool CancelTask(TaskId task_id) override;
37   bool RunOnce(bool may_block) override;
38   void Run() override;
39   void BreakLoop() override;
40 
41  private:
42   // Called by the GLib's main loop when is time to call the callback scheduled
43   // with Post*Task(). The pointer to the callback passed when scheduling it is
44   // passed to this function as a gpointer on |user_data|.
45   static gboolean OnRanPostedTask(gpointer user_data);
46 
47   // Called by the GLib's main loop when the watched source |source| is
48   // ready to perform the operation given in |condition| without blocking.
49   static gboolean OnWatchedFdReady(GIOChannel *source,
50                                    GIOCondition condition,
51                                    gpointer user_data);
52 
53   // Called by the GLib's main loop when the scheduled callback is removed due
54   // to it being executed or canceled.
55   static void DestroyPostedTask(gpointer user_data);
56 
57   // Return a new unused task_id.
58   TaskId NextTaskId();
59 
60   GMainLoop* loop_;
61 
62   struct ScheduledTask {
63     // A pointer to this GlibMessageLoop so we can remove the Task from the
64     // glib callback.
65     GlibMessageLoop* loop;
66     tracked_objects::Location location;
67 
68     MessageLoop::TaskId task_id;
69     guint source_id;
70     bool persistent;
71     base::Closure closure;
72   };
73 
74   std::map<MessageLoop::TaskId, ScheduledTask*> tasks_;
75 
76   MessageLoop::TaskId last_id_ = kTaskIdNull;
77 
78   DISALLOW_COPY_AND_ASSIGN(GlibMessageLoop);
79 };
80 
81 }  // namespace brillo
82 
83 #endif  // LIBBRILLO_BRILLO_MESSAGE_LOOPS_GLIB_MESSAGE_LOOP_H_
84