Wait() public method

public Wait ( TimeSpan timeout ) : bool
timeout TimeSpan
return bool
コード例 #1
0
ファイル: BatchBlockTest.cs プロジェクト: Profit0004/mono
		public void BasicUsageTest ()
		{
			int[] array = null;
			var evt = new ManualResetEventSlim (false);

			var buffer = new BatchBlock<int> (10);
			var block = new ActionBlock<int[]> (i =>
			{
				array = i;
				evt.Set ();
			});
			buffer.LinkTo<int[]> (block);

			for (int i = 0; i < 9; i++)
				Assert.IsTrue (buffer.Post (i));

			Assert.IsFalse (evt.Wait (100));

			Assert.IsNull (array);

			Assert.IsTrue (buffer.Post (42));
			Assert.IsTrue (evt.Wait (1000));

			Assert.IsNotNull (array);
			CollectionAssert.AreEqual (new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 42 }, array);
		}
コード例 #2
0
ファイル: TimerTests.cs プロジェクト: Corillian/corefx
        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);
            }
        }
コード例 #3
0
		public void BasicUsageTest ()
		{
			Tuple<IList<int>, IList<int>, IList<string>> result = null;
			var evt = new ManualResetEventSlim (false);

			var actionBlock =
				new ActionBlock<Tuple<IList<int>, IList<int>, IList<string>>> (r =>
				{
					result = r;
					evt.Set ();
				});
			var block = new BatchedJoinBlock<int, int, string> (3);

			block.LinkTo (actionBlock);

			// all targets once
			Assert.IsTrue (block.Target1.Post (1));
			Assert.IsTrue (block.Target2.Post (2));

			Assert.IsFalse (evt.Wait (100));
			Assert.IsNull (result);

			Assert.IsTrue (block.Target3.Post ("foo"));

			Assert.IsTrue (evt.Wait (1000));

			Assert.IsNotNull (result);
			CollectionAssert.AreEqual (new[] { 1 }, result.Item1);
			CollectionAssert.AreEqual (new[] { 2 }, result.Item2);
			CollectionAssert.AreEqual (new[] { "foo" }, result.Item3);
		}
コード例 #4
0
        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();
                }
            }
        }
コード例 #5
0
ファイル: JoinBlockTest.cs プロジェクト: Profit0004/mono
		public void BasicUsageTest ()
		{
			Tuple<int, int> tuple = null;
			var evt = new ManualResetEventSlim (false);

			var ablock = new ActionBlock<Tuple<int, int>> (t =>
			{
				tuple = t;
				evt.Set ();
			});
			var block = new JoinBlock<int, int> ();
			block.LinkTo (ablock);

			block.Target1.Post (42);

			evt.Wait (1000);
			Assert.IsNull (tuple);

			block.Target2.Post (24);

			evt.Wait ();
			Assert.IsNotNull (tuple);
			Assert.AreEqual (42, tuple.Item1);
			Assert.AreEqual (24, tuple.Item2);
		}
コード例 #6
0
ファイル: BatchedJoinBlockTest.cs プロジェクト: nlhepler/mono
		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);
		}
コード例 #7
0
        public void PushTryPop(int producerThreads, int consumerThreads)
        {
            var stack = new ConcurrentStack<int>();
            var startEvent = new ManualResetEventSlim(false);
            var finished = 0;
            var stop = false;
            var producerTasks = Enumerable.Range(0, producerThreads).Select(i => Task.Factory.StartNew(() =>
                {
                    var count = iterations/producerThreads;
                    startEvent.Wait();
                    for (var j = 0; j < count; j++)
                        stack.Push(0);
                    Interlocked.Increment(ref finished);
                    if (finished >= producerThreads) stop = true;
                }, TaskCreationOptions.LongRunning)).ToArray();
            var consumerTasks = Enumerable.Range(0, consumerThreads).Select(i => Task.Factory.StartNew(() =>
                {
                    int num;
                    startEvent.Wait();
                    while (!stop) stack.TryPop(out num);
                }, TaskCreationOptions.LongRunning)).ToArray();

            var stopwatch = Stopwatch.StartNew();
            startEvent.Set();
            stop = true;
            Task.WaitAll(producerTasks);
            Task.WaitAll(consumerTasks);
            stopwatch.StopAndLog(iterations);
        }
