private void OnEvent(Event e)
        {
            int waitHandle = e._WaitHandle;

            PendingRecord pendingRecord;

            lock (pendingRecords)
            {
                if (!pendingRecords.TryGetValue(waitHandle, out pendingRecord))
                {
                    return;
                }
                if (--pendingRecord.Count == 0)
                {
                    pendingRecords.Remove(waitHandle);
                }
            }

            if (pendingRecord.Count == 0)
            {
                if (pendingRecord.HandleAllocated)
                {
                    WaitHandlePool.Release(waitHandle);
                }

                TimeFlow.Default.Cancel(pendingRecord.TimeoutToken);
                Unbind(new Event {
                    _WaitHandle = waitHandle
                }, OnEvent);
                Unbind((TimeoutEvent)pendingRecord.TimeoutToken.value, OnTimeout);
            }

            Interlocked.Decrement(ref sessionRefCount);
        }
        private void OnTimeout(TimeoutEvent e)
        {
            Trace.Debug("{0} response timeout {1}", Name, e.Key);

            int waitHandle = (int)e.Key;

            int           count = 0;
            PendingRecord pendingRecord;

            lock (pendingRecords)
            {
                if (!pendingRecords.TryGetValue(waitHandle, out pendingRecord))
                {
                    return;
                }
                count = pendingRecord.Count;
                pendingRecords.Remove(waitHandle);
            }

            if (pendingRecord.HandleAllocated)
            {
                WaitHandlePool.Release(waitHandle);
            }

            Unbind(new Event {
                _WaitHandle = waitHandle
            }, OnEvent);
            Unbind((TimeoutEvent)pendingRecord.TimeoutToken.value, OnTimeout);

            Interlocked.Add(ref sessionRefCount, -count);
        }
        protected WaitForAnyEvent(Coroutine coroutine, Event[] requests,
                                  double seconds, params Event[] e)
        {
            this.coroutine = coroutine;

            if (!ReferenceEquals(requests, null))
            {
                waitHandle = WaitHandlePool.Acquire();
                for (int i = 0, count = requests.Length; i < count; ++i)
                {
                    requests[i]._WaitHandle = waitHandle;
                }
                for (int i = 0, count = e.Length; i < count; ++i)
                {
                    e[i]._WaitHandle = waitHandle;
                }
            }

            expected = e;

            handlerTokens = new Binding.Token[expected.Length];
            for (int i = 0; i < expected.Length; ++i)
            {
                handlerTokens[i] = Flow.Bind(expected[i], OnEvent);
            }

            if (seconds > 0)
            {
                TimeoutEvent timeoutEvent = new TimeoutEvent {
                    Key = this
                };
                timeoutToken = Flow.Bind(timeoutEvent, OnTimeout);
                timerToken   = TimeFlow.Default.Reserve(timeoutEvent, seconds);
            }
        }
        void OnEvent(Event e)
        {
            for (int i = 0; i < expected.Length; ++i)
            {
                if (actual[i] == null && expected[i].Equivalent(e))
                {
                    Flow.Unbind(handlerTokens[i]);
                    handlerTokens[i] = new Binding.Token();
                    actual[i]        = e;
                    ++count;
                    break;
                }
            }

            if (count >= expected.Length)
            {
                if (timerToken.HasValue)
                {
                    TimeFlow.Default.Cancel(timerToken.Value);
                    Flow.Unbind(timeoutToken);
                }

                if (waitHandle != 0)
                {
                    WaitHandlePool.Release(waitHandle);
                }

                coroutine.Result = actual;
                coroutine.Continue();
            }
        }
示例#5
0
        void OnTimeout(TimeoutEvent e)
        {
            Flow.Unbind(handlerToken);
            Flow.Unbind(timeoutToken);

            int waitHandle = handlerToken.Key._WaitHandle;

            if (waitHandle != 0)
            {
                WaitHandlePool.Release(waitHandle);
            }

            Trace.Error("WaitForEvent timeout for {0}", handlerToken.Key);

            coroutine.Status = CoroutineStatus.Timeout;
            coroutine.Result = null;  // indicates timeout
            coroutine.Continue();
        }
