vfs: check userland buffers before reading them.
[haiku.git] / headers / private / shared / RWLockManager.h
blobde62004a299213b5fc46323988014096a012c1a6
1 /*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5 #ifndef _RW_LOCK_MANAGER_H
6 #define _RW_LOCK_MANAGER_H
8 #include <Locker.h>
10 #include <util/DoublyLinkedList.h>
13 namespace BPrivate {
16 class RWLockManager;
19 class RWLockable {
20 public:
21 RWLockable();
23 private:
24 struct Waiter : DoublyLinkedListLinkImpl<Waiter> {
25 Waiter(bool writer)
27 thread(find_thread(NULL)),
28 writer(writer),
29 queued(false)
33 thread_id thread;
34 status_t status;
35 bool writer;
36 bool queued;
39 typedef DoublyLinkedList<Waiter> WaiterList;
41 friend class RWLockManager;
43 private:
44 thread_id fOwner;
45 int32 fOwnerCount;
46 int32 fReaderCount;
47 WaiterList fWaiters;
51 class RWLockManager {
52 public:
53 RWLockManager();
54 ~RWLockManager();
56 status_t Init() { return fLock.InitCheck(); }
58 bool Lock() { return fLock.Lock(); }
59 void Unlock() { return fLock.Unlock(); }
61 bool ReadLock(RWLockable* lockable);
62 bool TryReadLock(RWLockable* lockable);
63 status_t ReadLockWithTimeout(RWLockable* lockable,
64 bigtime_t timeout);
65 void ReadUnlock(RWLockable* lockable);
67 bool WriteLock(RWLockable* lockable);
68 bool TryWriteLock(RWLockable* lockable);
69 status_t WriteLockWithTimeout(RWLockable* lockable,
70 bigtime_t timeout);
71 void WriteUnlock(RWLockable* lockable);
73 inline bool GenericLock(bool write, RWLockable* lockable);
74 inline bool TryGenericLock(bool write,
75 RWLockable* lockable);
76 inline status_t GenericLockWithTimeout(bool write,
77 RWLockable* lockable, bigtime_t timeout);
78 inline void GenericUnlock(bool write, RWLockable* lockable);
80 private:
81 status_t _Wait(RWLockable* lockable, bool writer,
82 bigtime_t timeout);
83 void _Unblock(RWLockable* lockable);
85 private:
86 BLocker fLock;
90 inline bool
91 RWLockManager::GenericLock(bool write, RWLockable* lockable)
93 return write ? WriteLock(lockable) : ReadLock(lockable);
97 inline bool
98 RWLockManager::TryGenericLock(bool write, RWLockable* lockable)
100 return write ? TryWriteLock(lockable) : TryReadLock(lockable);
104 inline status_t
105 RWLockManager::GenericLockWithTimeout(bool write, RWLockable* lockable,
106 bigtime_t timeout)
108 return write
109 ? WriteLockWithTimeout(lockable, timeout)
110 : ReadLockWithTimeout(lockable, timeout);
114 inline void
115 RWLockManager::GenericUnlock(bool write, RWLockable* lockable)
117 if (write)
118 WriteUnlock(lockable);
119 else
120 ReadUnlock(lockable);
124 } // namespace BPrivate
127 using BPrivate::RWLockable;
128 using BPrivate::RWLockManager;
131 #endif // _RW_LOCK_MANAGER_H