コード例 #8
0
        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("終了");
        }
コード例 #9
0
ファイル: BatchBlockTest.cs プロジェクト: Profit0004/mono
		public void TriggerBatchTest ()
		{
			int[] array = null;
			var evt = new ManualResetEventSlim (false);

			var buffer = new BatchBlock<int> (10);
			var block = new ActionBlock<int[]> (i =>
			{
				array = i;
				evt.Set ();
			});
			buffer.LinkTo (block);

			for (int i = 0; i < 9; i++)
				Assert.IsTrue (buffer.Post (i));

			buffer.TriggerBatch ();
			evt.Wait ();

			Assert.IsNotNull (array);
			Assert.IsTrue (buffer.Post (42));
			evt.Wait (1600);

			CollectionAssert.AreEquivalent (new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 },
				array);
		}
コード例 #10
0
        public void when_sending_message_with_session_then_session_receiver_gets_it()
        {
            var sender = this.Settings.CreateTopicClient(this.Topic);
            var signal = new ManualResetEventSlim();
            var body = Guid.NewGuid().ToString();

            var receiver = new SessionSubscriptionReceiver(this.Settings, this.Topic, this.Subscription);

            sender.Send(new BrokeredMessage(Guid.NewGuid().ToString()));
            sender.Send(new BrokeredMessage(body) { SessionId = "foo" });

            var received = "";

            receiver.Start(
                m =>
                {
                    received = m.GetBody<string>();
                    signal.Set();
                    return MessageReleaseAction.CompleteMessage;
                });

            signal.Wait();

            receiver.Stop();

            Assert.Equal(body, received);
        }
コード例 #11
0
		public ETradeDispatcher(Action<Exception> errorHandler)
			: base(errorHandler)
		{
			const int num = 2; //num of Add() calls below
			var count = 0;
			var done = new ManualResetEventSlim(false);
			Action report = delegate
			{
				if (Interlocked.Increment(ref count) == num)
					done.Set();
			};
			int idmain, iddom;

			idmain = iddom = 0;

			Add(() =>
			{
				idmain = Thread.CurrentThread.ManagedThreadId;
				report();
			}, _eventThreadRequestName);

			Add(() =>
			{
				iddom = Thread.CurrentThread.ManagedThreadId;
				report();
			}, _eventThreadResponseName);

			done.Wait();

			_eventThreadRequestId = idmain;
			_eventThreadResponseId = iddom;
		}
コード例 #12
0
ファイル: Program.cs プロジェクト: andyedinborough/Forever
 public static void Test(Action action)
 {
     _remain = 100000;
     var mre = new ManualResetEventSlim(false);
     action();
     while (_remain > 0) mre.Wait(100);
 }
コード例 #13
0
        public void OpenCalledOnConnectionRestored()
        {
            int openInvoked = 0;
            var wh = new ManualResetEventSlim();

            var redisConnection = GetMockRedisConnection();

            var redisMessageBus = new Mock<RedisMessageBus>(GetDependencyResolver(), new RedisScaleoutConfiguration(String.Empty, String.Empty),
                redisConnection.Object) { CallBase = true };

            redisMessageBus.Setup(m => m.OpenStream(It.IsAny<int>())).Callback(() =>
            {
                // Open would be called twice - once when connection starts and once when it is restored
                if (++openInvoked == 2)
                {
                    wh.Set();
                }
            });

            // Creating an instance to invoke the constructor which starts the connection
            var instance = redisMessageBus.Object;

            redisConnection.Raise(mock => mock.ConnectionRestored += null, new Exception());

            Assert.True(wh.Wait(TimeSpan.FromSeconds(5)));
        }
コード例 #14
0
ファイル: ConnectionFacts.cs プロジェクト: kietnha/SignalR
        public void MarkActiveStopsConnectionIfCalledAfterExtendedPeriod(HostType hostType, TransportType transportType, MessageBusType messageBusType)
        {
            using (var host = CreateHost(hostType, transportType))
            {
                host.Initialize(messageBusType: messageBusType);
                var connection = CreateHubConnection(host);

                using (connection)
                {
                    var disconnectWh = new ManualResetEventSlim();

                    connection.Closed += () =>
                    {
                        disconnectWh.Set();
                    };

                    connection.Start(host.Transport).Wait();

                    // The MarkActive interval should check the reconnect window. Since this is short it should force the connection to disconnect.
                    ((Client.IConnection)connection).ReconnectWindow = TimeSpan.FromSeconds(1);

                    Assert.True(disconnectWh.Wait(TimeSpan.FromSeconds(15)), "Closed never fired");
                }
            }
        }
