My favorites | Sign in
Project Home Downloads Issues Source
Repository:
Checkout   Browse   Changes   Clones    
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#region Copyright 2010-2011 by Roger Knapp, Licensed under the Apache License, Version 2.0
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#endregion
#define SUPPORT_RECURSION
using System;
using System.Threading;

namespace CSharpTest.Net.Synchronization
{
/// <summary>
/// provides a simple and fast, writer only lock, request for read immediatly return true.
/// </summary>
public class ReservedWriteLocking<T> : ReservedWriteLocking
where T : ILockStrategy, new()
{
/// <summary> Constructs the reader-writer lock using a new T() </summary>
public ReservedWriteLocking() : base(new T())
{ }
}

/// <summary>
/// provides a simple and fast, writer only lock, request for read immediatly return true.
/// </summary>
public class ReservedWriteLocking : ILockStrategy
{
/// <summary> The syncronization object writers and potential readers use to lock </summary>
object _sync;
/// <summary> The underlying lock that will be acquired directly by Read() and after the 2nd call to Write() </summary>
ILockStrategy _lock;
/// <summary> The current count of the calls to Write() </summary>
int _writeCount;

/// <summary>
/// Constructs the reader-writer lock using the lock provided
/// </summary>
public ReservedWriteLocking(ILockStrategy lck)
{
_sync = this;
_lock = Check.NotNull(lck);
}

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public virtual void Dispose()
{
object exit = Interlocked.Exchange(ref _sync, null);
if (exit == null)
return;

_lock.Dispose();
Check.Assert<InvalidOperationException>(_writeCount == 0);
}

/// <summary> Changes every time a write lock is aquired. If WriteVersion == 0, no write locks have been issued. </summary>
public int WriteVersion { get { return _lock.WriteVersion; } }

/// <summary>
/// Returns true if the lock was successfully obtained within the timeout specified
/// </summary>
public bool TryRead(int millisecondsTimeout)
{
return _lock.TryRead(millisecondsTimeout);
}

/// <summary>
/// Releases a read lock
/// </summary>
public void ReleaseRead()
{
_lock.ReleaseRead();
}

/// <summary>
/// The first call reserves the Write lock for the current thread but does not stop reader access
/// until the write lock is acquired again.
/// </summary>
public virtual bool TryWrite(int millisecondsTimeout)
{
if (_sync == null) throw new ObjectDisposedException(GetType().FullName);
// First obtain the 'writer lock':

if (!Monitor.TryEnter(_sync, millisecondsTimeout))
return false;
if (_writeCount == 0)
{
_writeCount++;
return true;
}
if (_lock.TryWrite(millisecondsTimeout))
{
_writeCount++;
return true;
}
return false;
}

/// <summary>
/// Releases a writer lock
/// </summary>
public void ReleaseWrite()
{
Check.Assert<InvalidOperationException>(_writeCount > 0);
_writeCount--;

if (_writeCount > 0)
_lock.ReleaseWrite();

Monitor.Exit(_sync);
}

/// <summary>
/// Returns a reader lock that can be elevated to a write lock
/// </summary>
public ReadLock Read() { return ReadLock.Acquire(this, -1); }

/// <summary>
/// Returns a reader lock that can be elevated to a write lock
/// </summary>
/// <exception cref="System.TimeoutException"/>
public ReadLock Read(int millisecondsTimeout) { return ReadLock.Acquire(this, millisecondsTimeout); }

/// <summary>
/// Returns a read and write lock
/// </summary>
public WriteLock Write() { return WriteLock.Acquire(this, -1); }

/// <summary>
/// Returns a read and write lock
/// </summary>
/// <exception cref="System.TimeoutException"/>
public WriteLock Write(int millisecondsTimeout) { return WriteLock.Acquire(this, millisecondsTimeout); }
}
}

Change log

59104bd26e63 by rogerk on Apr 26, 2011   Diff
Release version 1.11.426.305
Go to: 
Project members, sign in to write a code review

Older revisions

All revisions of this file

File info

Size: 5266 bytes, 145 lines
Powered by Google Project Hosting