Lucene.Net  3.0.3
Lucene.Net is a port of the Lucene search engine library, written in C# and targeted at .NET runtime users.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
VerifyingLockFactory.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 using System;
19 
20 namespace Lucene.Net.Store
21 {
22 
23  /// <summary> A <see cref="LockFactory" /> that wraps another <see cref="LockFactory" />
24  /// and verifies that each lock obtain/release
25  /// is "correct" (never results in two processes holding the
26  /// lock at the same time). It does this by contacting an
27  /// external server (<see cref="LockVerifyServer" />) to assert that
28  /// at most one process holds the lock at a time. To use
29  /// this, you should also run <see cref="LockVerifyServer" /> on the
30  /// host &amp; port matching what you pass to the constructor.
31  ///
32  /// </summary>
33  /// <seealso cref="LockVerifyServer">
34  /// </seealso>
35  /// <seealso cref="LockStressTest">
36  /// </seealso>
37 
39  {
40 
41  internal LockFactory lf;
42  internal sbyte id;
43  internal System.String host;
44  internal int port;
45 
46  private class CheckedLock:Lock
47  {
48  private void InitBlock(VerifyingLockFactory enclosingInstance)
49  {
50  this.enclosingInstance = enclosingInstance;
51  }
52  private VerifyingLockFactory enclosingInstance;
53  public VerifyingLockFactory Enclosing_Instance
54  {
55  get
56  {
57  return enclosingInstance;
58  }
59 
60  }
61  private Lock lock_Renamed;
62 
63  public CheckedLock(VerifyingLockFactory enclosingInstance, Lock lock_Renamed)
64  {
65  InitBlock(enclosingInstance);
66  this.lock_Renamed = lock_Renamed;
67  }
68 
69  private void Verify(sbyte message)
70  {
71  try
72  {
73  System.Net.Sockets.TcpClient s = new System.Net.Sockets.TcpClient(Enclosing_Instance.host, Enclosing_Instance.port);
74  System.IO.Stream out_Renamed = s.GetStream();
75  out_Renamed.WriteByte((byte) Enclosing_Instance.id);
76  out_Renamed.WriteByte((byte) message);
77  System.IO.Stream in_Renamed = s.GetStream();
78  int result = in_Renamed.ReadByte();
79  in_Renamed.Close();
80  out_Renamed.Close();
81  s.Close();
82  if (result != 0)
83  throw new System.SystemException("lock was double acquired");
84  }
85  catch (System.Exception e)
86  {
87  throw new System.SystemException(e.Message, e);
88  }
89  }
90 
91  public override bool Obtain(long lockWaitTimeout)
92  {
93  lock (this)
94  {
95  bool obtained = lock_Renamed.Obtain(lockWaitTimeout);
96  if (obtained)
97  Verify((sbyte) 1);
98  return obtained;
99  }
100  }
101 
102  public override bool Obtain()
103  {
104  lock (this)
105  {
106  return lock_Renamed.Obtain();
107  }
108  }
109 
110  public override bool IsLocked()
111  {
112  lock (this)
113  {
114  return lock_Renamed.IsLocked();
115  }
116  }
117 
118  public override void Release()
119  {
120  lock (this)
121  {
122  if (IsLocked())
123  {
124  Verify((sbyte) 0);
125  lock_Renamed.Release();
126  }
127  }
128  }
129  }
130 
131  /// <param name="id">should be a unique id across all clients
132  /// </param>
133  /// <param name="lf">the LockFactory that we are testing
134  /// </param>
135  /// <param name="host">host or IP where <see cref="LockVerifyServer" />
136  /// is running
137  /// </param>
138  /// <param name="port">the port <see cref="LockVerifyServer" /> is
139  /// listening on
140  /// </param>
141  public VerifyingLockFactory(sbyte id, LockFactory lf, System.String host, int port)
142  {
143  this.id = id;
144  this.lf = lf;
145  this.host = host;
146  this.port = port;
147  }
148 
149  public override Lock MakeLock(System.String lockName)
150  {
151  lock (this)
152  {
153  return new CheckedLock(this, lf.MakeLock(lockName));
154  }
155  }
156 
157  public override void ClearLock(System.String lockName)
158  {
159  lock (this)
160  {
161  lf.ClearLock(lockName);
162  }
163  }
164  }
165 }