コード例 #15
0
        public void Ctor_ThrowsAnException_IfLockCanNotBeGranted()
        {
            var releaseLock = new ManualResetEventSlim(false);
            var lockAcquired = new ManualResetEventSlim(false);

            var thread = new Thread(
                () => UseConnection(connection1 =>
                {
                    var storage = CreateStorage(connection1);
                    using (new SqlServerDistributedLock(storage, "exclusive", _timeout))
                    {
                        lockAcquired.Set();
                        releaseLock.Wait();
                    }
                }));
            thread.Start();

            lockAcquired.Wait();

            UseConnection(connection2 =>
            {
                var storage = CreateStorage(connection2);
                Assert.Throws<DistributedLockTimeoutException>(
                    () =>
                    {
                        using (new SqlServerDistributedLock(storage, "exclusive", _timeout))
                        {
                        }
                    });
            });

            releaseLock.Set();
            thread.Join();
        }
コード例 #16
0
ファイル: EndToEndTests.cs プロジェクト: ZixiangBoy/SignalR-1
        public async Task WebSocketSendReceiveTest()
        {
            const int MessageCount = 3;
            var sentMessages = new List<string>();
            var receivedMessages = new List<string>();

            using (var hubConnection = new HubConnection(HubUrl))
            {
                var wh = new ManualResetEventSlim();

                var proxy = hubConnection.CreateHubProxy("StoreWebSocketTestHub");
                proxy.On<string>("echo", m =>
                {
                    receivedMessages.Add(m);
                    if (receivedMessages.Count == MessageCount)
                    {
                        wh.Set();
                    }
                });

                await hubConnection.Start(new WebSocketTransport());

                for (var i = 0; i < MessageCount; i++)
                {
                    var message = "MyMessage" + i;
                    await proxy.Invoke("Echo", message);
                    sentMessages.Add(message);
                }

                await Task.Run(() => wh.Wait(5000));
            }

            Assert.Equal(sentMessages, receivedMessages);
        }
コード例 #17
0
        private static void Main(string[] args)
        {
            var taskOne = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Task 1 is starting...");
                Thread.Sleep(5000);
                ManualResetEventSlim.Set();
                Console.WriteLine("Task 1 is completed.");
            });

            var taskTwo = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Task 2 waiting for Task 1 to complete...");
                ManualResetEventSlim.Wait();
                Console.WriteLine("Task 2 is started...");

                Console.WriteLine("All tasks are completed");
            });


            taskTwo.Wait();


            Console.ReadLine();
        }
コード例 #18
0
        private bool RawSendHelper(byte[] aData, bool aWait)
        {
            if (IsInBackgroundThread)
            {
                return SendRawData(aData);
            }
            if (!IsConnected)
            {
                return false;
            }
            if (aWait)
            {
                using (var xEvent = new ManualResetEventSlim(false))
                {
                    mPendingWrites.Add(new Outgoing {Packet = aData, Completed = xEvent});
                    while (IsConnected)
                    {
                        if (xEvent.Wait(25))
                        {
                            break;
                        }
                    }
                    return IsConnected; // ??
                }
            }
            else
            {
                mPendingWrites.Add(new Outgoing {Packet = aData});
                return true;
            }

        }
コード例 #19
0
ファイル: StressRuns.cs プロジェクト: nonintanon/SignalR
        public static IDisposable RunConnectDisconnect(int connections)
        {
            var host = new MemoryHost();

            host.MapHubs();

            for (int i = 0; i < connections; i++)
            {
                var connection = new Client.Hubs.HubConnection("http://foo");
                var proxy = connection.CreateHubProxy("EchoHub");
                var wh = new ManualResetEventSlim(false);

                proxy.On("echo", _ => wh.Set());

                try
                {
                    connection.Start(host).Wait();

                    proxy.Invoke("Echo", "foo").Wait();

                    if (!wh.Wait(TimeSpan.FromSeconds(10)))
                    {
                        Debugger.Break();
                    }
                }
                finally
                {
                    connection.Stop();
                }
            }

            return host;
        }
