/* * Copyright 2013, Jérôme Duval, korli@users.berlios.de. * Copyright 2014, Rene Gollent, rene@gollent.com. * Copyright 2005, Nathan Whitehorn. * * Distributed under the terms of the MIT License. */ #include "lid_monitor.h" #include "power_button_monitor.h" #include #include class PowerManagementDaemon : public BServer { public: PowerManagementDaemon(); virtual ~PowerManagementDaemon(); private: void _EventLoop(); static status_t _EventLooper(void *arg); thread_id fEventThread; PowerMonitor* fPowerMonitors[2]; uint32 fMonitorCount; bool fQuitRequested; }; int main(void) { new PowerManagementDaemon(); be_app->Run(); delete be_app; return 0; } PowerManagementDaemon::PowerManagementDaemon() : BServer("application/x-vnd.Haiku-powermanagement", false, NULL), fMonitorCount(0), fQuitRequested(false) { PowerMonitor* powerButtonMonitor = new PowerButtonMonitor; if (powerButtonMonitor->FDs().size() > 0) fPowerMonitors[fMonitorCount++] = powerButtonMonitor; else delete powerButtonMonitor; PowerMonitor* lidMonitor = new LidMonitor; if (lidMonitor->FDs().size() > 0) fPowerMonitors[fMonitorCount++] = lidMonitor; else delete lidMonitor; fEventThread = spawn_thread(_EventLooper, "_power_daemon_event_loop_", B_NORMAL_PRIORITY, this); if (fEventThread < B_OK) return; if (resume_thread(fEventThread) < B_OK) { kill_thread(fEventThread); fEventThread = -1; return; } } PowerManagementDaemon::~PowerManagementDaemon() { fQuitRequested = true; for (uint32 i = 0; i < fMonitorCount; i++) delete fPowerMonitors[i]; status_t status; wait_for_thread(fEventThread, &status); } status_t PowerManagementDaemon::_EventLooper(void* arg) { PowerManagementDaemon* self = (PowerManagementDaemon*)arg; self->_EventLoop(); return B_OK; } void PowerManagementDaemon::_EventLoop() { if (fMonitorCount == 0) return; std::map descriptorMap; size_t fdCount = 0; for (uint32 i = 0; i < fMonitorCount; i++) fdCount += fPowerMonitors[i]->FDs().size(); object_wait_info info[fdCount]; uint32 index = 0; for (uint32 i = 0; i < fMonitorCount; i++) { const std::set& fds = fPowerMonitors[i]->FDs(); for (std::set::iterator it = fds.begin(); it != fds.end(); ++it) { info[index].object = *it; info[index].type = B_OBJECT_TYPE_FD; info[index].events = B_EVENT_READ; descriptorMap[*it] = fPowerMonitors[i]; ++index; } } while (!fQuitRequested) { if (wait_for_objects(info, fdCount) < B_OK) continue; // handle events and reset events for (uint32 i = 0; i < fdCount; i++) { if (info[i].events & B_EVENT_READ) descriptorMap[info[i].object]->HandleEvent(info[i].object); else info[i].events = B_EVENT_READ; } } }