vfs: check userland buffers before reading them.
[haiku.git] / headers / private / shared / Thread.h
blob7a47213dd962db40a95ba462d04afd7dacc0c497
1 /*
2 Open Tracker License
4 Terms and Conditions
6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30 of Be Incorporated in the United States and other countries. Other brand product
31 names are registered trademarks or trademarks of their respective holders.
32 All rights reserved.
34 #ifndef __THREAD__
35 #define __THREAD__
38 #include <Debug.h>
39 #include <Looper.h>
40 #include <OS.h>
42 #include "ObjectList.h"
43 #include "FunctionObject.h"
46 namespace BPrivate {
48 class MessengerAutoLocker {
49 // move this into AutoLock.h
50 public:
51 MessengerAutoLocker(BMessenger* messenger)
52 : fMessenger(messenger),
53 fHasLock(messenger->LockTarget())
56 ~MessengerAutoLocker()
58 Unlock();
61 bool operator!() const
63 return !fHasLock;
66 bool IsLocked() const
68 return fHasLock;
71 void Unlock()
73 if (fHasLock) {
74 BLooper* looper;
75 fMessenger->Target(&looper);
76 if (looper)
77 looper->Unlock();
78 fHasLock = false;
82 private:
83 BMessenger* fMessenger;
84 bool fHasLock;
88 class SimpleThread {
89 // this should only be used as a base class,
90 // subclass needs to add proper locking mechanism
91 public:
92 SimpleThread(int32 priority = B_LOW_PRIORITY, const char* name = 0);
93 virtual ~SimpleThread();
95 void Go();
97 private:
98 static status_t RunBinder(void*);
99 virtual void Run() = 0;
101 protected:
102 thread_id fScanThread;
103 int32 fPriority;
104 const char* fName;
108 class Thread : private SimpleThread {
109 public:
110 static void Launch(FunctionObject* functor,
111 int32 priority = B_LOW_PRIORITY, const char* name = 0);
113 private:
114 Thread(FunctionObject*, int32 priority, const char* name);
115 ~Thread();
116 virtual void Run();
118 FunctionObject* fFunctor;
122 class ThreadSequence : private SimpleThread {
123 public:
124 static void Launch(BObjectList<FunctionObject>*, bool async = true,
125 int32 priority = B_LOW_PRIORITY);
127 private:
128 ThreadSequence(BObjectList<FunctionObject>*, int32 priority);
129 ~ThreadSequence();
131 virtual void Run();
132 static void Run(BObjectList<FunctionObject>*list);
134 BObjectList<FunctionObject>* fFunctorList;
138 // would use SingleParamFunctionObjectWithResult, except mwcc won't handle this
139 template <class Param1>
140 class SingleParamFunctionObjectWorkaround : public
141 FunctionObjectWithResult<status_t> {
142 public:
143 SingleParamFunctionObjectWorkaround(
144 status_t (*function)(Param1), Param1 param1)
145 : fFunction(function),
146 fParam1(param1)
150 virtual void operator()()
151 { (fFunction)(fParam1); }
153 virtual ulong Size() const { return sizeof(*this); }
155 private:
156 status_t (*fFunction)(Param1);
157 Param1 fParam1;
161 template <class T>
162 class SimpleMemberFunctionObjectWorkaround : public
163 FunctionObjectWithResult<status_t> {
164 public:
165 SimpleMemberFunctionObjectWorkaround(status_t (T::*function)(), T* onThis)
166 : fFunction(function),
167 fOnThis(onThis)
171 virtual void operator()()
172 { (fOnThis->*fFunction)(); }
174 virtual ulong Size() const { return sizeof(*this); }
176 private:
177 status_t (T::*fFunction)();
178 T fOnThis;
182 template <class Param1, class Param2>
183 class TwoParamFunctionObjectWorkaround : public
184 FunctionObjectWithResult<status_t> {
185 public:
186 TwoParamFunctionObjectWorkaround(status_t (*callThis)(Param1, Param2),
187 Param1 param1, Param2 param2)
188 : function(callThis),
189 fParam1(param1),
190 fParam2(param2)
194 virtual void operator()()
195 { (function)(fParam1, fParam2); }
197 virtual uint32 Size() const { return sizeof(*this); }
199 private:
200 status_t (*function)(Param1, Param2);
201 Param1 fParam1;
202 Param2 fParam2;
206 template <class Param1, class Param2, class Param3>
207 class ThreeParamFunctionObjectWorkaround : public
208 FunctionObjectWithResult<status_t> {
209 public:
210 ThreeParamFunctionObjectWorkaround(
211 status_t (*callThis)(Param1, Param2, Param3),
212 Param1 param1, Param2 param2, Param3 param3)
213 : function(callThis),
214 fParam1(param1),
215 fParam2(param2),
216 fParam3(param3)
220 virtual void operator()()
221 { (function)(fParam1, fParam2, fParam3); }
223 virtual uint32 Size() const { return sizeof(*this); }
225 private:
226 status_t (*function)(Param1, Param2, Param3);
227 Param1 fParam1;
228 Param2 fParam2;
229 Param3 fParam3;
233 template <class Param1, class Param2, class Param3, class Param4>
234 class FourParamFunctionObjectWorkaround : public
235 FunctionObjectWithResult<status_t> {
236 public:
237 FourParamFunctionObjectWorkaround(
238 status_t (*callThis)(Param1, Param2, Param3, Param4),
239 Param1 param1, Param2 param2, Param3 param3, Param4 param4)
240 : function(callThis),
241 fParam1(param1),
242 fParam2(param2),
243 fParam3(param3),
244 fParam4(param4)
248 virtual void operator()()
249 { (function)(fParam1, fParam2, fParam3, fParam4); }
251 virtual uint32 Size() const { return sizeof(*this); }
253 private:
254 status_t (*function)(Param1, Param2, Param3, Param4);
255 Param1 fParam1;
256 Param2 fParam2;
257 Param3 fParam3;
258 Param4 fParam4;
262 template<class Param1>
263 void
264 LaunchInNewThread(const char* name, int32 priority, status_t (*func)(Param1),
265 Param1 p1)
267 Thread::Launch(new SingleParamFunctionObjectWorkaround<Param1>(func, p1),
268 priority, name);
272 template<class T>
273 void
274 LaunchInNewThread(const char* name, int32 priority, status_t (T::*function)(),
275 T* onThis)
277 Thread::Launch(new SimpleMemberFunctionObjectWorkaround<T>(function,
278 onThis), priority, name);
282 template<class Param1, class Param2>
283 void
284 LaunchInNewThread(const char* name, int32 priority,
285 status_t (*func)(Param1, Param2),
286 Param1 p1, Param2 p2)
288 Thread::Launch(new
289 TwoParamFunctionObjectWorkaround<Param1, Param2>(func, p1, p2),
290 priority, name);
294 template<class Param1, class Param2, class Param3>
295 void
296 LaunchInNewThread(const char* name, int32 priority,
297 status_t (*func)(Param1, Param2, Param3),
298 Param1 p1, Param2 p2, Param3 p3)
300 Thread::Launch(new ThreeParamFunctionObjectWorkaround<Param1, Param2,
301 Param3>(func, p1, p2, p3), priority, name);
305 template<class Param1, class Param2, class Param3, class Param4>
306 void
307 LaunchInNewThread(const char* name, int32 priority,
308 status_t (*func)(Param1, Param2, Param3, Param4),
309 Param1 p1, Param2 p2, Param3 p3, Param4 p4)
311 Thread::Launch(new FourParamFunctionObjectWorkaround<Param1, Param2,
312 Param3, Param4>(func, p1, p2, p3, p4), priority, name);
316 template<class View>
317 class MouseDownThread {
318 public:
319 static void TrackMouse(View* view, void (View::*)(BPoint),
320 void (View::*)(BPoint, uint32) = 0,
321 bigtime_t pressingPeriod = 100000);
323 protected:
324 MouseDownThread(View* view, void (View::*)(BPoint),
325 void (View::*)(BPoint, uint32), bigtime_t pressingPeriod);
327 virtual ~MouseDownThread();
329 void Go();
330 virtual void Track();
332 static status_t TrackBinder(void*);
334 private:
335 BMessenger fOwner;
336 void (View::*fDonePressing)(BPoint);
337 void (View::*fPressing)(BPoint, uint32);
338 bigtime_t fPressingPeriod;
339 volatile thread_id fThreadID;
343 template<class View>
344 void
345 MouseDownThread<View>::TrackMouse(View* view,
346 void(View::*donePressing)(BPoint),
347 void(View::*pressing)(BPoint, uint32), bigtime_t pressingPeriod)
349 (new MouseDownThread(view, donePressing, pressing, pressingPeriod))->Go();
353 template<class View>
354 MouseDownThread<View>::MouseDownThread(View* view,
355 void (View::*donePressing)(BPoint),
356 void (View::*pressing)(BPoint, uint32), bigtime_t pressingPeriod)
357 : fOwner(view, view->Window()),
358 fDonePressing(donePressing),
359 fPressing(pressing),
360 fPressingPeriod(pressingPeriod)
365 template<class View>
366 MouseDownThread<View>::~MouseDownThread()
371 template<class View>
372 void
373 MouseDownThread<View>::Go()
375 fThreadID = spawn_thread(&MouseDownThread::TrackBinder,
376 "MouseTrackingThread", B_NORMAL_PRIORITY, this);
378 if (fThreadID <= 0 || resume_thread(fThreadID) != B_OK)
379 // didn't start, don't leak self
380 delete this;
384 template<class View>
385 status_t
386 MouseDownThread<View>::TrackBinder(void* castToThis)
388 MouseDownThread* self = static_cast<MouseDownThread*>(castToThis);
389 self->Track();
390 // dead at this point
391 return B_OK;
395 template<class View>
396 void
397 MouseDownThread<View>::Track()
399 for (;;) {
400 MessengerAutoLocker lock(&fOwner);
401 if (!lock)
402 break;
404 BLooper* looper;
405 View* view = dynamic_cast<View*>(fOwner.Target(&looper));
406 if (!view)
407 break;
409 uint32 buttons;
410 BPoint location;
411 view->GetMouse(&location, &buttons, false);
412 if (!buttons) {
413 (view->*fDonePressing)(location);
414 break;
416 if (fPressing)
417 (view->*fPressing)(location, buttons);
419 lock.Unlock();
420 snooze(fPressingPeriod);
423 delete this;
427 } // namespace BPrivate
429 using namespace BPrivate;
431 #endif // __THREAD__