コード例 #20
0
        public void BackgroundHttpRequester_StopAsync_Stops_Current_Active_Request()
        {
            var cancelled = false;
            var mre = new ManualResetEventSlim();

            Func<Uri, CancellationToken, bool> processor = (u, c) =>
            {
                try
                {
                    mre.Wait(c);
                }
                catch (AggregateException)
                {
                }
                catch (OperationCanceledException)
                {
                }
                mre.Set();
                cancelled = c.IsCancellationRequested;
                return true;
            };

            var requester = new BackgroundHttpFuncRequester(processor);
            requester.Add(TestHelpers.CreateRequestList(1)[0]);
            requester.Start(TimeSpan.FromMilliseconds(10));

            Assert.IsFalse(cancelled);
            requester.StopAsync().Wait(3000);

            Assert.IsTrue(mre.Wait(3000));
            Assert.IsTrue(cancelled);
        }
コード例 #21
0
        // 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();
        }
コード例 #22
0
        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();
        }
コード例 #23
0
        public void UseSqlNotificationsIfAvailable(bool supportSqlNotifications)
        {
            // Arrange
            var sqlDependencyAdded = false;
            var retryLoopCount = 0;
            var mre = new ManualResetEventSlim();
            var dbProviderFactory = new MockDbProviderFactory();
            var dbBehavior = new Mock<IDbBehavior>();
            dbBehavior.Setup(db => db.UpdateLoopRetryDelays).Returns(_defaultRetryDelays);
            dbBehavior.Setup(db => db.StartSqlDependencyListener()).Returns(supportSqlNotifications);
            dbBehavior.Setup(db => db.AddSqlDependency(It.IsAny<IDbCommand>(), It.IsAny<Action<SqlNotificationEventArgs>>()))
                .Callback(() =>
                {
                    sqlDependencyAdded = true;
                    mre.Set();
                });
            var operation = new ObservableDbOperation("test", "test", new TraceSource("test"), dbProviderFactory, dbBehavior.Object);
            operation.Faulted += _ => mre.Set();
            operation.Queried += () =>
            {
                retryLoopCount++;
                if (retryLoopCount > 1)
                {
                    mre.Set();
                }
            };

            // Act
            ThreadPool.QueueUserWorkItem(_ => operation.ExecuteReaderWithUpdates((record, o) => { }));
            mre.Wait();
            operation.Dispose();

            // Assert
            Assert.Equal(supportSqlNotifications, sqlDependencyAdded);
        }
コード例 #24
0
ファイル: BasicIrc.cs プロジェクト: hova0/badimebot
    /// <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;
        }
    }
コード例 #25
0
        public void events_raised_whilst_consuming_events_should_be_recorded()
        {
            var waitForConsumption = new ManualResetEventSlim(false);
            Transaction consumerTransaction = null;

            var eventStore = Substitute.For<EventStore>();

            //Because consumers run in background threads, we need to block until complete before we assert.
            eventStore.When(_ => _.LogConsumption(Arg.Any<RaisedEvent>(), Arg.Any<ConsumptionLog>())).Do(info =>
                                                                                                             {
                                                                                                                 consumerTransaction =
                                                                                                                     Transaction.Current;
                                                                                                                 waitForConsumption.Set();
                                                                                                             });

            var domain = new TestableDomain(null, null, eventStore);

            var key = "test";

            domain.Consume(
                new RaisedEvent(
                    new DogRegistered(key, null),
                    DateTimeOffset.UtcNow));

            waitForConsumption.Wait();

            var aggregateInfo = domain.AggregateTracker[typeof (Dog), key];

            ((string) aggregateInfo.Instance.AsDynamic().earbrand).ShouldEqual(key);
            aggregateInfo.Lifestate.ShouldEqual(AggregateLifestate.Live);

            var recorded = domain.TransactionTracker[consumerTransaction].RecordedEvents;
            recorded.Count().ShouldEqual(1);
            recorded.First().Event.ShouldBeType<DogIsNotVaccinated>();
        }
