haiku/src/servers/power/power_daemon.cpp

129 lines
2.7 KiB
C++

/*
* 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 <Server.h>
#include <map>
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<int, PowerMonitor*> 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<int>& fds = fPowerMonitors[i]->FDs();
for (std::set<int>::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;
}
}
}