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 35 main(void) 36 { 37 new PowerManagementDaemon(); 38 be_app->Run(); 39 delete be_app; 40 return 0; 41 } 42 43 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 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 85 PowerManagementDaemon::_EventLooper(void* arg) 86 { 87 PowerManagementDaemon* self = (PowerManagementDaemon*)arg; 88 self->_EventLoop(); 89 return B_OK; 90 } 91 92 93 void 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