コード例 #26
0
ファイル: BulkInsert.cs プロジェクト: robashton/ravendb
		public override void Respond(IHttpContext context)
		{
			if (string.IsNullOrEmpty(context.Request.QueryString["no-op"]) == false)
			{
				// this is a no-op request which is there just to force the client HTTP layer to handle the authentication
				// only used for legacy clients
				return; 
			}
			if("generate-single-use-auth-token".Equals(context.Request.QueryString["op"],StringComparison.InvariantCultureIgnoreCase))
			{
				// using windows auth with anonymous access = none sometimes generate a 401 even though we made two requests
				// instead of relying on windows auth, which require request buffering, we generate a one time token and return it.
				// we KNOW that the user have access to this db for writing, since they got here, so there is no issue in generating 
				// a single use token for them.
				var token = server.RequestAuthorizer.GenerateSingleUseAuthToken(Database, context.User);
				context.WriteJson(new
				{
					Token = token
				});
				return;
			}

			if (HttpContext.Current != null)
			{
				HttpContext.Current.Server.ScriptTimeout = 60*60*6; // six hours should do it, I think.
			}
			var options = new BulkInsertOptions
			{
				CheckForUpdates = context.GetCheckForUpdates(),
				CheckReferencesInIndexes = context.GetCheckReferencesInIndexes()
			};

			var operationId = ExtractOperationId(context);
			var sp = Stopwatch.StartNew();

			var status = new BulkInsertStatus();

			int documents = 0;
			var mre = new ManualResetEventSlim(false);

			var currentDatbase = Database;
			var task = Task.Factory.StartNew(() =>
			{
				currentDatbase.BulkInsert(options, YieldBatches(context, mre, batchSize => documents += batchSize), operationId);
			    status.Documents = documents;
			    status.Completed = true;
			});

			long id;
			Database.AddTask(task, status, out id);

			mre.Wait(Database.WorkContext.CancellationToken);

			context.Log(log => log.Debug("\tBulk inserted received {0:#,#;;0} documents in {1}, task #: {2}", documents, sp.Elapsed, id));

			context.WriteJson(new
			{
				OperationId = id
			});
		}
コード例 #27
0
        public async Task CanInvokeMethodsAndReceiveMessagesFromValidTypedHub(HostType hostType, TransportType transportType, MessageBusType messageBusType)
        {
            using (var host = CreateHost(hostType, transportType))
            {
                host.Initialize(messageBusType: messageBusType);

                using (var connection = CreateHubConnection(host))
                {
                    var hub = connection.CreateHubProxy("ValidTypedHub");
                    var echoTcs = new TaskCompletionSource<string>();
                    var pingWh = new ManualResetEventSlim();

                    hub.On<string>("Echo", message => echoTcs.TrySetResult(message));
                    hub.On("Ping", pingWh.Set);

                    await connection.Start(host.TransportFactory());

                    hub.InvokeWithTimeout("Echo", "arbitrary message");
                    Assert.True(echoTcs.Task.Wait(TimeSpan.FromSeconds(10)));
                    Assert.Equal("arbitrary message", echoTcs.Task.Result);

                    hub.InvokeWithTimeout("Ping");
                    Assert.True(pingWh.Wait(TimeSpan.FromSeconds(10)));
                }
            }
        }
コード例 #28
0
ファイル: DisconnectFacts.cs プロジェクト: kppullin/SignalR
        public void DisconnectFiresForHubsWhenConnectionGoesAway()
        {
            using (var host = new MemoryHost())
            {
                host.MapHubs();
                host.Configuration.DisconnectTimeout = TimeSpan.Zero;
                host.Configuration.HeartbeatInterval = TimeSpan.FromSeconds(5);
                var connectWh = new ManualResetEventSlim();
                var disconnectWh = new ManualResetEventSlim();
                host.DependencyResolver.Register(typeof(MyHub), () => new MyHub(connectWh, disconnectWh));
                var connection = new Client.Hubs.HubConnection("http://foo/");

                connection.CreateHubProxy("MyHub");

                // Maximum wait time for disconnect to fire (3 heart beat intervals)
                var disconnectWait = TimeSpan.FromTicks(host.Configuration.HeartbeatInterval.Ticks * 3);

                connection.Start(host).Wait();

                Assert.True(connectWh.Wait(TimeSpan.FromSeconds(10)), "Connect never fired");

                connection.Stop();

                Assert.True(disconnectWh.Wait(disconnectWait), "Disconnect never fired");
            }
        }
