1/* 2 * Copyright 2009, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Clemens Zeidler, haiku@Clemens-Zeidler.de 7 */ 8 9 10#include "DriverInterface.h" 11 12#include <Autolock.h> 13#include <Messenger.h> 14 15 16Monitor::~Monitor() 17{ 18} 19 20 21status_t 22Monitor::StartWatching(BHandler* target) 23{ 24 if (fWatcherList.HasItem(target)) 25 return B_ERROR; 26 27 fWatcherList.AddItem(target); 28 return B_OK; 29} 30 31 32status_t 33Monitor::StopWatching(BHandler* target) 34{ 35 return fWatcherList.RemoveItem(target); 36} 37 38 39void 40Monitor::Broadcast(uint32 message) 41{ 42 for (int i = 0; i < fWatcherList.CountItems(); i++) { 43 BMessenger messenger(fWatcherList.ItemAt(i)); 44 messenger.SendMessage(message); 45 } 46} 47 48 49// #pragma mark - 50 51 52PowerStatusDriverInterface::PowerStatusDriverInterface() 53 : 54 fIsWatching(0), 55 fWaitSem(-1), 56 fThread(-1) 57{ 58} 59 60 61PowerStatusDriverInterface::~PowerStatusDriverInterface() 62{ 63} 64 65 66status_t 67PowerStatusDriverInterface::StartWatching(BHandler* target) 68{ 69 BAutolock autolock(fListLocker); 70 71 status_t status = Monitor::StartWatching(target); 72 if (status != B_OK) 73 return status; 74 75 if (fThread > 0) 76 return B_OK; 77 78 fThread = spawn_thread(&_ThreadWatchPowerFunction, "PowerStatusThread", 79 B_LOW_PRIORITY, this); 80 if (fThread >= 0) { 81 fWaitSem = create_sem(0, "power status wait"); 82 83 atomic_set(&fIsWatching, 1); 84 status = resume_thread(fThread); 85 } else 86 return fThread; 87 88 if (status != B_OK && fWatcherList.CountItems() == 0) { 89 atomic_set(&fIsWatching, 0); 90 delete_sem(fWaitSem); 91 92 fThread = -1; 93 fWaitSem = -1; 94 } 95 96 return status; 97} 98 99 100status_t 101PowerStatusDriverInterface::StopWatching(BHandler* target) 102{ 103 if (fThread < 0) 104 return B_BAD_VALUE; 105 106 fListLocker.Lock(); 107 108 if (fWatcherList.CountItems() == 1) { 109 fListLocker.Unlock(); 110 Disconnect(); 111 } else 112 fListLocker.Unlock(); 113 114 return Monitor::StopWatching(target); 115} 116 117 118void 119PowerStatusDriverInterface::Broadcast(uint32 message) 120{ 121 BAutolock autolock(fListLocker); 122 Monitor::Broadcast(message); 123} 124 125 126void 127PowerStatusDriverInterface::Disconnect() 128{ 129 if (fThread < 0) 130 return; 131 132 atomic_set(&fIsWatching, 0); 133 delete_sem(fWaitSem); 134 135 wait_for_thread(fThread, NULL); 136 fThread = -1; 137 fWaitSem = -1; 138} 139 140 141int32 142PowerStatusDriverInterface::_ThreadWatchPowerFunction(void* data) 143{ 144 PowerStatusDriverInterface* that = (PowerStatusDriverInterface*)data; 145 that->_WatchPowerStatus(); 146 return 0; 147} 148 149