DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
Locker.cs
Go to the documentation of this file.
1 //
2 // Copyright 2010-2015 Deveel
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 using System;
18 using System.Collections.Generic;
19 
20 namespace Deveel.Data.Transactions {
21  public sealed class Locker {
22  private readonly Dictionary<object, LockingQueue> queuesMap = new Dictionary<object, LockingQueue>();
23 
24  public Locker(IDatabase database) {
25  Database = database;
26  }
27 
28  public IDatabase Database { get; private set; }
29 
30  private void AddToHandle(LockHandle handle, ILockable[] lockables, AccessType accessType, LockingMode mode) {
31  if (lockables == null)
32  return;
33 
34  for (int i = lockables.Length - 1; i >= 0; --i) {
35  var lockable = lockables[i];
36  var queue = GetQueueFor(lockable);
37 
38  // slightly confusing: this will add Lock to given table queue
39  var @lock = new Lock(queue, mode, accessType);
40  @lock.Acquire();
41  handle.AddLock(@lock);
42  }
43  }
44 
45  public LockHandle Lock(ILockable[] lockables, AccessType accessType, LockingMode mode) {
46  lock (this) {
47  int count = 0;
48  if ((accessType & AccessType.Read) != 0)
49  count += lockables.Length;
50  if ((accessType & AccessType.Write) != 0)
51  count += lockables.Length;
52 
53  var handle = new LockHandle(count);
54 
55  if ((accessType & AccessType.Read) != 0)
56  AddToHandle(handle, lockables, AccessType.Read, mode);
57 
58  if ((accessType & AccessType.Write) != 0)
59  AddToHandle(handle, lockables, AccessType.Write, mode);
60 
61  return handle;
62  }
63  }
64 
65  public LockHandle Lock(ILockable lockable, AccessType accessType, LockingMode mode) {
66  return Lock(new[] {lockable}, accessType, mode);
67  }
68 
69  public LockHandle LockRead(ILockable lockable, LockingMode mode) {
70  return Lock(lockable, AccessType.Read, mode);
71  }
72 
73  public LockHandle LockRead(ILockable[] lockables, LockingMode mode) {
74  return Lock(lockables, AccessType.Read, mode);
75  }
76 
77  public LockHandle LockWrite(ILockable lockable, LockingMode mode) {
78  return Lock(lockable, AccessType.Write, mode);
79  }
80 
81  public LockHandle LockWrite(ILockable[] lockables, LockingMode mode) {
82  return Lock(lockables, AccessType.Write, mode);
83  }
84 
85  public LockHandle Lock(ILockable[] toWrite, ILockable[] toRead, LockingMode mode) {
86  lock (this) {
87  int lockCount = toRead.Length + toWrite.Length;
88  LockHandle handle = new LockHandle(lockCount);
89 
90  AddToHandle(handle, toWrite, AccessType.Write, mode);
91  AddToHandle(handle, toRead, AccessType.Read, mode);
92 
93  return handle;
94  }
95  }
96 
97  private LockingQueue GetQueueFor(ILockable lockable) {
98  LockingQueue queue;
99 
100  if (!queuesMap.TryGetValue(lockable.RefId, out queue)) {
101  queue = new LockingQueue(lockable);
102  queuesMap[lockable.RefId] = queue;
103  }
104 
105  return queue;
106  }
107 
108  public void Unlock(LockHandle handle) {
109  lock (this) {
110  handle.Release();
111  }
112  }
113 
114  public void Reset() {
115  lock (this) {
116  queuesMap.Clear();
117  }
118  }
119 
120  public bool IsLocked(ILockable lockable) {
121  lock (this) {
122  LockingQueue queue;
123  if (!queuesMap.TryGetValue(lockable.RefId, out queue))
124  return false;
125 
126  return !queue.IsEmpty;
127  }
128  }
129  }
130 }
LockHandle LockRead(ILockable lockable, LockingMode mode)
Definition: Locker.cs:69
void Unlock(LockHandle handle)
Definition: Locker.cs:108
LockingQueue GetQueueFor(ILockable lockable)
Definition: Locker.cs:97
LockingMode
The mode applied to a lock over a resource during a transaction.
Definition: LockingMode.cs:24
LockHandle Lock(ILockable lockable, AccessType accessType, LockingMode mode)
Definition: Locker.cs:65
LockHandle LockRead(ILockable[] lockables, LockingMode mode)
Definition: Locker.cs:73
The default implementation of a database in a system.
Definition: Database.cs:38
bool IsLocked(ILockable lockable)
Definition: Locker.cs:120
The representation of a single database in the system.
Definition: IDatabase.cs:40
Locker(IDatabase database)
Definition: Locker.cs:24
LockHandle Lock(ILockable[] lockables, AccessType accessType, LockingMode mode)
Definition: Locker.cs:45
LockHandle LockWrite(ILockable lockable, LockingMode mode)
Definition: Locker.cs:77
LockHandle Lock(ILockable[] toWrite, ILockable[] toRead, LockingMode mode)
Definition: Locker.cs:85
LockHandle LockWrite(ILockable[] lockables, LockingMode mode)
Definition: Locker.cs:81
void AddToHandle(LockHandle handle, ILockable[] lockables, AccessType accessType, LockingMode mode)
Definition: Locker.cs:30