コード例 #29
0
        static void DoWork(CancellationToken token)
        {
            while (true)
            {
                if (token.IsCancellationRequested)
                {
                    Console.WriteLine("Canceled while running.");
                    token.ThrowIfCancellationRequested();
                }

                // Wait on the event to be signaled
                // or the token to be canceled,
                // whichever comes first. The token
                // will throw an exception if it is canceled
                // while the thread is waiting on the event.
                try
                {
                    // mres is a ManualResetEventSlim
                    mres.Wait(token);
                }
                catch (OperationCanceledException)
                {
                    // Throw immediately to be responsive. The
                    // alternative is to do one more item of work,
                    // and throw on next iteration, because
                    // IsCancellationRequested will be true.
                    Console.WriteLine("The wait operation was canceled.");
                    throw;
                }

                Console.Write("Working...");
                // Simulating work.
                Thread.SpinWait(500000);
            }
        }
コード例 #30
0
ファイル: CommandsTests.cs プロジェクト: Degot/Rhino.Raft
		public void When_command_committed_CompletionTaskSource_is_notified()
		{
			const int CommandCount = 5;
			var leader = CreateNetworkAndGetLeader(3);
			var commands = Builder<DictionaryCommand.Set>.CreateListOfSize(CommandCount)
				.All()
				.With(x => x.Completion = new TaskCompletionSource<object>())
				.With(x => x.AssignedIndex = -1)
				.Build()
				.ToList();


			var nonLeaderNode = Nodes.First(x => x.State != RaftEngineState.Leader);
			var commitsAppliedEvent = new ManualResetEventSlim();

			nonLeaderNode.CommitIndexChanged += (oldIndex, newIndex) =>
			{
				//CommandCount + 1 --> take into account NOP command that leader sends after election
				if (newIndex == CommandCount + 1)
					commitsAppliedEvent.Set();
			};

			commands.ForEach(leader.AppendCommand);

			Assert.True(commitsAppliedEvent.Wait(nonLeaderNode.Options.ElectionTimeout * 2));
			commands.Should().OnlyContain(cmd => cmd.Completion.Task.Status == TaskStatus.RanToCompletion);
		}
コード例 #31
0
        public void when_sending_message_then_can_receive_it()
        {
            var sender = new TopicSender(this.Settings, this.Topic);
            Data data = new Data { Id = Guid.NewGuid(), Title = "Foo" };
            Data received = null;
            using (var receiver = new SubscriptionReceiver(this.Settings, this.Topic, this.Subscription))
            {
                var signal = new ManualResetEventSlim();

                receiver.Start(
                    m =>
                    {
                        received = m.GetBody<Data>();
                        signal.Set();
                        return MessageReleaseAction.CompleteMessage;
                    });

                sender.SendAsync(() => new BrokeredMessage(data));

                signal.Wait();
            }

            Assert.NotNull(received);
            Assert.Equal(data.Id, received.Id);
            Assert.Equal(data.Title, received.Title);
        }
コード例 #32
0
        public async void ConnectRetriesOnError()
        {
            int invokationCount = 0;
            var wh = new ManualResetEventSlim();
            var redisConnection = GetMockRedisConnection();

            var tcs = new TaskCompletionSource<object>();
            tcs.TrySetCanceled();

            redisConnection.Setup(m => m.ConnectAsync(It.IsAny<string>(), It.IsAny<TraceSource>())).Returns<string, TraceSource>((connectionString, trace) =>
            {
                if (++invokationCount == 2)
                {
                    wh.Set();
                    return Task.FromResult(0);
                }
                else
                {
                    return tcs.Task;
                }
            });

            var redisMessageBus = new RedisMessageBus(GetDependencyResolver(), new RedisScaleoutConfiguration(String.Empty, String.Empty),
            redisConnection.Object, false);

            await redisMessageBus.ConnectWithRetry();

            Assert.True(wh.Wait(TimeSpan.FromSeconds(5)));
            Assert.Equal(RedisMessageBus.State.Connected, redisMessageBus.ConnectionState);
        }
