150 lines
2.4 KiB
C++
150 lines
2.4 KiB
C++
/*
|
|
* Copyright 2009-2015, Haiku, Inc. All Rights Reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* Clemens Zeidler, haiku@Clemens-Zeidler.de
|
|
*/
|
|
|
|
|
|
#include "DriverInterface.h"
|
|
|
|
#include <Autolock.h>
|
|
#include <Messenger.h>
|
|
|
|
|
|
Monitor::~Monitor()
|
|
{
|
|
}
|
|
|
|
|
|
status_t
|
|
Monitor::StartWatching(BHandler* target)
|
|
{
|
|
if (fWatcherList.HasItem(target))
|
|
return B_ERROR;
|
|
|
|
fWatcherList.AddItem(target);
|
|
return B_OK;
|
|
}
|
|
|
|
|
|
status_t
|
|
Monitor::StopWatching(BHandler* target)
|
|
{
|
|
return fWatcherList.RemoveItem(target);
|
|
}
|
|
|
|
|
|
void
|
|
Monitor::Broadcast(uint32 message)
|
|
{
|
|
for (int i = 0; i < fWatcherList.CountItems(); i++) {
|
|
BMessenger messenger(fWatcherList.ItemAt(i));
|
|
messenger.SendMessage(message);
|
|
}
|
|
}
|
|
|
|
|
|
// #pragma mark -
|
|
|
|
|
|
PowerStatusDriverInterface::PowerStatusDriverInterface()
|
|
:
|
|
fIsWatching(0),
|
|
fWaitSem(-1),
|
|
fThread(-1),
|
|
fListLocker("driver list")
|
|
{
|
|
}
|
|
|
|
|
|
PowerStatusDriverInterface::~PowerStatusDriverInterface()
|
|
{
|
|
}
|
|
|
|
|
|
status_t
|
|
PowerStatusDriverInterface::StartWatching(BHandler* target)
|
|
{
|
|
BAutolock autolock(fListLocker);
|
|
|
|
status_t status = Monitor::StartWatching(target);
|
|
if (status != B_OK)
|
|
return status;
|
|
|
|
if (fThread > 0)
|
|
return B_OK;
|
|
|
|
fThread = spawn_thread(&_ThreadWatchPowerFunction, "PowerStatusThread",
|
|
B_LOW_PRIORITY, this);
|
|
if (fThread >= 0) {
|
|
fWaitSem = create_sem(0, "power status wait");
|
|
|
|
atomic_set(&fIsWatching, 1);
|
|
status = resume_thread(fThread);
|
|
} else
|
|
return fThread;
|
|
|
|
if (status != B_OK && fWatcherList.CountItems() == 0) {
|
|
atomic_set(&fIsWatching, 0);
|
|
delete_sem(fWaitSem);
|
|
|
|
fThread = -1;
|
|
fWaitSem = -1;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
status_t
|
|
PowerStatusDriverInterface::StopWatching(BHandler* target)
|
|
{
|
|
if (fThread < 0)
|
|
return B_BAD_VALUE;
|
|
|
|
fListLocker.Lock();
|
|
|
|
if (fWatcherList.CountItems() == 1) {
|
|
fListLocker.Unlock();
|
|
Disconnect();
|
|
} else
|
|
fListLocker.Unlock();
|
|
|
|
return Monitor::StopWatching(target);
|
|
}
|
|
|
|
|
|
void
|
|
PowerStatusDriverInterface::Broadcast(uint32 message)
|
|
{
|
|
BAutolock autolock(fListLocker);
|
|
Monitor::Broadcast(message);
|
|
}
|
|
|
|
|
|
void
|
|
PowerStatusDriverInterface::Disconnect()
|
|
{
|
|
if (fThread < 0)
|
|
return;
|
|
|
|
atomic_set(&fIsWatching, 0);
|
|
delete_sem(fWaitSem);
|
|
|
|
wait_for_thread(fThread, NULL);
|
|
fThread = -1;
|
|
fWaitSem = -1;
|
|
}
|
|
|
|
|
|
int32
|
|
PowerStatusDriverInterface::_ThreadWatchPowerFunction(void* data)
|
|
{
|
|
PowerStatusDriverInterface* that = (PowerStatusDriverInterface*)data;
|
|
that->_WatchPowerStatus();
|
|
return 0;
|
|
}
|
|
|