1 /*
2 * Copyright 2013, Jérôme Duval, korli@users.berlios.de.
3 * Copyright 2014, Rene Gollent, rene@gollent.com.
4 * Copyright 2005, Nathan Whitehorn.
5 *
6 * Distributed under the terms of the MIT License.
7 */
8
9
10 #include "lid_monitor.h"
11 #include "power_button_monitor.h"
12
13 #include <Server.h>
14
15 #include <map>
16
17
18 class PowerManagementDaemon : public BServer {
19 public:
20 PowerManagementDaemon();
21 virtual ~PowerManagementDaemon();
22 private:
23 void _EventLoop();
24 static status_t _EventLooper(void *arg);
25
26 thread_id fEventThread;
27 PowerMonitor* fPowerMonitors[2];
28 uint32 fMonitorCount;
29
30 bool fQuitRequested;
31 };
32
33
34 int
main(void)35 main(void)
36 {
37 new PowerManagementDaemon();
38 be_app->Run();
39 delete be_app;
40 return 0;
41 }
42
43
PowerManagementDaemon()44 PowerManagementDaemon::PowerManagementDaemon()
45 :
46 BServer("application/x-vnd.Haiku-powermanagement", false, NULL),
47 fMonitorCount(0),
48 fQuitRequested(false)
49 {
50 PowerMonitor* powerButtonMonitor = new PowerButtonMonitor;
51 if (powerButtonMonitor->FDs().size() > 0)
52 fPowerMonitors[fMonitorCount++] = powerButtonMonitor;
53 else
54 delete powerButtonMonitor;
55
56 PowerMonitor* lidMonitor = new LidMonitor;
57 if (lidMonitor->FDs().size() > 0)
58 fPowerMonitors[fMonitorCount++] = lidMonitor;
59 else
60 delete lidMonitor;
61
62 fEventThread = spawn_thread(_EventLooper, "_power_daemon_event_loop_",
63 B_NORMAL_PRIORITY, this);
64 if (fEventThread < B_OK)
65 return;
66 if (resume_thread(fEventThread) < B_OK) {
67 kill_thread(fEventThread);
68 fEventThread = -1;
69 return;
70 }
71 }
72
73
~PowerManagementDaemon()74 PowerManagementDaemon::~PowerManagementDaemon()
75 {
76 fQuitRequested = true;
77 for (uint32 i = 0; i < fMonitorCount; i++)
78 delete fPowerMonitors[i];
79 status_t status;
80 wait_for_thread(fEventThread, &status);
81 }
82
83
84 status_t
_EventLooper(void * arg)85 PowerManagementDaemon::_EventLooper(void* arg)
86 {
87 PowerManagementDaemon* self = (PowerManagementDaemon*)arg;
88 self->_EventLoop();
89 return B_OK;
90 }
91
92
93 void
_EventLoop()94 PowerManagementDaemon::_EventLoop()
95 {
96 if (fMonitorCount == 0)
97 return;
98
99 std::map<int, PowerMonitor*> descriptorMap;
100
101 size_t fdCount = 0;
102 for (uint32 i = 0; i < fMonitorCount; i++)
103 fdCount += fPowerMonitors[i]->FDs().size();
104
105 object_wait_info info[fdCount];
106 uint32 index = 0;
107 for (uint32 i = 0; i < fMonitorCount; i++) {
108 const std::set<int>& fds = fPowerMonitors[i]->FDs();
109 for (std::set<int>::iterator it = fds.begin(); it != fds.end(); ++it) {
110 info[index].object = *it;
111 info[index].type = B_OBJECT_TYPE_FD;
112 info[index].events = B_EVENT_READ;
113 descriptorMap[*it] = fPowerMonitors[i];
114 ++index;
115 }
116 }
117 while (!fQuitRequested) {
118 if (wait_for_objects(info, fdCount) < B_OK)
119 continue;
120 // handle events and reset events
121 for (uint32 i = 0; i < fdCount; i++) {
122 if (info[i].events & B_EVENT_READ)
123 descriptorMap[info[i].object]->HandleEvent(info[i].object);
124 else
125 info[i].events = B_EVENT_READ;
126 }
127 }
128 }
129