コード例 #33
0
ファイル: HubProxyFacts.cs プロジェクト: hallco978/SignalR
        public void ConnectionErrorCapturesExceptionsThrownInClientHubMethod(HostType hostType, TransportType transportType)
        {
            using (var host = CreateHost(hostType, transportType))
            {
                var wh = new ManualResetEventSlim();
                Exception thrown = new Exception(),
                          caught = null;

                host.Initialize();

                var connection = CreateHubConnection(host);
                var proxy = connection.CreateHubProxy("ChatHub");

                proxy.On("addMessage", () =>
                {
                    throw thrown;
                });

                connection.Error += e =>
                {
                    caught = e;
                    wh.Set();
                };

                connection.Start(host.Transport).Wait();
                proxy.Invoke("Send", "");

                Assert.True(wh.Wait(TimeSpan.FromSeconds(5)));
                Assert.Equal(thrown, caught);
            }
        }
コード例 #34
0
ファイル: ChannelExtensions.cs プロジェクト: kenkendk/cocol
        /// <summary>
        /// Blocking wait for a task, equivalent to calling Task.Wait(),
        /// but works around a race in Mono that causes Wait() to hang
        /// </summary>
        /// <param name="task">The task to wait for</param>
        /// <returns>The task</returns>
        public static Task WaitForTask(this Task task)
        {
            // Mono has a race when waiting for a
            // task to complete, this workaround
            // ensures that the wait call does not hang
            if (IsRunningMono)
            {
                if (!task.IsCompleted)
                {
                    using (var lck = new System.Threading.ManualResetEventSlim(false))
                    {
                        task.ContinueWith(x => lck.Set());
                        // This ensures we never return with
                        // an incomplete task, but may casue
                        // some spin waiting
                        while (!task.IsCompleted)
                        {
                            lck.Wait();
                        }
                    }
                }
            }
            else
            {
                try { task.Wait(); }
                catch
                {
                    // Don't throw the exception here
                    // let the caller access the task
                }
            }

            return(task);
        }
コード例 #35
0
        public void TestAllow()
        {
            var configSource = StartBootstrap("ConnectionFilter.config");
            var serverConfig = configSource.Servers.FirstOrDefault();
            var appServer = BootStrap.AppServers.FirstOrDefault() as TestServer;
            appServer.NewSessionConnected += m_Server_NewSessionConnected;

            EndPoint serverAddress = new IPEndPoint(IPAddress.Parse("127.0.0.1"), serverConfig.Port);

            using (Socket socket = new Socket(serverAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
            {
                TestConnectionFilter.Allow = true;
                int oldCount = TestConnectionFilter.ConnectedCount;

                var signal = new ManualResetEventSlim(false);

                ThreadPool.QueueUserWorkItem((o) =>
                    {
                        var s = o as Socket;
                        s.Connect(serverAddress);
                        signal.Set();
                    }, socket);

                Assert.IsTrue(signal.Wait(2000));
                Thread.Sleep(100);
                Assert.AreEqual(oldCount + 1, TestConnectionFilter.ConnectedCount);

                if (!m_NewSessionConnectedEvent.WaitOne(1000))
                    Assert.Fail("New session hasnot been accept on time!");
            }
        }
コード例 #36
0
        [Test]         // bug https://bugzilla.novell.com/show_bug.cgi?id=325368
        public void EnabledInElapsed()
        {
            var elapsedCount = 0;
            var mre          = new ST.ManualResetEventSlim();

            timer           = new Timer(50);
            timer.AutoReset = false;
            timer.Elapsed  += (s, e) =>
            {
                elapsedCount++;
                if (elapsedCount == 1)
                {
                    timer.Enabled = true;
                }
                else if (elapsedCount == 2)
                {
                    mre.Set();
                }
            };
            timer.Start();

            Assert.IsTrue(mre.Wait(1000), "#1 re-enabling timer in Elapsed didn't work");
            Assert.AreEqual(2, elapsedCount, "#2 wrong elapsedCount");
            timer.Stop();
        }
コード例 #37
0
        public void Can_create_actor_using_remote_daemon_and_interact_with_child()
        {
            var p = CreateTestProbe();
            Sys.EventStream.Subscribe(p.Ref, typeof(string));
            var supervisor = Sys.ActorOf<SomeActor>();
            var provider = (RemoteActorRefProvider)((ActorSystemImpl)Sys).Provider;
            var daemon = provider.RemoteDaemon;
            var childCreatedEvent=new ManualResetEventSlim();


            var path = (((ActorSystemImpl)Sys).Guardian.Path.Address + "/remote/user/foo").ToString();

            //ask to create an actor MyRemoteActor, this actor has a child "child"
            daemon.Tell(new DaemonMsgCreate(Props.Create(() => new MyRemoteActor(childCreatedEvent)), null, path, supervisor));

            //Wait for the child to be created (actors are instantiated async)
            childCreatedEvent.Wait();

            //try to resolve the child actor "child"
            var child = provider.ResolveActorRef(provider.RootPath / "remote/user/foo/child".Split('/'));
            //pass a message to the child
            child.Tell("hello");
            //expect the child to forward the message to the eventstream
            p.ExpectMsg("hello");
        }
コード例 #38
0
 public void Start()
 {
     try
     {
         slim.Wait();
         slim.Reset();
     }
     finally
     {
         slim.Set();
     }
 }
コード例 #39
0
        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);
                }
        }
