1 package locklib;
2
3 import ensure.Ensure;
4
5 /**
6 * The lock manager holds information about all locks currently held and all
7 * locks currently being waited for. The lock manager also keeps some auxiliary
8 * objects that handle specific features of the locking API such as the
9 * waiting queue factory, the lock pre-checker and the lock policy.
10 * @param <LockType> the type of lock
11 */
12 public class LockManager<LockType> {
13 /**
14 * The policy regulating how locks work.
15 */
16 private LockPolicy<LockType> m_policy;
17
18 /**
19 * Pre-checker used to check whether a request should be queued or should
20 * fail.
21 */
22 private LockPreChecker<LockType> m_pre_checker;
23
24 /**
25 * Factory that creates wait queues.
26 */
27 private WaitQueueFactory<LockType> m_queue_factory;
28
29 /**
30 * The API to provide to the targets.
31 */
32 private LockManagerListener<LockType> m_api;
33
34 /**
35 * Creates a new lock manager.
36 * @param p the lock policy
37 * @param pc the pre-checker to use; if <code>null</code>, the default
38 * pre-checker is used
39 * @param factory the wait factory to set; if <code>null</code>, the
40 * default factory is used
41 */
42 public LockManager(LockPolicy<LockType> p, LockPreChecker<LockType> pc,
43 WaitQueueFactory<LockType> factory) {
44 Ensure.not_null(p, "p == null");
45
46 m_policy = p;
47 m_pre_checker = pc;
48 if (pc == null) {
49 m_pre_checker = new NullLockPreChecker<>();
50 }
51
52 m_queue_factory = factory;
53 if (factory == null) {
54 m_queue_factory = new FifoWaitQueueFactory<>();
55 }
56
57 m_api = new LockManagerListener<LockType>() {
58 @Override
59 public void locked(LockGrant<LockType> g) {
60 m_pre_checker.locked(g);
61 }
62
63 @Override
64 public void unlocked(LockGrant<LockType> g) {
65 m_pre_checker.unlocked(g);
66 }
67 };
68 }
69
70 /**
71 * Obtains the lock manager API for reporting lock information. This
72 * method is package-protected because only targets should invoke these
73 * methods.
74 * @return the API
75 */
76 LockManagerListener<LockType> api() {
77 return m_api;
78 }
79
80 /**
81 * Obtains the wait queue factory.
82 * @return the wait queue factory
83 */
84 public WaitQueueFactory<LockType> wait_queue_factory() {
85 return m_queue_factory;
86 }
87
88 /**
89 * Obtains the currently defined lock pre-checker.
90 * @return the pre-checker
91 */
92 public LockPreChecker<LockType> pre_checker() {
93 return m_pre_checker;
94 }
95
96 /**
97 * Obtains the current lock policy.
98 * @return the lock policy
99 */
100 public LockPolicy<LockType> policy() {
101 return m_policy;
102 }
103 }