xref: /haiku/src/apps/cortex/support/ILockable.h (revision 1d9d47fc72028bb71b5f232a877231e59cfe2438)
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:						// constants
36 	enum lock_t {
37 		WRITE,
38 		READ
39 	};
40 
41 public:						// interface
42 	virtual bool lock(
43 		lock_t type=WRITE,
44 		bigtime_t timeout=B_INFINITE_TIMEOUT)=0;
45 
46 	virtual bool unlock(
47 		lock_t type=WRITE)=0;
48 
49 	virtual bool isLocked(
50 		lock_t type=WRITE) const=0;
51 };
52 
53 
54 
55 // a simple hands-free lock helper
56 
57 class Autolock {
58 public:				// *** ctor/dtor
59 	virtual ~Autolock() {
60 		ASSERT(m_target);
61 		if(m_locked)
62 			m_target->unlock();
63 	}
64 
65 	Autolock(ILockable& target) : m_target(&target) { init(); }
66 	Autolock(ILockable* target) : m_target( target) { init(); }
67 
68 	Autolock(const ILockable& target) :
69 		m_target(const_cast<ILockable*>(&target)) { init(); }
70 	Autolock(const ILockable* target) :
71 		m_target(const_cast<ILockable*>( target)) { init(); }
72 
73 private:
74 	void init() {
75 		ASSERT(m_target);
76 		m_locked = m_target->lock();
77 	}
78 
79 	ILockable*			m_target;
80 	bool						m_locked;
81 };
82 
83 __END_CORTEX_NAMESPACE
84 #endif /*__ILockable_H__*/
85