示例#6
0
        void OnEvent(Event e)
        {
            Flow.Unbind(handlerToken);

            if (timerToken.HasValue)
            {
                TimeFlow.Default.Cancel(timerToken.Value);
                Flow.Unbind(timeoutToken);
            }

            int waitHandle = handlerToken.Key._WaitHandle;

            if (waitHandle != 0)
            {
                WaitHandlePool.Release(waitHandle);
            }

            coroutine.Result = e;
            coroutine.Continue();
        }
        void OnTimeout(TimeoutEvent e)
        {
            for (int i = 0, length = expected.Length; i < length; ++i)
            {
                Flow.Unbind(handlerTokens[i]);
            }

            Flow.Unbind(timeoutToken);

            if (waitHandle != 0)
            {
                WaitHandlePool.Release(waitHandle);
            }

            Trace.Error("WaitForAnyEvent timeout for {0}", expected);

            coroutine.Status = CoroutineStatus.Timeout;
            coroutine.Result = null;
            coroutine.Continue();
        }
        public void ConnectAndRequest(Event req)
        {
            int waitHandle = req._WaitHandle;

            bool handleAllocated = false;

            if (waitHandle == 0)
            {
                waitHandle      = WaitHandlePool.Acquire();
                req._WaitHandle = waitHandle;
                handleAllocated = true;
            }

            lock (pendingRecords)
            {
                PendingRecord pendingRecord;
                if (!pendingRecords.TryGetValue(waitHandle, out pendingRecord))
                {
                    TimeoutEvent timeoutEvent = new TimeoutEvent {
                        Key = waitHandle
                    };

                    Bind(new Event {
                        _WaitHandle = waitHandle
                    }, OnEvent);
                    Bind(timeoutEvent, OnTimeout);

                    pendingRecord = new PendingRecord {
                        HandleAllocated = handleAllocated,
                        TimeoutToken    =
                            TimeFlow.Default.Reserve(timeoutEvent, ResponseTimeout)
                    };
                    pendingRecords.Add(waitHandle, pendingRecord);
                }
                ++pendingRecord.Count;
            }

            Interlocked.Increment(ref sessionRefCount);

            ConnectAndSend(req);
        }
示例#9
0
        protected WaitForEvent(Coroutine coroutine, Event request, Event e, double seconds)
        {
            this.coroutine = coroutine;

            if (!ReferenceEquals(request, null))
            {
                int waitHandle = WaitHandlePool.Acquire();
                request._WaitHandle = waitHandle;
                e._WaitHandle       = waitHandle;
            }

            handlerToken = Flow.Bind(e, OnEvent);
            if (seconds > 0)
            {
                TimeoutEvent timeoutEvent = new TimeoutEvent {
                    Key = this
                };
                timeoutToken = Flow.Bind(timeoutEvent, OnTimeout);
                timerToken   = TimeFlow.Default.Reserve(timeoutEvent, seconds);
            }
        }
示例#10
0
        void OnTimeout(TimeoutEvent e)
        {
            for (int i = 0, count = actual.Length; i < count; ++i)
            {
                if (ReferenceEquals(actual[i], null))
                {
                    Flow.Unbind(handlerTokens[i]);
                }
            }
            Flow.Unbind(timeoutToken);

            if (waitHandle != 0)
            {
                WaitHandlePool.Release(waitHandle);
            }

            Trace.Error("WaitForAllEvents timeout for {0}", expected);

            coroutine.Status = CoroutineStatus.Timeout;
            coroutine.Result = actual;  // incomplete array indicates timeout
            coroutine.Continue();
        }
示例#11
0
        void OnEvent(Event e)
        {
            int i;
            int length = expected.Length;

            for (i = 0; i < length; ++i)
            {
                if (expected[i].Equivalent(e))
                {
                    break;
                }
            }

            if (i >= length)
            {
                return;
            }

            for (i = 0; i < length; ++i)
            {
                Flow.Unbind(handlerTokens[i]);
            }

            if (timerToken.HasValue)
            {
                TimeFlow.Default.Cancel(timerToken.Value);
                Flow.Unbind(timeoutToken);
            }

            if (waitHandle != 0)
            {
                WaitHandlePool.Release(waitHandle);
            }

            coroutine.Result = e;
            coroutine.Continue();
        }