View Javadoc
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 }