xref: /haiku/src/apps/cortex/support/ILockable.h (revision cfc3fa87da824bdf593eb8b817a83b6376e77935)
1 // ILockable.h (Cortex)
2 // * PURPOSE
3 //   Simple interface by which an object's locking capabilites
4 //   are declared/exposed.  Includes support for multiple lock
5 //   modes (read/write) which objects can choose to support if
6 //   they wish.
7 //
8 // * IMPLEMENTATION/USAGE
9 //   Implementations are expected to follow the rules described
10 //   in the MultiLock documentation (Be Developer Newsletter
11 //   Vol.2 #36, Sep '98).  In brief: write locks can be nested
12 //   (a thread holding the write lock may nest as many read or
13 //   or write locks as it likes) but read locks may not (only one
14 //   per thread.)
15 //
16 //   If using a simple BLocker to implement, ignore the mode.
17 //
18 // * HISTORY
19 //   e.moon		26jul99		Moved Autolock into this file to
20 //											resolve header-naming conflict.
21 //   e.moon		7jul99		Reworked slightly for Cortex.
22 //   e.moon		13apr99		Begun (beDub)
23 
24 #ifndef __ILockable_H__
25 #define __ILockable_H__
26 
27 #include <Debug.h>
28 
29 #include "cortex_defs.h"
30 __BEGIN_CORTEX_NAMESPACE
31 
32 // the locking interface
33 
34 class ILockable {
35 public:
36 	ILockable() { }
37 	virtual ~ILockable() { }
38 public:						// constants
39 	enum lock_t {
40 		WRITE,
41 		READ
42 	};
43 
44 public:						// interface
45 	virtual bool lock(
46 		lock_t type=WRITE,
47 		bigtime_t timeout=B_INFINITE_TIMEOUT)=0;
48 
49 	virtual bool unlock(
50 		lock_t type=WRITE)=0;
51 
52 	virtual bool isLocked(
53 		lock_t type=WRITE) const=0;
54 };
55 
56 
57 
58 // a simple hands-free lock helper
59 
60 class Autolock {
61 public:				// *** ctor/dtor
62 	virtual ~Autolock() {
63 		ASSERT(m_target);
64 		if(m_locked)
65 			m_target->unlock();
66 	}
67 
68 	Autolock(ILockable& target) : m_target(&target) { init(); }
69 	Autolock(ILockable* target) : m_target( target) { init(); }
70 
71 	Autolock(const ILockable& target) :
72 		m_target(const_cast<ILockable*>(&target)) { init(); }
73 	Autolock(const ILockable* target) :
74 		m_target(const_cast<ILockable*>( target)) { init(); }
75 
76 private:
77 	void init() {
78 		ASSERT(m_target);
79 		m_locked = m_target->lock();
80 	}
81 
82 	ILockable*			m_target;
83 	bool						m_locked;
84 };
85 
86 __END_CORTEX_NAMESPACE
87 #endif /*__ILockable_H__*/
88