vfs: check userland buffers before reading them.
[haiku.git] / src / apps / powerstatus / DriverInterface.cpp
blob2fab52866f52320b42e3bfca8af414318da1a26c
1 /*
2 * Copyright 2009-2015, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Clemens Zeidler, haiku@Clemens-Zeidler.de
7 */
10 #include "DriverInterface.h"
12 #include <Autolock.h>
13 #include <Messenger.h>
16 Monitor::~Monitor()
21 status_t
22 Monitor::StartWatching(BHandler* target)
24 if (fWatcherList.HasItem(target))
25 return B_ERROR;
27 fWatcherList.AddItem(target);
28 return B_OK;
32 status_t
33 Monitor::StopWatching(BHandler* target)
35 return fWatcherList.RemoveItem(target);
39 void
40 Monitor::Broadcast(uint32 message)
42 for (int i = 0; i < fWatcherList.CountItems(); i++) {
43 BMessenger messenger(fWatcherList.ItemAt(i));
44 messenger.SendMessage(message);
49 // #pragma mark -
52 PowerStatusDriverInterface::PowerStatusDriverInterface()
54 fIsWatching(0),
55 fWaitSem(-1),
56 fThread(-1),
57 fListLocker("driver list")
62 PowerStatusDriverInterface::~PowerStatusDriverInterface()
67 status_t
68 PowerStatusDriverInterface::StartWatching(BHandler* target)
70 BAutolock autolock(fListLocker);
72 status_t status = Monitor::StartWatching(target);
73 if (status != B_OK)
74 return status;
76 if (fThread > 0)
77 return B_OK;
79 fThread = spawn_thread(&_ThreadWatchPowerFunction, "PowerStatusThread",
80 B_LOW_PRIORITY, this);
81 if (fThread >= 0) {
82 fWaitSem = create_sem(0, "power status wait");
84 atomic_set(&fIsWatching, 1);
85 status = resume_thread(fThread);
86 } else
87 return fThread;
89 if (status != B_OK && fWatcherList.CountItems() == 0) {
90 atomic_set(&fIsWatching, 0);
91 delete_sem(fWaitSem);
93 fThread = -1;
94 fWaitSem = -1;
97 return status;
101 status_t
102 PowerStatusDriverInterface::StopWatching(BHandler* target)
104 if (fThread < 0)
105 return B_BAD_VALUE;
107 fListLocker.Lock();
109 if (fWatcherList.CountItems() == 1) {
110 fListLocker.Unlock();
111 Disconnect();
112 } else
113 fListLocker.Unlock();
115 return Monitor::StopWatching(target);
119 void
120 PowerStatusDriverInterface::Broadcast(uint32 message)
122 BAutolock autolock(fListLocker);
123 Monitor::Broadcast(message);
127 void
128 PowerStatusDriverInterface::Disconnect()
130 if (fThread < 0)
131 return;
133 atomic_set(&fIsWatching, 0);
134 delete_sem(fWaitSem);
136 wait_for_thread(fThread, NULL);
137 fThread = -1;
138 fWaitSem = -1;
142 int32
143 PowerStatusDriverInterface::_ThreadWatchPowerFunction(void* data)
145 PowerStatusDriverInterface* that = (PowerStatusDriverInterface*)data;
146 that->_WatchPowerStatus();
147 return 0;