public void BasicUsageTest() { Tuple<IList<int>, IList<int>> result = null; var evt = new ManualResetEventSlim (false); var actionBlock = new ActionBlock<Tuple<IList<int>, IList<int>>> (r => { result = r; evt.Set (); }); var block = new BatchedJoinBlock<int, int> (2); block.LinkTo (actionBlock); // both targets once Assert.IsTrue (block.Target1.Post (1)); Assert.IsFalse(evt.Wait(100)); Assert.IsNull (result); Assert.IsTrue (block.Target2.Post (2)); Assert.IsTrue (evt.Wait (100)); Assert.IsNotNull (result); CollectionAssert.AreEqual (new[] { 1 }, result.Item1); CollectionAssert.AreEqual (new[] { 2 }, result.Item2); result = null; evt.Reset (); // target 1 twice Assert.IsTrue (block.Target1.Post (3)); Assert.IsFalse(evt.Wait(100)); Assert.IsNull (result); Assert.IsTrue (block.Target1.Post (4)); Assert.IsTrue (evt.Wait (100)); Assert.IsNotNull (result); CollectionAssert.AreEqual (new[] { 3, 4 }, result.Item1); CollectionAssert.IsEmpty (result.Item2); result = null; evt.Reset (); // target 2 twice Assert.IsTrue (block.Target2.Post (5)); Assert.IsFalse(evt.Wait(100)); Assert.IsNull (result); Assert.IsTrue (block.Target2.Post (6)); Assert.IsTrue (evt.Wait (100)); Assert.IsNotNull (result); CollectionAssert.IsEmpty (result.Item1); CollectionAssert.AreEqual (new[] { 5, 6 }, result.Item2); }
/// <summary> /// Joins an IRC channel. Only one channel is supported at a time. /// </summary> /// <param name="channel"></param> public void Join(string channel) { // Leave current channel lock (_lockobject) { if (!String.IsNullOrEmpty(_currentChannel) && _state == ConnectionState.ChannelJoined) { WriteToServerStream($"PART {_currentChannel}"); _state = ConnectionState.Connected; } } _LookingforServerResponseEvent.Reset(); if (!channel.StartsWith("#")) { channel = "#" + channel; } WriteToServerStream($"JOIN {channel}"); _LookingforServerResponse = true; _LookingforServerResponseCode = 366; _LookingforServerResponseEvent.Wait(); // Successfully joined _currentChannel = channel; lock (_lockobject) { _state = ConnectionState.ChannelJoined; } }
// Validates init, set, reset state transitions. private static void RunManualResetEventSlimTest0_StateTrans(bool init) { ManualResetEventSlim ev = new ManualResetEventSlim(init); if (ev.IsSet != init) { Debug.WriteLine("* RunManualResetEventSlimTest0_StateTrans(init={0})", init); Assert.True(false, string.Format(" > FAILED. expected IsSet=={0}, but it's {1}", init, ev.IsSet)); } for (int i = 0; i < 50; i++) { ev.Set(); if (!ev.IsSet) { Debug.WriteLine("* RunManualResetEventSlimTest0_StateTrans(init={0})", init); Assert.True(false, string.Format(" > FAILED. expected IsSet, but it's false")); } ev.Reset(); if (ev.IsSet) { Debug.WriteLine("* RunManualResetEventSlimTest0_StateTrans(init={0})", init); Assert.True(false, string.Format(" > FAILED. expected !IsSet, but it's true")); } } }
public void MemberRemovedEvent() { var reset = new ManualResetEventSlim(); _client.GetCluster().AddMembershipListener(new MembershipListener { OnMemberAdded = memberAddedEvent => { reset.Set(); } }); var member = StartMember(_remoteController, _cluster); Assert.IsTrue(reset.Wait(30 * 1000)); reset.Reset(); MembershipEvent memberRemovedEvent = null; _client.GetCluster().AddMembershipListener(new MembershipListener { OnMemberRemoved = memberRemoved => { memberRemovedEvent = memberRemoved; reset.Set(); } }); StopMember(_remoteController, _cluster, member); Assert.IsTrue(reset.Wait(30*1000)); Assert.IsInstanceOf<ICluster>(memberRemovedEvent.Source); Assert.IsInstanceOf<ICluster>(memberRemovedEvent.GetCluster()); Assert.AreEqual(MembershipEvent.MemberRemoved, memberRemovedEvent.GetEventType()); Assert.IsNotNull(memberRemovedEvent.GetMember()); Assert.AreEqual(1, memberRemovedEvent.GetMembers().Count); }
public void TestTimerStartAutoReset() { using (var timer = new TestTimer(1)) { var mres = new ManualResetEventSlim(); int count = 0; int target = 1; timer.AutoReset = false; timer.Elapsed += (sender, e) => { if (Interlocked.Increment(ref count) == target) { mres.Set(); } }; timer.Start(); mres.Wait(); Assert.False(timer.Enabled, "Auto-reset timer should not be enabled after elapsed"); Assert.Equal(1, count); count = 0; target = 10; mres.Reset(); timer.AutoReset = true; mres.Wait(); timer.Stop(); Assert.InRange(count, target, int.MaxValue); } }
public void SuccessiveTimeoutTest(HostType hostType, TransportType transportType, MessageBusType messageBusType) { using (var host = CreateHost(hostType, transportType)) { // Arrange var mre = new ManualResetEventSlim(false); host.Initialize(keepAlive: 5, messageBusType: messageBusType); var connection = CreateConnection(host, "/my-reconnect"); using (connection) { connection.Reconnected += () => { mre.Set(); }; connection.Start(host.Transport).Wait(); ((Client.IConnection)connection).KeepAliveData = new KeepAliveData(TimeSpan.FromMilliseconds(500)); // Assert that Reconnected is called Assert.True(mre.Wait(TimeSpan.FromSeconds(15))); // Assert that Reconnected is called again mre.Reset(); Assert.True(mre.Wait(TimeSpan.FromSeconds(15))); // Clean-up mre.Dispose(); } } }
static void PrintFooBar(int p) { System.Threading.ManualResetEventSlim mres = new System.Threading.ManualResetEventSlim(false); // initialize as unsignaled System.Threading.ManualResetEventSlim mres2 = new System.Threading.ManualResetEventSlim(true); // initialize as unsignaled Thread t1 = new Thread(() => { for (int i = 0; i < 20; i++) { mres2.Wait(); Console.WriteLine("foo"); mres2.Reset(); mres.Set(); } } ); t1.Start(); Thread t2 = new Thread(() => { for (int i = 0; i < 20; i++) { mres.Wait();//true Console.WriteLine("bar"); mres.Reset(); mres2.Set(); } }); t2.Start(); }
// Demonstrates: // ManualResetEventSlim construction // ManualResetEventSlim.Wait() // ManualResetEventSlim.Set() // ManualResetEventSlim.Reset() // ManualResetEventSlim.IsSet static void MRES_SetWaitReset() { System.Threading.ManualResetEventSlim mres1 = new System.Threading.ManualResetEventSlim(false); // initialize as unsignaled System.Threading.ManualResetEventSlim mres2 = new System.Threading.ManualResetEventSlim(false); // initialize as unsignaled System.Threading.ManualResetEventSlim mres3 = new System.Threading.ManualResetEventSlim(true); // initialize as signaled // Start an asynchronous Task that manipulates mres3 and mres2 var observer = Task.Factory.StartNew(() => { mres1.Wait(); Console.WriteLine("observer sees signaled mres1!"); Console.WriteLine("observer resetting mres3..."); mres3.Reset(); // should switch to unsignaled Console.WriteLine("observer signalling mres2"); mres2.Set(); }); Console.WriteLine("main thread: mres3.IsSet = {0} (should be true)", mres3.IsSet); Console.WriteLine("main thread signalling mres1"); mres1.Set(); // This will "kick off" the observer Task mres2.Wait(); // This won't return until observer Task has finished resetting mres3 Console.WriteLine("main thread sees signaled mres2!"); Console.WriteLine("main thread: mres3.IsSet = {0} (should be false)", mres3.IsSet); // It's good form to Dispose() a ManualResetEventSlim when you're done with it observer.Wait(); // make sure that this has fully completed mres1.Dispose(); mres2.Dispose(); mres3.Dispose(); }
private static void FunWithMRE() { ManualResetEventSlim mre = new ManualResetEventSlim(); //MRE mre = new MRE(); mre.WaitAsync().ContinueWith(t => CW("Wait 1 complete")); mre.WaitAsync().ContinueWith(t => CW("Wait 2 complete")); mre.WaitAsync().ContinueWith(t => CW("Wait 3 complete")); WaitUntilKey("set"); mre.Set(); mre.WaitAsync().ContinueWith(t => CW("Wait 4 complete")); mre.WaitAsync().ContinueWith(t => CW("Wait 5 complete")); mre.WaitAsync().ContinueWith(t => CW("Wait 6 complete")); //WaitUntilKey("reset"); mre.Reset(); mre.WaitAsync().ContinueWith(t => CW("Wait 7 complete")); mre.WaitAsync().ContinueWith(t => CW("Wait 8 complete")); mre.WaitAsync().ContinueWith(t => CW("Wait 9 complete")); WaitUntilKey("set again"); mre.Set(); }
public void CheckForStructureChangesStartsFullReparseIfChangeOverlapsMultipleSpans() { // Arrange using (var parser = new RazorEditorParser(CreateHost(), TestLinePragmaFileName)) { var original = new StringTextBuffer("Foo @bar Baz"); var changed = new StringTextBuffer("Foo @bap Daz"); var change = new TextChange(7, 3, original, 3, changed); var parseComplete = new ManualResetEventSlim(); var parseCount = 0; parser.DocumentParseComplete += (sender, args) => { Interlocked.Increment(ref parseCount); parseComplete.Set(); }; Assert.Equal(PartialParseResult.Rejected, parser.CheckForStructureChanges(new TextChange(0, 0, new StringTextBuffer(string.Empty), 12, original))); MiscUtils.DoWithTimeoutIfNotDebugging(parseComplete.Wait); // Wait for the parse to finish parseComplete.Reset(); // Act var result = parser.CheckForStructureChanges(change); // Assert Assert.Equal(PartialParseResult.Rejected, result); MiscUtils.DoWithTimeoutIfNotDebugging(parseComplete.Wait); Assert.Equal(2, parseCount); } }
static void Main(string[] args) { // create the primtive ManualResetEventSlim manualResetEvent = new ManualResetEventSlim(); // create the cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource(); // create and start the task that will wait on the event Task waitingTask = Task.Factory.StartNew(() => { while (true) { // wait on the primitive manualResetEvent.Wait(tokenSource.Token); // print out a message Console.WriteLine("Waiting task active"); } }, tokenSource.Token); // create and start the signalling task Task signallingTask = Task.Factory.StartNew(() => { // create a random generator for sleep periods Random rnd = new Random(); // loop while the task has not been cancelled while (!tokenSource.Token.IsCancellationRequested) { // go to sleep for a random period tokenSource.Token.WaitHandle.WaitOne(rnd.Next(500, 2000)); // set the event manualResetEvent.Set(); Console.WriteLine("Event set"); // go to sleep again tokenSource.Token.WaitHandle.WaitOne(rnd.Next(500, 2000)); // reset the event manualResetEvent.Reset(); Console.WriteLine("Event reset"); } // if we reach this point, we know the task has been cancelled tokenSource.Token.ThrowIfCancellationRequested(); }, tokenSource.Token); // ask the user to press return before we cancel // the token and bring the tasks to an end Console.WriteLine("Press enter to cancel tasks"); Console.ReadLine(); // cancel the token source and wait for the tasks tokenSource.Cancel(); try { Task.WaitAll(waitingTask, signallingTask); } catch (AggregateException) { // discard exceptions } // wait for input before exiting Console.WriteLine("Press enter to finish"); Console.ReadLine(); }
public override void Run(VoidAction tickCallback) { // 59.75 is sort of compensation long ticksPerFrame = (int)Math.Round(MyGameTimer.Frequency / 59.75f); long targetTicks = 0; MyLog.Default.WriteLine("Timer Frequency: " + MyGameTimer.Frequency); MyLog.Default.WriteLine("Ticks per frame: " + ticksPerFrame); ManualResetEventSlim waiter = new ManualResetEventSlim(false, 0); MyTimer.TimerEventHandler handler = new MyTimer.TimerEventHandler((a, b, c, d, e) => { waiter.Set(); }); base.Run(delegate { using (Stats.Generic.Measure("WaitForUpdate")) { var currentTicks = m_gameTimer.ElapsedTicks; // Wait for correct frame start targetTicks += ticksPerFrame; if (currentTicks > targetTicks + ticksPerFrame * 5) { // We're more behind than 5 frames, don't try to catch up targetTicks = currentTicks; } else { // For until correct tick comes if (MyFakes.ENABLE_UPDATE_WAIT) { var remaining = MyTimeSpan.FromTicks(targetTicks - currentTicks); int waitMs = (int)(remaining.Miliseconds - 0.1); // To handle up to 0.1ms inaccuracy of timer if (waitMs > 0) { waiter.Reset(); MyTimer.StartOneShot(waitMs, handler); waiter.Wait(17); // Never wait more than 17ms //Debug.Assert(MyPerformanceCounter.ElapsedTicks < targetTicks); //VRageRender.MyRenderStats.Write("WaitRemaining", (float)MyPerformanceCounter.TicksToMs(targetTicks - MyPerformanceCounter.ElapsedTicks), VRageRender.MyStatTypeEnum.MinMaxAvg, 300, 3); } } while (m_gameTimer.ElapsedTicks < targetTicks) ; } } //UpdateInternal(); tickCallback(); ProfilerShort.Commit(); }); }
public void Execute() { // // 通常の使い方. // var mres = new ManualResetEventSlim(false); ThreadPool.QueueUserWorkItem(DoProc, mres); Output.Write("メインスレッド待機中・・・"); mres.Wait(); Output.WriteLine("終了"); // // WaitメソッドにCancellationTokenを受け付けるオーバーロードを使用。 // mres.Reset(); var tokenSource = new CancellationTokenSource(); var token = tokenSource.Token; Task.Factory.StartNew(DoProc, mres); // // キャンセル状態に設定. // tokenSource.Cancel(); Output.Write("メインスレッド待機中・・・"); try { // // CancellationTokenを指定して、Wait呼び出し。 // この場合は、以下のどちらかの条件を満たした時点でWaitが解除される。 // ・別の場所にて、Setが呼ばれてシグナル状態となる。 // ・CancellationTokenがキャンセルされる。 // // トークンがキャンセルされた場合、OperationCanceledExceptionが発生するので // CancellationTokenを指定するWaitを呼び出す場合は、try-catchが必須となる。 // // 今回の例の場合は、予めCancellationTokenをキャンセルしているので // タスク処理でシグナル状態に設定されるよりも先に、キャンセル状態に設定される。 // なので、実行結果には、「*** シグナル状態に設定 ***」という文言は出力されない。 // mres.Wait(token); } catch (OperationCanceledException cancelEx) { Output.Write("*** {0} *** ", cancelEx.Message); } Output.WriteLine("終了"); }
public void Start() { try { slim.Wait(); slim.Reset(); } finally { slim.Set(); } }
public void MemcacheClientReplicasTest() { var callbackMutex = new ManualResetEventSlim(false); var client = new MemcacheClient(_configuration); // The number of requests sent is capped by the number of nodes in the cluster. // The last iteration of the loop below actually tests the case where the total // number of copies (Replicas+1) is strictly greater than the number of nodes. int nodeCount = _configuration.NodesEndPoints.Count; for (int replicas = 0; replicas <= nodeCount; replicas++) { _configuration.Replicas = replicas; // SET callbackMutex.Reset(); NodeMock.TrySendCounter = 0; Assert.IsTrue(client.Set("toto", new byte[0], TimeSpan.MaxValue, s => callbackMutex.Set())); Assert.AreEqual(Math.Min(replicas + 1, nodeCount), NodeMock.TrySendCounter); Assert.IsTrue(callbackMutex.Wait(1000), string.Format("The SET callback has not been received after 1 second (Replicas = {0})", replicas)); // GET callbackMutex.Reset(); NodeMock.TrySendCounter = 0; Assert.IsTrue(client.Get("toto", (Status s, byte[] data) => callbackMutex.Set())); Assert.AreEqual(Math.Min(replicas + 1, nodeCount), NodeMock.TrySendCounter); Assert.IsTrue(callbackMutex.Wait(1000), string.Format("The GET callback has not been received after 1 second (Replicas = {0})", replicas)); // DELETE callbackMutex.Reset(); NodeMock.TrySendCounter = 0; Assert.IsTrue(client.Delete("toto", s => callbackMutex.Set())); Assert.AreEqual(Math.Min(replicas + 1, nodeCount), NodeMock.TrySendCounter); Assert.IsTrue(callbackMutex.Wait(1000), string.Format("The DELETE callback has not been received after 1 second (Replicas = {0})", replicas)); } }
public void LatestOfSource() { var source = AsyncEnumerable.Source<int>(); var latest = source.Latest(); var step = new ManualResetEventSlim(false); var proceed = new ManualResetEventSlim(false); Assert.IsTrue(latest.Item.IsNone, $"(0) {latest.Item}"); var t = Task.Run(async () => { await source.Yield(1); await Task.Yield(); step.Set(); proceed.Wait(); proceed.Reset(); await source.Yield(2); await Task.Yield(); step.Set(); proceed.Wait(); proceed.Reset(); await source.Break(); await Task.Yield(); step.Set(); proceed.Wait(); proceed.Reset(); }); step.Wait(); step.Reset(); Assert.IsTrue(latest.Item.Value == 1, $"(1) {latest.Item}"); proceed.Set(); step.Wait(); step.Reset(); Assert.IsTrue(latest.Item.Value == 2, $"(2) {latest.Item}"); proceed.Set(); step.Wait(); step.Reset(); Assert.IsTrue(latest.Item.IsCompleted, $"(3) {latest.Item}"); proceed.Set(); }
public ShipsViewModel() { WaitShipsEvent = new ManualResetEventSlim(false); KanColleGame.Current.ObservablePropertyChanged.Where(r => r == nameof(KanColleGame.Current.Ships)).Subscribe(_ => { Count = KanColleGame.Current.Ships.Count + KanColleGame.Current.DroppedShip; WaitShipsEvent.Reset(); Ships = KanColleGame.Current.Ships.Values.Select(r => new ShipViewModel(r)).ToArray(); WaitShipsEvent.Set(); }); }
public void NextOfSource() { var source = AsyncEnumerable.Source<int>(); var next = source.Next(); var step = new ManualResetEventSlim(false); var proceed = new ManualResetEventSlim(false); var t = Task.Run(async () => { await source.Yield(1); await Task.Yield(); step.Set(); proceed.Wait(); proceed.Reset(); await source.Yield(2); await Task.Yield(); step.Set(); proceed.Wait(); proceed.Reset(); await source.Break(); await Task.Yield(); step.Set(); proceed.Wait(); proceed.Reset(); }); step.Wait(); step.Reset(); Assert.IsTrue(next.Result == 1, $"(1) {next.Result}"); next = source.Next(); proceed.Set(); step.Wait(); step.Reset(); Assert.IsTrue(next.Result == 2, $"(2) {next.Result}"); next = source.Next(); proceed.Set(); step.Wait(); step.Reset(); }
public void Set_Reset_Cycles() { using (var resetEvent = new ManualResetEventSlim(false)) { var stopwatch = Stopwatch.StartNew(); for (var i = 0; i < Iterations; i++) { resetEvent.Set(); resetEvent.Reset(); } stopwatch.StopAndLog(Iterations); } }
public HarvesterProcessingDispatcher(ILogger logger, Func<IFileBatchManager> fileBatchManagerFactory, string harvesterName) { _logger = logger; _harvesterName = harvesterName; _fileBatchManagerFactory = fileBatchManagerFactory; _operationQueue = new Queue<BasicSerializedDeliveryEventArgs<FileMessage>>(); _shutdownEvent = new ManualResetEventSlim(false); _shutdownEvent.Reset(); _dispatcher = new Task(this.Processing, TaskCreationOptions.LongRunning); _dispatcher.Start(); _syncObject = new object(); }
public override void Run(VoidAction tickCallback) { long targetTicks = 0; ManualResetEventSlim waiter = new ManualResetEventSlim(false, 0); MyTimer.TimerEventHandler handler = new MyTimer.TimerEventHandler((a, b, c, d, e) => { waiter.Set(); }); base.Run(delegate { using (StatGroup.Measure(StatName)) { var currentTicks = m_gameTimer.ElapsedTicks; // Wait for correct frame start targetTicks += TickPerFrame; if (currentTicks > targetTicks + TickPerFrame * 5) { // We're more behind than 5 frames, don't try to catch up targetTicks = currentTicks; } else { // For until correct tick comes if (EnableUpdateWait) { var remaining = MyTimeSpan.FromTicks(targetTicks - currentTicks); int waitMs = (int)(remaining.Miliseconds - 0.1); // To handle up to 0.1ms inaccuracy of timer if (waitMs > 0) { waiter.Reset(); MyTimer.StartOneShot(waitMs, handler); waiter.Wait(17); // Never wait more than 17ms //Debug.Assert(MyPerformanceCounter.ElapsedTicks < targetTicks); //VRageRender.MyRenderStats.Write("WaitRemaining", (float)MyPerformanceCounter.TicksToMs(targetTicks - MyPerformanceCounter.ElapsedTicks), VRageRender.MyStatTypeEnum.MinMaxAvg, 300, 3); } } while (m_gameTimer.ElapsedTicks < targetTicks) ; } } //UpdateInternal(); tickCallback(); }); }
public bool WaitForWorkItems(double timeout) { if (_Disposed) { return(false); } if (_Queue.Count > 0) { return(true); } else { Interlocked.Increment(ref _WaiterCount); if (timeout <= 0) { timeout = DefaultWaitTimeout; } int timeoutMs = (int)Math.Ceiling(TimeSpan.FromSeconds(timeout).TotalMilliseconds); try { if (_Queue.Count > 0) { return(true); } else { var result = _WaiterSignal.Wait(timeoutMs); if (_Disposed) { return(false); } else { _WaiterSignal.Reset(); return(result); } } } finally { Interlocked.Decrement(ref _WaiterCount); } } }
public CommandResult Execute() { _fileSystemMigrator.Migrate(); _console.WriteLine("scriptcs (ctrl-c to exit)"); _logger.InfoFormat("Running script '{0}' and watching for changes...", _config.ScriptName); while (true) { using (var fileChanged = new ManualResetEventSlim()) using (var watcher = new FileWatcher(_config.ScriptName, 500, _fileSystem)) { _logger.DebugFormat("Creating app domain '{0}'...", _config.ScriptName); var appDomain = AppDomain.CreateDomain(_config.ScriptName, null, _setup); try { watcher.Changed += (sender, e) => { _logger.DebugFormat("Script '{0}' changed.", _config.ScriptName); EnsureUnloaded(appDomain); fileChanged.Set(); }; watcher.Start(); _logger.DebugFormat("Executing script '{0}' and watching for changes...", _config.ScriptName); fileChanged.Reset(); try { appDomain.DoCallBack(_executeScriptCommand.Execute); } catch (AppDomainUnloadedException ex) { _logger.DebugFormat("App domain '{0}' has been unloaded.", ex, _config.ScriptName); } } finally { EnsureUnloaded(appDomain); } fileChanged.Wait(); _logger.InfoFormat("Script changed. Reloading...", _config.ScriptName); } } }
private static void ExecutorTaskAction(Action action, int interval, int delay, int runTime, int maxRuns, Stopwatch sw, CancellationToken cancelToken = new CancellationToken(), TaskCreationOptions taskOptions = TaskCreationOptions.None) { TaskCreationOptions taskCreationOptions = TaskCreationOptions.AttachedToParent | taskOptions; StopIfCancelled(cancelToken); if (delay > 0) { Thread.Sleep(delay); } if (maxRuns == 0) return; long iteration = 0; using (ManualResetEventSlim resetEvent = new ManualResetEventSlim(false)) { while (true) { StopIfCancelled(cancelToken); Task subTask = Task.Factory.StartNew(action, cancelToken, taskCreationOptions, TaskScheduler.Current); if (interval == Timeout.Infinite) { break; } if (maxRuns > 0 && ++iteration >= maxRuns) { break; } try { sw.Start(); resetEvent.Wait(interval, cancelToken); sw.Stop(); } finally { resetEvent.Reset(); } StopIfCancelled(cancelToken); if (runTime > 0 && sw.ElapsedMilliseconds >= runTime) { break; } } } }
public void TestBrowser() { #if __ANDROID__ if(global::Android.OS.Build.VERSION.SdkInt < global::Android.OS.BuildVersionCodes.JellyBean) { Assert.Inconclusive("PeerToPeer requires API level 16, but found {0}", global::Android.OS.Build.VERSION.Sdk); } #endif //Use a short timeout to speed up the test since it is performed locally //Android will get stuck in DNSProcessResult which hangs indefinitely if //no results are found (Which will happen if registration is aborted between //the resolve reply and query record steps) ServiceParams.Timeout = TimeSpan.FromSeconds(3); var mre = new ManualResetEventSlim(); CouchbaseLiteServiceBrowser browser = new CouchbaseLiteServiceBrowser(new ServiceBrowser()); browser.ServiceResolved += (sender, e) => { Log.D(TAG, "Discovered service: {0}", e.Service.Name); if(e.Service.Name == TAG) { mre.Set(); } }; browser.ServiceRemoved += (o, args) => { Log.D(TAG, "Service destroyed: {0}", args.Service.Name); if(args.Service.Name == TAG) { mre.Set(); } }; browser.Start(); CouchbaseLiteServiceBroadcaster broadcaster = new CouchbaseLiteServiceBroadcaster(new RegisterService(), 59840); broadcaster.Name = TAG; broadcaster.Start(); Assert.IsTrue(mre.Wait(TimeSpan.FromSeconds(10))); //FIXME.JHB: Why does Linux hate this part sporadically? mre.Reset(); broadcaster.Dispose(); var success = mre.Wait(TimeSpan.FromSeconds(10)); browser.Dispose(); Assert.IsTrue(success); }
private static void ClientConnect() { using (var client = new AsyncSocketConnector()) using (var ready = new System.Threading.ManualResetEventSlim(false)) { client.FilterChain.AddLast("ssl", new SslFilter("TempCert", null)); client.FilterChain.AddLast("text", new ProtocolCodecFilter(new TextLineCodecFactory())); client.MessageReceived += (s, e) => { Debug.WriteLine("Client got: " + e.Message); ready.Set(); }; var session = client.Connect(new IPEndPoint(IPAddress.Loopback, port)).Await().Session; Debug.WriteLine("Client sending: hello"); session.Write("hello "); Debug.WriteLine("Client sending: send"); session.Write("send"); ready.Wait(3000); Assert.IsTrue(ready.IsSet); ready.Reset(); Assert.IsFalse(ready.IsSet); Debug.WriteLine("Client sending: hello"); session.Write(IoBuffer.Wrap(Encoding.UTF8.GetBytes("hello \n"))); Debug.WriteLine("Client sending: send"); session.Write(IoBuffer.Wrap(Encoding.UTF8.GetBytes("send\n"))); ready.Wait(3000); Assert.IsTrue(ready.IsSet); session.Close(true); } }
static async Task Main(string[] args) { var cts = new CancellationTokenSource(); // Pass the same token source to the delegate and to the task instance. Task.Run(() => DoWork(cts.Token), cts.Token); Console.WriteLine("Press c to cancel, p to pause, or s to start/restart,"); Console.WriteLine("or any other key to exit."); // New-style UI thread. bool goAgain = true; while (goAgain) { char ch = Console.ReadKey(true).KeyChar; switch (ch) { case 'c': // Token can only be canceled once. cts.Cancel(); break; case 'p': mres.Reset(); break; case 's': mres.Set(); break; default: goAgain = false; break; } Thread.Sleep(100); } cts.Dispose(); }
public void CanUpdateToBeNoItemsInChildTable(string requestedStorage) { CreateRdbmsSchema(); using (var store = NewDocumentStore(requestedStorage: requestedStorage)) { var eventSlim = new ManualResetEventSlim(false); store.SystemDatabase.StartupTasks.OfType<SqlReplicationTask>() .First().AfterReplicationCompleted += successCount => { if (successCount != 0) eventSlim.Set(); }; using (var session = store.OpenSession()) { session.Store(new Order { OrderLines = new List<OrderLine> { new OrderLine{Cost = 3, Product = "Milk", Quantity = 3}, new OrderLine{Cost = 4, Product = "Bear", Quantity = 2}, } }); session.SaveChanges(); } SetupSqlReplication(store, defaultScript); eventSlim.Wait(TimeSpan.FromMinutes(5)); AssertCounts(1, 2); eventSlim.Reset(); using (var session = store.OpenSession()) { session.Load<Order>(1).OrderLines.Clear(); session.SaveChanges(); } eventSlim.Wait(TimeSpan.FromMinutes(5)); AssertCounts(1, 0); } }
// // Taking the Upgradable read lock is like taking a read lock // but we limit it to a single upgradable at a time. // public bool TryEnterUpgradeableReadLock(int millisecondsTimeout) { var currentThreadState = CurrentThreadState; if (CheckState(currentThreadState, millisecondsTimeout, LockState.Upgradable)) { ++currentThreadState.UpgradeableRecursiveCount; return(true); } if ((currentThreadState.LockState & LockState.Read) > 0) { throw new LockRecursionException("The current thread has already entered read mode"); } ++WaitingUpgradeCount; var start = millisecondsTimeout == -1 ? 0 : _stopwatch.ElapsedMilliseconds; var taken = false; var success = false; // We first try to obtain the upgradeable right try { while (!_upgradableEvent.IsSet || !taken) { try { } finally { taken = _upgradableTaken.TryRelaxedSet(); } if (taken) { break; } if (millisecondsTimeout != -1 && _stopwatch.ElapsedMilliseconds - start > millisecondsTimeout) { --WaitingUpgradeCount; return(false); } _upgradableEvent.Wait(ComputeTimeout(millisecondsTimeout, start)); } _upgradableEvent.Reset(); RuntimeHelpers.PrepareConstrainedRegions(); try { // Then it's a simple reader lock acquiring TryEnterReadLock(ComputeTimeout(millisecondsTimeout, start), ref success); } finally { if (success) { currentThreadState.LockState |= LockState.Upgradable; currentThreadState.LockState &= ~LockState.Read; --currentThreadState.ReaderRecursiveCount; ++currentThreadState.UpgradeableRecursiveCount; } else { _upgradableTaken.Value = false; _upgradableEvent.Set(); } } --WaitingUpgradeCount; } catch (Exception ex) { No.Op(ex); // An async exception occured, if we had taken the upgradable mode, release it _upgradableTaken.Value &= !taken || success; } return(success); }
public void TestBatcherCancel() { var mre = new ManualResetEventSlim(); var scheduler = new SingleTaskThreadpoolScheduler(); var batcher = new Batcher<int>(new TaskFactory(scheduler), 5, 500, (inbox) => { mre.Set(); }); batcher.QueueObject(0); Assert.IsTrue(mre.Wait(1000), "Batcher didn't initially run"); mre.Reset(); batcher.QueueObject(0); batcher.Clear(); Assert.False(mre.Wait(TimeSpan.FromSeconds(1)), "Batcher ran after being cancelled"); }
internal void SleepWorkerThreadFunc(PriorityQueue <SleepItem> pendingSleeps, System.Threading.ManualResetEventSlim newSleepEvent) { while (true) { long now = TimeProvider.Ticks; SleepItem currentSleep; Monitor.Enter(pendingSleeps); if (pendingSleeps.Peek(out currentSleep)) { if (currentSleep.Tick(now)) { pendingSleeps.Dequeue(); Monitor.Exit(pendingSleeps); continue; } else { Monitor.Exit(pendingSleeps); } } else { Monitor.Exit(pendingSleeps); if (!newSleepEvent.Wait(SleepThreadTimeoutMs)) { return; } newSleepEvent.Reset(); continue; } long sleepUntil = currentSleep.Until; now = TimeProvider.Ticks; long timeToSleep = (sleepUntil - now) + SleepFudgeFactor; if (timeToSleep < SleepSpinThreshold) { int iteration = 1; while (TimeProvider.Ticks < sleepUntil) { Thread.SpinWait(20 * iteration); iteration += 1; } timeToSleep = 0; } if (timeToSleep > 0) { if (timeToSleep > MaximumSleepLength) { timeToSleep = MaximumSleepLength; } int msToSleep = 0; if (timeToSleep >= MinimumSleepLength) { msToSleep = (int)(timeToSleep / Time.MillisecondInTicks); } if (newSleepEvent != null) { newSleepEvent.Reset(); newSleepEvent.Wait(msToSleep); } } } }
public void TestPullerChangedEvent() { if (!Boolean.Parse((string)Runtime.Properties["replicationTestsEnabled"])) { Assert.Inconclusive("Replication tests disabled."); return; } var docIdTimestamp = Convert.ToString(Runtime.CurrentTimeMillis()); var doc1Id = string.Format("doc1-{0}", docIdTimestamp); var doc2Id = string.Format("doc2-{0}", docIdTimestamp); AddDocWithId(doc1Id, "attachment.png"); AddDocWithId(doc2Id, "attachment2.png"); var pull = database.CreatePullReplication(GetReplicationURL()); List<ReplicationStatus> statusHistory = new List<ReplicationStatus>(); pull.Changed += (sender, e) => { statusHistory.Add(e.Source.Status); if(e.Source.ChangesCount > 0 && e.Source.CompletedChangesCount != e.Source.ChangesCount) { Assert.AreEqual(ReplicationStatus.Active, e.Source.Status); } if(e.Source.Status == ReplicationStatus.Stopped) { Assert.AreNotEqual(0, e.Source.CompletedChangesCount); Assert.AreEqual(e.Source.ChangesCount, e.Source.CompletedChangesCount); } }; RunReplication(pull); foreach (var status in statusHistory.Take(statusHistory.Count - 1)) { Assert.AreEqual(ReplicationStatus.Active, status); } Assert.AreEqual(ReplicationStatus.Stopped, statusHistory[statusHistory.Count - 1]); doc1Id = string.Format("doc3-{0}", docIdTimestamp); doc2Id = string.Format("doc4-{0}", docIdTimestamp); AddDocWithId(doc1Id, "attachment.png"); AddDocWithId(doc2Id, "attachment2.png"); pull = database.CreatePullReplication(GetReplicationURL()); pull.Continuous = true; statusHistory.Clear(); var doneEvent = new ManualResetEventSlim(); pull.Changed += (sender, e) => { statusHistory.Add(e.Source.Status); if(e.Source.ChangesCount > 0 && e.Source.CompletedChangesCount != e.Source.ChangesCount) { Assert.AreEqual(ReplicationStatus.Active, e.Source.Status); } if(e.Source.Status == ReplicationStatus.Idle) { Assert.AreNotEqual(0, e.Source.CompletedChangesCount); Assert.AreEqual(e.Source.ChangesCount, e.Source.CompletedChangesCount); doneEvent.Set(); } else if(e.Source.Status == ReplicationStatus.Stopped) { doneEvent.Set(); } }; pull.Start(); Assert.IsTrue(doneEvent.Wait(TimeSpan.FromSeconds(60))); Assert.IsNull(pull.LastError); foreach (var status in statusHistory.Take(statusHistory.Count - 1)) { Assert.AreEqual(ReplicationStatus.Active, status); } Assert.AreEqual(ReplicationStatus.Idle, statusHistory[statusHistory.Count - 1]); doneEvent.Reset(); statusHistory.Clear(); doc1Id = string.Format("doc5-{0}", docIdTimestamp); AddDocWithId(doc1Id, "attachment.png"); Assert.IsTrue(doneEvent.Wait(TimeSpan.FromSeconds(60))); Assert.IsNull(pull.LastError); foreach (var status in statusHistory.Take(statusHistory.Count - 1)) { Assert.AreEqual(ReplicationStatus.Active, status); } Assert.AreEqual(ReplicationStatus.Idle, statusHistory[statusHistory.Count - 1]); doneEvent.Reset(); statusHistory.Clear(); pull.Stop(); Assert.IsTrue(doneEvent.Wait(TimeSpan.FromSeconds(60))); Assert.IsNull(pull.LastError); Assert.AreEqual(2, statusHistory.Count); Assert.AreEqual(ReplicationStatus.Active, statusHistory.First()); Assert.AreEqual(ReplicationStatus.Stopped, statusHistory[1]); }
/// <summary> /// Notifies the <see cref="Barrier"/> that there will be additional participants. /// </summary> /// <param name="participantCount">The number of additional participants to add to the /// barrier.</param> /// <returns>The phase number of the barrier in which the new participants will first /// participate.</returns> /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="participantCount"/> is less than /// 0.</exception> /// <exception cref="T:System.ArgumentOutOfRangeException">Adding <paramref name="participantCount"/> participants would cause the /// barrier's participant count to exceed <see cref="T:System.Int16.MaxValue"/>.</exception> /// <exception cref="T:System.InvalidOperationException"> /// The method was invoked from within a post-phase action. /// </exception> /// <exception cref="T:System.ObjectDisposedException">The current instance has already been /// disposed.</exception> public long AddParticipants(int participantCount) { // check dispose ThrowIfDisposed(); if (participantCount < 1) { throw new ArgumentOutOfRangeException(nameof(participantCount), participantCount, SR.Barrier_AddParticipants_NonPositive_ArgumentOutOfRange); } else if (participantCount > MAX_PARTICIPANTS) //overflow { throw new ArgumentOutOfRangeException(nameof(participantCount), SR.Barrier_AddParticipants_Overflow_ArgumentOutOfRange); } // in case of this is called from the PHA if (_actionCallerID != 0 && Environment.CurrentManagedThreadId == _actionCallerID) { throw new InvalidOperationException(SR.Barrier_InvalidOperation_CalledFromPHA); } SpinWait spinner = new SpinWait(); long newPhase = 0; while (true) { int currentTotal = _currentTotalCount; int total; int current; bool sense; GetCurrentTotal(currentTotal, out current, out total, out sense); if (participantCount + total > MAX_PARTICIPANTS) //overflow { throw new ArgumentOutOfRangeException(nameof(participantCount), SR.Barrier_AddParticipants_Overflow_ArgumentOutOfRange); } if (SetCurrentTotal(currentTotal, current, total + participantCount, sense)) { // Calculating the first phase for that participant, if the current phase already finished return the next phase else return the current phase // To know that the current phase is the sense doesn't match the // phase odd even, so that means it didn't yet change the phase count, so currentPhase +1 is returned, otherwise currentPhase is returned long currPhase = CurrentPhaseNumber; newPhase = (sense != (currPhase % 2 == 0)) ? currPhase + 1 : currPhase; // If this participant is going to join the next phase, which means the postPhaseAction is being running, this participants must wait until this done // and its event is reset. // Without that, if the postPhaseAction takes long time, this means the event that the current participant is going to wait on is still set // (FinishPhase didn't reset it yet) so it should wait until it reset if (newPhase != currPhase) { // Wait on the opposite event if (sense) { _oddEvent.Wait(); } else { _evenEvent.Wait(); } } //This else to fix the racing where the current phase has been finished, m_currentPhase has been updated but the events have not been set/reset yet // otherwise when this participant calls SignalAndWait it will wait on a set event however all other participants have not arrived yet. else { if (sense && _evenEvent.IsSet) { _evenEvent.Reset(); } else if (!sense && _oddEvent.IsSet) { _oddEvent.Reset(); } } break; } spinner.SpinOnce(); } return(newPhase); }
public void SendToRecvFromAsync_Datagram_UDP_UdpClient(IPAddress leftAddress, IPAddress rightAddress) { // TODO #5185: harden against packet loss const int DatagramSize = 256; const int DatagramsToSend = 256; const int AckTimeout = 1000; const int TestTimeout = 30000; using (var left = new UdpClient(new IPEndPoint(leftAddress, 0))) using (var right = new UdpClient(new IPEndPoint(rightAddress, 0))) { var leftEndpoint = (IPEndPoint)left.Client.LocalEndPoint; var rightEndpoint = (IPEndPoint)right.Client.LocalEndPoint; var receiverAck = new ManualResetEventSlim(); var senderAck = new ManualResetEventSlim(); var receivedChecksums = new uint?[DatagramsToSend]; int receivedDatagrams = 0; Task receiverTask = Task.Run(async () => { for (; receivedDatagrams < DatagramsToSend; receivedDatagrams++) { UdpReceiveResult result = await left.ReceiveAsync(); receiverAck.Set(); Assert.True(senderAck.Wait(AckTimeout)); senderAck.Reset(); Assert.Equal(DatagramSize, result.Buffer.Length); Assert.Equal(rightEndpoint, result.RemoteEndPoint); int datagramId = (int)result.Buffer[0]; Assert.Null(receivedChecksums[datagramId]); receivedChecksums[datagramId] = Fletcher32.Checksum(result.Buffer, 0, result.Buffer.Length); } }); var sentChecksums = new uint[DatagramsToSend]; int sentDatagrams = 0; Task senderTask = Task.Run(async () => { var random = new Random(); var sendBuffer = new byte[DatagramSize]; for (; sentDatagrams < DatagramsToSend; sentDatagrams++) { random.NextBytes(sendBuffer); sendBuffer[0] = (byte)sentDatagrams; int sent = await right.SendAsync(sendBuffer, DatagramSize, leftEndpoint); Assert.True(receiverAck.Wait(AckTimeout)); receiverAck.Reset(); senderAck.Set(); Assert.Equal(DatagramSize, sent); sentChecksums[sentDatagrams] = Fletcher32.Checksum(sendBuffer, 0, sent); } }); Assert.True(Task.WaitAll(new[] { receiverTask, senderTask }, TestTimeout)); for (int i = 0; i < DatagramsToSend; i++) { Assert.NotNull(receivedChecksums[i]); Assert.Equal(sentChecksums[i], (uint)receivedChecksums[i]); } } }
public void Reset(int value) { evt.Reset(); Interlocked.Exchange(ref count, value); }
public void TestGetReplicator() { if (!Boolean.Parse((string)GetProperty("replicationTestsEnabled"))) { Assert.Inconclusive("Replication tests disabled."); return; } using (var remoteDb = _sg.CreateDatabase(TempDbName())) { var replicationUrl = remoteDb.RemoteUri; var replicator = database.CreatePullReplication(replicationUrl); Assert.IsNotNull(replicator); Assert.IsTrue(replicator.IsPull); Assert.IsFalse(replicator.Continuous); Assert.IsFalse(replicator.IsRunning); ReplicationStatus lastStatus = replicator.Status; var mre = new ManualResetEventSlim(); replicator.Changed += (sender, e) => { if (lastStatus != e.Source.Status) { lastStatus = e.Source.Status; mre.Set(); } }; replicator.Start(); Assert.IsTrue(mre.Wait(TimeSpan.FromSeconds(10)), "Timed out waiting for replicator to start"); Assert.IsTrue(replicator.IsRunning); var activeReplicators = default(IList<Replication>); var got = database.ActiveReplicators.AcquireTemp(out activeReplicators); Assert.IsTrue(got); Assert.AreEqual(1, activeReplicators.Count); Assert.AreEqual(replicator, activeReplicators[0]); replicator.Stop(); mre.Reset(); Assert.IsTrue(mre.Wait(TimeSpan.FromSeconds(10)), "Timed out waiting for replicator to stop"); Assert.IsFalse(replicator.IsRunning); Sleep(500); got = database.ActiveReplicators.AcquireTemp(out activeReplicators); Assert.IsTrue(got); Assert.AreEqual(0, activeReplicators.Count); } }
/// <summary> /// Notifies the <see cref="Barrier"/> that there will be additional participants. /// </summary> /// <param name="participantCount">The number of additional participants to add to the /// barrier.</param> /// <returns>The phase number of the barrier in which the new participants will first /// participate.</returns> /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="participantCount"/> is less than /// 0.</exception> /// <exception cref="T:System.ArgumentOutOfRangeException">Adding <paramref name="participantCount"/> participants would cause the /// barrier's participant count to exceed <see cref="T:System.Int16.MaxValue"/>.</exception> /// <exception cref="T:System.InvalidOperationException"> /// The method was invoked from within a post-phase action. /// </exception> /// <exception cref="T:System.ObjectDisposedException">The current instance has already been /// disposed.</exception> public long AddParticipants(int participantCount) { // check dispose ThrowIfDisposed(); if (participantCount < 1) { throw new ArgumentOutOfRangeException("participantCount", participantCount, "The participantCount argument must be a positive value."); } if (participantCount > _maxParticipants) //overflow { throw new ArgumentOutOfRangeException("participantCount", "Adding participantCount participants would result in the number of participants exceeding the maximum number allowed."); } // in case of this is called from the PHA if (_actionCallerId != 0 && Thread.CurrentThread.ManagedThreadId == _actionCallerId) { throw new InvalidOperationException("This method may not be called from within the postPhaseAction."); } var spinner = new SpinWait(); long newPhase; while (true) { var currentTotal = Volatile.Read(ref _currentTotalCount); int total; int current; bool sense; GetCurrentTotal(currentTotal, out current, out total, out sense); if (participantCount + total > _maxParticipants) //overflow { throw new ArgumentOutOfRangeException("participantCount", "Adding participantCount participants would result in the number of participants exceeding the maximum number allowed."); } if (SetCurrentTotal(currentTotal, current, total + participantCount, sense)) { // Calculating the first phase for that participant, if the current phase already finished return the next phase else return the current phase // To know that the current phase is the sense doesn't match the // phase odd even, so that means it didn't yet change the phase count, so currentPhase +1 is returned, otherwise currentPhase is returned var currPhase = CurrentPhaseNumber; newPhase = (sense != (currPhase % 2 == 0)) ? currPhase + 1 : currPhase; // If this participant is going to join the next phase, which means the postPhaseAction is being running, this participants must wait until this done // and its event is reset. // Without that, if the postPhaseAction takes long time, this means the event that the current participant is going to wait on is still set // (FinishPhase didn't reset it yet) so it should wait until it reset if (newPhase != currPhase) { // Wait on the opposite event if (sense) { _oddEvent.Wait(); } else { _evenEvent.Wait(); } } //This else to fix the racing where the current phase has been finished, m_currentPhase has been updated but the events have not been set/reset yet // otherwise when this participant calls SignalAndWait it will wait on a set event however all other participants have not arrived yet. else { if (sense && _evenEvent.IsSet) { _evenEvent.Reset(); } else if (!sense && _oddEvent.IsSet) { _oddEvent.Reset(); } } break; } spinner.SpinOnce(); } return(newPhase); }
// // Taking the Upgradable read lock is like taking a read lock // but we limit it to a single upgradable at a time. // public bool TryEnterUpgradeableReadLock(int millisecondsTimeout) { ThreadLockState ctstate = CurrentThreadState; if (CheckState(ctstate, millisecondsTimeout, LockState.Upgradable)) { ++ctstate.UpgradeableRecursiveCount; return(true); } if (ctstate.LockState.Has(LockState.Read)) { throw new LockRecursionException("The current thread has already entered read mode"); } ++numUpgradeWaiters; long start = millisecondsTimeout == -1 ? 0 : sw.ElapsedMilliseconds; bool taken = false; bool success = false; // We first try to obtain the upgradeable right try { while (!upgradableEvent.IsSet() || !taken) { try {} finally { taken = upgradableTaken.TryRelaxedSet(); } if (taken) { break; } if (millisecondsTimeout != -1 && (sw.ElapsedMilliseconds - start) > millisecondsTimeout) { --numUpgradeWaiters; return(false); } upgradableEvent.Wait(ComputeTimeout(millisecondsTimeout, start)); } upgradableEvent.Reset(); RuntimeHelpers.PrepareConstrainedRegions(); try { // Then it's a simple reader lock acquiring TryEnterReadLock(ComputeTimeout(millisecondsTimeout, start), ref success); } finally { if (success) { ctstate.LockState |= LockState.Upgradable; ctstate.LockState &= ~LockState.Read; --ctstate.ReaderRecursiveCount; ++ctstate.UpgradeableRecursiveCount; } else { upgradableTaken.Value = false; upgradableEvent.Set(); } } --numUpgradeWaiters; } catch { // An async exception occured, if we had taken the upgradable mode, release it if (taken && !success) { upgradableTaken.Value = false; } } return(success); }
public bool TryEnterWriteLock(int millisecondsTimeout) { ThreadLockState ctstate = CurrentThreadState; if (CheckState(ctstate, millisecondsTimeout, LockState.Write)) { ++ctstate.WriterRecursiveCount; return(true); } ++numWriteWaiters; bool isUpgradable = ctstate.LockState.Has(LockState.Upgradable); bool registered = false; bool success = false; RuntimeHelpers.PrepareConstrainedRegions(); try { /* If the code goes there that means we had a read lock beforehand * that need to be suppressed, we also take the opportunity to register * our interest in the write lock to avoid other write wannabe process * coming in the middle */ if (isUpgradable && rwlock >= RwRead) { try {} finally { if (Interlocked.Add(ref rwlock, RwWaitUpgrade - RwRead) >> RwReadBit == 0) { readerDoneEvent.Set(); } registered = true; } } int stateCheck = isUpgradable ? RwWaitUpgrade + RwWait : RwWait; long start = millisecondsTimeout == -1 ? 0 : sw.ElapsedMilliseconds; do { int state = rwlock; if (state <= stateCheck) { try {} finally { if (Interlocked.CompareExchange(ref rwlock, RwWrite, state) == state) { writerDoneEvent.Reset(); ctstate.LockState ^= LockState.Write; ++ctstate.WriterRecursiveCount; --numWriteWaiters; registered = false; success = true; } } if (success) { return(true); } } state = rwlock; // We register our interest in taking the Write lock (if upgradeable it's already done) if (!isUpgradable) { while ((state & RwWait) == 0) { try {} finally { if (Interlocked.CompareExchange(ref rwlock, state | RwWait, state) == state) { registered = true; } } if (registered) { break; } state = rwlock; } } // Before falling to sleep do { if (rwlock <= stateCheck) { break; } if ((rwlock & RwWrite) != 0) { writerDoneEvent.Wait(ComputeTimeout(millisecondsTimeout, start)); } else if ((rwlock >> RwReadBit) > 0) { readerDoneEvent.Wait(ComputeTimeout(millisecondsTimeout, start)); } } while (millisecondsTimeout < 0 || (sw.ElapsedMilliseconds - start) < millisecondsTimeout); } while (millisecondsTimeout < 0 || (sw.ElapsedMilliseconds - start) < millisecondsTimeout); --numWriteWaiters; } finally { if (registered) { Interlocked.Add(ref rwlock, isUpgradable ? -RwWaitUpgrade : -RwWait); } } return(false); }
bool TryEnterReadLock(int millisecondsTimeout, ref bool success) { ThreadLockState ctstate = CurrentThreadState; if (CheckState(ctstate, millisecondsTimeout, LockState.Read)) { ++ctstate.ReaderRecursiveCount; return(true); } // This is downgrading from upgradable, no need for check since // we already have a sort-of read lock that's going to disappear // after user calls ExitUpgradeableReadLock. // Same idea when recursion is allowed and a write thread wants to // go for a Read too. if (ctstate.LockState.Has(LockState.Upgradable) || (!noRecursion && ctstate.LockState.Has(LockState.Write))) { RuntimeHelpers.PrepareConstrainedRegions(); try {} finally { Interlocked.Add(ref rwlock, RwRead); ctstate.LockState |= LockState.Read; ++ctstate.ReaderRecursiveCount; success = true; } return(true); } ++numReadWaiters; int val = 0; long start = millisecondsTimeout == -1 ? 0 : sw.ElapsedMilliseconds; do { /* Check if a writer is present (RwWrite) or if there is someone waiting to * acquire a writer lock in the queue (RwWait | RwWaitUpgrade). */ if ((rwlock & (RwWrite | RwWait | RwWaitUpgrade)) > 0) { writerDoneEvent.Wait(ComputeTimeout(millisecondsTimeout, start)); continue; } /* Optimistically try to add ourselves to the reader value * if the adding was too late and another writer came in between * we revert the operation. */ RuntimeHelpers.PrepareConstrainedRegions(); try {} finally { if (((val = Interlocked.Add(ref rwlock, RwRead)) & (RwWrite | RwWait | RwWaitUpgrade)) == 0) { /* If we are the first reader, reset the event to let other threads * sleep correctly if they try to acquire write lock */ if (val >> RwReadBit == 1) { readerDoneEvent.Reset(); } ctstate.LockState ^= LockState.Read; ++ctstate.ReaderRecursiveCount; --numReadWaiters; success = true; } else { Interlocked.Add(ref rwlock, -RwRead); } } if (success) { return(true); } writerDoneEvent.Wait(ComputeTimeout(millisecondsTimeout, start)); } while (millisecondsTimeout == -1 || (sw.ElapsedMilliseconds - start) < millisecondsTimeout); --numReadWaiters; return(false); }
public void CanDelete() { CreateRdbmsSchema(); using (var store = NewDocumentStore()) { var eventSlim = new ManualResetEventSlim(false); store.SystemDatabase.StartupTasks.OfType<SqlReplicationTask>() .First().AfterReplicationCompleted += successCount => { if (successCount != 0) eventSlim.Set(); }; using (var session = store.OpenSession()) { session.Store(new Order { OrderLines = new List<OrderLine> { new OrderLine{Cost = 3, Product = "Milk", Quantity = 3}, new OrderLine{Cost = 4, Product = "Bear", Quantity = 2}, } }); session.SaveChanges(); } SetupSqlReplication(store, defaultScript); eventSlim.Wait(TimeSpan.FromMinutes(5)); AssertCounts(1, 2); eventSlim.Reset(); store.DatabaseCommands.Delete("orders/1", null); eventSlim.Wait(TimeSpan.FromMinutes(5)); AssertCounts(0, 0); } }
private static void SendToRecvFrom_Datagram_UDP(IPAddress leftAddress, IPAddress rightAddress) { // TODO #5185: Harden against packet loss const int DatagramSize = 256; const int DatagramsToSend = 256; const int AckTimeout = 1000; const int TestTimeout = 30000; var left = new Socket(leftAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp); left.BindToAnonymousPort(leftAddress); var right = new Socket(rightAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp); right.BindToAnonymousPort(rightAddress); var leftEndpoint = (IPEndPoint)left.LocalEndPoint; var rightEndpoint = (IPEndPoint)right.LocalEndPoint; var receiverAck = new ManualResetEventSlim(); var senderAck = new ManualResetEventSlim(); var receivedChecksums = new uint?[DatagramsToSend]; var leftThread = new Thread(() => { using (left) { EndPoint remote = leftEndpoint.Create(leftEndpoint.Serialize()); var recvBuffer = new byte[DatagramSize]; for (int i = 0; i < DatagramsToSend; i++) { int received = left.ReceiveFrom(recvBuffer, SocketFlags.None, ref remote); Assert.Equal(DatagramSize, received); Assert.Equal(rightEndpoint, remote); int datagramId = (int)recvBuffer[0]; Assert.Null(receivedChecksums[datagramId]); receivedChecksums[datagramId] = Fletcher32.Checksum(recvBuffer, 0, received); receiverAck.Set(); Assert.True(senderAck.Wait(AckTimeout)); senderAck.Reset(); } } }); leftThread.Start(); var sentChecksums = new uint[DatagramsToSend]; using (right) { var random = new Random(); var sendBuffer = new byte[DatagramSize]; for (int i = 0; i < DatagramsToSend; i++) { random.NextBytes(sendBuffer); sendBuffer[0] = (byte)i; int sent = right.SendTo(sendBuffer, SocketFlags.None, leftEndpoint); Assert.True(receiverAck.Wait(AckTimeout)); receiverAck.Reset(); senderAck.Set(); Assert.Equal(DatagramSize, sent); sentChecksums[i] = Fletcher32.Checksum(sendBuffer, 0, sent); } } Assert.True(leftThread.Join(TestTimeout)); for (int i = 0; i < DatagramsToSend; i++) { Assert.NotNull(receivedChecksums[i]); Assert.Equal(sentChecksums[i], (uint)receivedChecksums[i]); } }
public bool TryEnterWriteLock(int millisecondsTimeout) { var currentThreadState = CurrentThreadState; if (CheckState(currentThreadState, millisecondsTimeout, LockState.Write)) { ++currentThreadState.WriterRecursiveCount; return(true); } ++WaitingWriteCount; var isUpgradable = (currentThreadState.LockState & LockState.Upgradable) > 0; var registered = false; var success = false; RuntimeHelpers.PrepareConstrainedRegions(); try { /* If the code goes there that means we had a read lock beforehand * that need to be suppressed, we also take the opportunity to register * our interest in the write lock to avoid other write wannabe process * coming in the middle */ if (isUpgradable && _rwLock >= _rwRead) { try { } finally { if (Interlocked.Add(ref _rwLock, _rwWaitUpgrade - _rwRead) >> _rwReadBit == 0) { _readerDoneEvent.Set(); } registered = true; } } var stateCheck = isUpgradable ? _rwWaitUpgrade + _rwWait : _rwWait; var start = millisecondsTimeout == -1 ? 0 : _stopwatch.ElapsedMilliseconds; var registration = isUpgradable ? _rwWaitUpgrade : _rwWait; do { var state = _rwLock; if (state <= stateCheck) { try { } finally { var toWrite = state + _rwWrite - (registered ? registration : 0); if (Interlocked.CompareExchange(ref _rwLock, toWrite, state) == state) { _writerDoneEvent.Reset(); currentThreadState.LockState ^= LockState.Write; ++currentThreadState.WriterRecursiveCount; --WaitingWriteCount; registered = false; success = true; } } if (success) { return(true); } } state = _rwLock; // We register our interest in taking the Write lock (if upgradeable it's already done) if (!isUpgradable) { while ((state & _rwWait) == 0) { try { } finally { registered |= Interlocked.CompareExchange(ref _rwLock, state | _rwWait, state) == state; } if (registered) { break; } state = _rwLock; } } // Before falling to sleep do { if (_rwLock <= stateCheck) { break; } if ((_rwLock & _rwWrite) != 0) { _writerDoneEvent.Wait(ComputeTimeout(millisecondsTimeout, start)); } else if (_rwLock >> _rwReadBit > 0) { _readerDoneEvent.Wait(ComputeTimeout(millisecondsTimeout, start)); } } while (millisecondsTimeout < 0 || _stopwatch.ElapsedMilliseconds - start < millisecondsTimeout); } while (millisecondsTimeout < 0 || _stopwatch.ElapsedMilliseconds - start < millisecondsTimeout); --WaitingWriteCount; } finally { if (registered) { Interlocked.Add(ref _rwLock, isUpgradable ? -_rwWaitUpgrade : -_rwWait); } } return(false); }
private static void SendToRecvFromAPM_Datagram_UDP(IPAddress leftAddress, IPAddress rightAddress) { // TODO #5185: Harden against packet loss const int DatagramSize = 256; const int DatagramsToSend = 256; const int AckTimeout = 1000; const int TestTimeout = 30000; var left = new Socket(leftAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp); left.BindToAnonymousPort(leftAddress); var right = new Socket(rightAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp); right.BindToAnonymousPort(rightAddress); var leftEndpoint = (IPEndPoint)left.LocalEndPoint; var rightEndpoint = (IPEndPoint)right.LocalEndPoint; var receiverAck = new ManualResetEventSlim(); var senderAck = new ManualResetEventSlim(); EndPoint receiveRemote = leftEndpoint.Create(leftEndpoint.Serialize()); var receiverFinished = new TaskCompletionSource<bool>(); var receivedChecksums = new uint?[DatagramsToSend]; var receiveBuffer = new byte[DatagramSize]; int receivedDatagrams = -1; Action<int, EndPoint> receiveHandler = null; receiveHandler = (received, remote) => { try { if (receivedDatagrams != -1) { Assert.Equal(DatagramSize, received); Assert.Equal(rightEndpoint, remote); int datagramId = (int)receiveBuffer[0]; Assert.Null(receivedChecksums[datagramId]); receivedChecksums[datagramId] = Fletcher32.Checksum(receiveBuffer, 0, received); receiverAck.Set(); Assert.True(senderAck.Wait(AckTimeout)); senderAck.Reset(); receivedDatagrams++; if (receivedDatagrams == DatagramsToSend) { left.Dispose(); receiverFinished.SetResult(true); return; } } else { receivedDatagrams = 0; } left.ReceiveFromAPM(receiveBuffer, 0, receiveBuffer.Length, SocketFlags.None, receiveRemote, receiveHandler); } catch (Exception ex) { receiverFinished.SetException(ex); } }; receiveHandler(0, null); var random = new Random(); var senderFinished = new TaskCompletionSource<bool>(); var sentChecksums = new uint[DatagramsToSend]; var sendBuffer = new byte[DatagramSize]; int sentDatagrams = -1; Action<int> sendHandler = null; sendHandler = sent => { try { if (sentDatagrams != -1) { Assert.True(receiverAck.Wait(AckTimeout)); receiverAck.Reset(); senderAck.Set(); Assert.Equal(DatagramSize, sent); sentChecksums[sentDatagrams] = Fletcher32.Checksum(sendBuffer, 0, sent); sentDatagrams++; if (sentDatagrams == DatagramsToSend) { right.Dispose(); senderFinished.SetResult(true); return; } } else { sentDatagrams = 0; } random.NextBytes(sendBuffer); sendBuffer[0] = (byte)sentDatagrams; right.SendToAPM(sendBuffer, 0, sendBuffer.Length, SocketFlags.None, leftEndpoint, sendHandler); } catch (Exception ex) { senderFinished.SetException(ex); } }; sendHandler(0); Assert.True(receiverFinished.Task.Wait(TestTimeout)); Assert.True(senderFinished.Task.Wait(TestTimeout)); for (int i = 0; i < DatagramsToSend; i++) { Assert.NotNull(receivedChecksums[i]); Assert.Equal(sentChecksums[i], (uint)receivedChecksums[i]); } }
public void TestGetReplicator() { if (!Boolean.Parse((string)Runtime.Properties["replicationTestsEnabled"])) { Assert.Inconclusive("Replication tests disabled."); return; } var replicationUrl = GetReplicationURL(); var replicator = database.CreatePullReplication(replicationUrl); Assert.IsNotNull(replicator); Assert.IsTrue(replicator.IsPull); Assert.IsFalse(replicator.Continuous); Assert.IsFalse(replicator.IsRunning); ReplicationStatus lastStatus = replicator.Status; var mre = new ManualResetEventSlim(); replicator.Changed += (sender, e) => { if(lastStatus != e.Source.Status) { lastStatus = e.Source.Status; mre.Set(); } }; replicator.Start(); Assert.IsTrue(mre.Wait(TimeSpan.FromSeconds(10)), "Timed out waiting for replicator to start"); Assert.IsTrue(replicator.IsRunning); var activeReplicators = new Replication[database.ActiveReplicators.Count]; database.ActiveReplicators.CopyTo(activeReplicators, 0); Assert.AreEqual(1, activeReplicators.Length); Assert.AreEqual(replicator, activeReplicators [0]); replicator.Stop(); mre.Reset(); Assert.IsTrue(mre.Wait(TimeSpan.FromSeconds(10)), "Timed out waiting for replicator to stop"); Assert.IsFalse(replicator.IsRunning); activeReplicators = new Replication[database.ActiveReplicators.Count]; database.ActiveReplicators.CopyTo(activeReplicators, 0); Assert.AreEqual(0, activeReplicators.Length); }
public void TestPusherChangedEvent() { if (!Boolean.Parse((string)GetProperty("replicationTestsEnabled"))) { Assert.Inconclusive("Replication tests disabled."); return; } using (var remoteDb = _sg.CreateDatabase(TempDbName())) { CreateDocuments(database, 2); var push = database.CreatePushReplication(remoteDb.RemoteUri); List<ReplicationStatus> statusHistory = new List<ReplicationStatus>(); push.Changed += (sender, e) => { statusHistory.Add(e.Status); if (e.ChangesCount > 0 && e.CompletedChangesCount != e.ChangesCount) { Assert.AreEqual(ReplicationStatus.Active, e.Status); } if (e.Status == ReplicationStatus.Stopped) { Assert.AreNotEqual(0, e.CompletedChangesCount); Assert.AreEqual(e.ChangesCount, e.CompletedChangesCount); } }; RunReplication(push); Sleep(1000); Assert.IsNull(push.LastError); foreach (var status in statusHistory.Take(statusHistory.Count - 1)) { Assert.AreEqual(ReplicationStatus.Active, status); } Assert.AreEqual(ReplicationStatus.Stopped, statusHistory[statusHistory.Count - 1]); CreateDocuments(database, 2); push = database.CreatePushReplication(remoteDb.RemoteUri); push.Continuous = true; statusHistory.Clear(); var doneEvent = new ManualResetEventSlim(); push.Changed += (sender, e) => { statusHistory.Add(e.Status); if(e.Status == ReplicationStatus.Idle && e.ChangesCount == e.CompletedChangesCount) { doneEvent.Set(); } }; push.Start(); Assert.IsTrue(doneEvent.Wait(TimeSpan.FromSeconds(60))); Assert.IsNull(push.LastError); foreach (var status in statusHistory.Take(statusHistory.Count - 1)) { Assert.AreEqual(ReplicationStatus.Active, status); } Assert.AreEqual(ReplicationStatus.Idle, statusHistory[statusHistory.Count - 1]); doneEvent.Reset(); statusHistory.Clear(); CreateDocuments(database, 1); Assert.IsTrue(doneEvent.Wait(TimeSpan.FromSeconds(60))); Assert.IsNull(push.LastError); foreach (var status in statusHistory.Take(statusHistory.Count - 1)) { Assert.IsTrue(status == ReplicationStatus.Active || status == ReplicationStatus.Idle); } Assert.AreEqual(ReplicationStatus.Idle, statusHistory[statusHistory.Count - 1]); doneEvent.Reset(); statusHistory.Clear(); StopReplication(push); Assert.AreEqual(2, statusHistory.Count); Assert.AreEqual(ReplicationStatus.Active, statusHistory.First()); Assert.AreEqual(ReplicationStatus.Stopped, statusHistory[1]); } }
public void Reset(int count) { evt.Reset(); initialCount = initial = count; }