コード例 #40
0
ファイル: JobQueue.cs プロジェクト: sq/Libraries
        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);
                }
            }
        }
コード例 #41
0
ファイル: TimerTest.cs プロジェクト: SickheadGames/BRUTE.mono
		public void AutoResetEventFalseStopsFiringElapsed ()
		{
			var elapsedCount = 0;
			var mre = new ST.ManualResetEventSlim ();
			timer = new Timer (50);
			timer.AutoReset = false;
			timer.Elapsed += (s, e) =>
			{
				elapsedCount++;
				if (elapsedCount > 1)
					mre.Set ();
			};
			timer.Start ();

			Assert.IsFalse (mre.Wait (1000), "#1 AutoReset=false didn't stop firing Elapsed, elapsedCount=" + elapsedCount);
			Assert.AreEqual (1, elapsedCount, "#2 wrong elapsedCount");
			timer.Stop ();
		}
コード例 #42
0
        public virtual bool TryGetResponse(out string response, int millisecondsTimeout)
        {
            var    mre  = new System.Threading.ManualResetEventSlim(false);
            string resp = response = null;

            ThreadPool.QueueUserWorkItem(_ => {
                resp = GetResponse();
                mre.Set();
            });

            if (mre.Wait(millisecondsTimeout))
            {
                response = resp;
                return(true);
            }
            else
            {
                return(false);
            }
        }
コード例 #43
0
 public override void Send(SendOrPostCallback d, object state)
 {
     if (Thread.CurrentThread != m_thread)
     {
         using (var signal = new System.Threading.ManualResetEventSlim())
         {
             Post(
                 (s) =>
             {
                 d(s);
                 signal.Set();
             },
                 state
                 );
             signal.Wait();
         }
     }
     else
     {
         d(state);
     }
 }
コード例 #44
0
        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
                    {
                        // Empty
                    }
                    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
                        {
                            // Empty
                        }
                        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
                            {
                                // Empty
                            }
                            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);
        }
コード例 #45
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
            {
                // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                while (!_upgradableEvent.IsSet || !taken)
                {
                    try
                    {
                        // Empty
                    }
                    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);
        }
コード例 #46
0
        private bool TryEnterReadLock(int millisecondsTimeout, ref bool success)
        {
            var 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;
            var start = millisecondsTimeout == -1 ? 0 : _stopwatch.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 || (_stopwatch.ElapsedMilliseconds - start) < millisecondsTimeout);

            --_numReadWaiters;
            return(false);
        }
コード例 #47
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)
        {
            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);
        }
コード例 #48
0
ファイル: TaskScheduler.cs プロジェクト: sq/Libraries
        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);
                    }
                }
            }
        }
コード例 #49
0
ファイル: Barrier.net35.cs プロジェクト: MasterMeyer/Theraot
        /// <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.");
            }
            else if (participantCount > Max_Participants) //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 = Thread.VolatileRead(ref _currentTotalCount);
                int  total;
                int  current;
                bool sense;
                GetCurrentTotal(currentTotal, out current, out total, out sense);
                if (participantCount + total > Max_Participants) //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 nextphase 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 ehich the current participant is goint to wait on is still set
                    // (FinishPPhase 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);
        }
コード例 #50
0
        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);
        }
コード例 #51
0
        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 = default;
            long     newPhase;

            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(sleep1Threshold: -1);
            }
            return(newPhase);
        }