1 /* Copyright (C) 2009 Versant Inc. http://www.db4o.com */ 2 3 using System; 4 using System.Threading; 5 6 namespace Db4objects.Db4o.Foundation 7 { 8 #if CF 9 public class Lock4 10 { 11 private volatile Thread lockedByThread; 12 13 private volatile Thread waitReleased; 14 private volatile Thread closureReleased; 15 16 readonly AutoResetEvent waitEvent = new AutoResetEvent(false); 17 readonly AutoResetEvent closureEvent = new AutoResetEvent(false); 18 Awake()19 public void Awake() 20 { 21 AwakeWait(); 22 } 23 Run(IClosure4 closure4)24 public Object Run(IClosure4 closure4) 25 { 26 EnterClosure(); 27 try 28 { 29 return closure4.Run(); 30 } 31 finally 32 { 33 AwakeClosure(); 34 } 35 } 36 Snooze(long timeout)37 public void Snooze(long timeout) 38 { 39 AwakeClosure(); 40 WaitWait(timeout); 41 EnterClosure(); 42 } 43 EnterClosure()44 private void EnterClosure() 45 { 46 while (lockedByThread != Thread.CurrentThread) 47 { 48 while (!SetLock()) 49 { 50 WaitClosure(); 51 } 52 } 53 } 54 AwakeClosure()55 private void AwakeClosure() 56 { 57 lock (this) 58 { 59 RemoveLock(); 60 closureReleased = Thread.CurrentThread; 61 closureEvent.Set(); 62 Thread.Sleep(0); 63 if (closureReleased == Thread.CurrentThread) 64 { 65 closureEvent.Reset(); 66 } 67 } 68 } 69 AwakeWait()70 private void AwakeWait() 71 { 72 lock (this) 73 { 74 waitReleased = Thread.CurrentThread; 75 waitEvent.Set(); 76 Thread.Sleep(0); 77 if (waitReleased == Thread.CurrentThread) 78 { 79 waitEvent.Reset(); 80 } 81 } 82 } 83 WaitWait(long timeout)84 private void WaitWait(long timeout) 85 { 86 waitEvent.WaitOne((int) timeout, false); 87 waitReleased = Thread.CurrentThread; 88 } 89 WaitClosure()90 private void WaitClosure() 91 { 92 closureEvent.WaitOne(); 93 closureReleased = Thread.CurrentThread; 94 } 95 SetLock()96 private bool SetLock() 97 { 98 lock (this) 99 { 100 if (lockedByThread == null) 101 { 102 lockedByThread = Thread.CurrentThread; 103 return true; 104 } 105 return false; 106 } 107 } 108 RemoveLock()109 private void RemoveLock() 110 { 111 lock (this) 112 { 113 if (lockedByThread == Thread.CurrentThread) 114 { 115 lockedByThread = null; 116 } 117 } 118 } 119 } 120 #endif 121 }