예제 #1
0
 public ScoringEventLoop(IEventLoop innerLoop, IEventProducer <IActivity> innerProducer, IEventConsumer <IActivity> consumer, IScorable <IActivity, Score> scorable)
 {
     SetField.NotNull(out this.innerLoop, nameof(innerLoop), innerLoop);
     SetField.NotNull(out this.innerProducer, nameof(innerProducer), innerProducer);
     SetField.NotNull(out this.consumer, nameof(consumer), consumer);
     SetField.NotNull(out this.scorable, nameof(scorable), scorable);
 }
예제 #2
0
 internal Document(IBrowsingContext context, TextSource source)
     : base(null, "#document", NodeType.Document)
 {
     _async             = true;
     _designMode        = false;
     _firedUnload       = false;
     _salvageable       = true;
     _shown             = false;
     _context           = context;
     _source            = source;
     Referrer           = String.Empty;
     ContentType        = MimeTypeNames.ApplicationXml;
     _ready             = DocumentReadyState.Loading;
     _sandbox           = Sandboxes.None;
     _quirksMode        = QuirksMode.Off;
     _loadingScripts    = new Queue <HtmlScriptElement>();
     _location          = new Location("about:blank");
     _ranges            = new List <WeakReference <Range> >();
     _location.Changed += LocationChanged;
     _view              = new Window(this);
     _loader            = context.CreateService <IResourceLoader>();
     _loop              = context.CreateService <IEventLoop>();
     _mutations         = new MutationHost(_loop);
     _subtasks          = new List <Task>();
     _statusCode        = HttpStatusCode.OK;
 }
        public async ValueTask <bool> ReleaseAsync(IChannel channel)
        {
            Contract.Requires(channel != null);

            log.Debug("ReleaseAsync for " + channel.Id);

            try
            {
                IEventLoop loop = channel.EventLoop;

                log.Debug("ReleaseAsync -0- for " + loop.InEventLoop);

                if (loop.InEventLoop)
                {
                    return(await this.DoReleaseChannel(channel));
                }
                else
                {
                    var promise = new TaskCompletionSource <bool>();
                    loop.Execute(this.DoReleaseChannel, channel, promise);
                    return(await promise.Task);
                }
            }
            catch (Exception)
            {
                CloseChannel(channel);
                throw;
            }
        }
예제 #4
0
        /// <remarks>PORT NOTE: matches behavior of NioEventLoop.processSelectedKey</remarks>
        static void OnIoCompleted(object sender, SocketAsyncEventArgs args)
        {
            var operation = (SocketChannelAsyncOperation)args;
            AbstractSocketChannel channel = operation.Channel;
            var        @unsafe            = (ISocketChannelUnsafe)channel.Unsafe;
            IEventLoop eventLoop          = channel.EventLoop;

            switch (args.LastOperation)
            {
            case SocketAsyncOperation.Accept:
                if (eventLoop.InEventLoop)
                {
                    @unsafe.FinishRead(operation);
                }
                else
                {
                    eventLoop.Execute(ReadCallbackAction, @unsafe, operation);
                }
                break;

            case SocketAsyncOperation.Connect:
                if (eventLoop.InEventLoop)
                {
                    @unsafe.FinishConnect(operation);
                }
                else
                {
                    eventLoop.Execute(ConnectCallbackAction, @unsafe, operation);
                }
                break;

            case SocketAsyncOperation.Receive:
            case SocketAsyncOperation.ReceiveFrom:
                if (eventLoop.InEventLoop)
                {
                    @unsafe.FinishRead(operation);
                }
                else
                {
                    eventLoop.Execute(ReadCallbackAction, @unsafe, operation);
                }
                break;

            case SocketAsyncOperation.Send:
            case SocketAsyncOperation.SendTo:
                if (eventLoop.InEventLoop)
                {
                    @unsafe.FinishWrite(operation);
                }
                else
                {
                    eventLoop.Execute(WriteCallbackAction, @unsafe, operation);
                }
                break;

            default:
                // todo: think of a better way to comm exception
                throw new ArgumentException("The last operation completed on the socket was not expected");
            }
        }
예제 #5
0
        public async Task TestClosedChannelExceptionCarryIOException()
        {
            IOException ioException = new IOException();
            IChannel    channel     = new TestChannel0(ioException);

            var        loopGroup = new DefaultEventLoopGroup(1);
            IEventLoop loop      = loopGroup.GetNext();

            try
            {
                RegisterChannel(loop, channel);
                await channel.ConnectAsync(new IPEndPoint(IPAddress.IPv6Any, 8888));

                try
                {
                    await channel.WriteAndFlushAsync("");
                }
                catch (Exception exc)
                {
                    Assert.Same(ioException, exc);
                }

                AssertClosedChannelException(channel.WriteAndFlushAsync(""), ioException);
                AssertClosedChannelException(channel.WriteAsync(""), ioException);
                AssertClosedChannelException(channel.BindAsync(new IPEndPoint(IPAddress.IPv6Any, 8888)), ioException);
            }
            finally
            {
                channel.CloseAsync().Ignore();
                await loopGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5));
            }
        }
예제 #6
0
 public virtual async Task <bool> ReleaseAsync(IChannel channel)
 {
     if (channel is null)
     {
         ThrowHelper.ThrowArgumentNullException(ExceptionArgument.channel);
     }
     try
     {
         IEventLoop loop = channel.EventLoop;
         if (loop.InEventLoop)
         {
             return(await DoReleaseChannel(channel));
         }
         else
         {
             var promise = new TaskCompletionSource <bool>();
             loop.Execute(DoReleaseChannel, channel, promise);
             return(await promise.Task);
         }
     }
     catch (Exception)
     {
         CloseChannel(channel);
         throw;
     }
 }
예제 #7
0
 public Application()
 {
     loop          = new DispatcherEventLoop();
     icon          = LoadIcon();
     windowFactory = WindowFactory.Create(hIcon: icon.Handle);
     windows       = new HashSet <WindowCore>();
 }
예제 #8
0
        /// <summary>
        /// 将IChannel绑定到IEventLoop
        /// </summary>
        /// <param name="channel"></param>
        public void Register(ChannelBase channel)
        {
            IEventLoop loop = mEventLoops[_index % mMaxLoop];

            Interlocked.Increment(ref _index);
            channel.RegisterLoop(loop);
        }
예제 #9
0
        /// <summary>
        /// Enqueues another function with respecting the async nature.
        /// Exceptions will be emitted respectively.
        /// </summary>
        /// <param name="loop">The loop to extend.</param>
        /// <param name="action">The action to enqueue.</param>
        /// <param name="priority">The priority of the item.</param>
        /// <returns>A task that is completed when the action has been invoked.</returns>
        public static Task <T> EnqueueAsync <T>(this IEventLoop loop, Func <CancellationToken, T> action, TaskPriority priority = TaskPriority.Normal)
        {
            if (loop != null)
            {
                var tcs = new TaskCompletionSource <T>();

                loop.Enqueue(c =>
                {
                    try
                    {
                        tcs.SetResult(action.Invoke(c));
                    }
                    catch (Exception ex)
                    {
                        tcs.SetException(ex);
                    }
                }, priority);

                return(tcs.Task);
            }
            else
            {
                try
                {
                    return(Task.FromResult(action.Invoke(default)));
예제 #10
0
        public Task ShutdownOutputAsync()
        {
            var tcs = new TaskCompletionSource();
            // todo: use closeExecutor if available
            //Executor closeExecutor = ((TcpSocketChannelUnsafe) unsafe()).closeExecutor();
            //if (closeExecutor != null) {
            //    closeExecutor.execute(new OneTimeTask() {

            //        public void run() {
            //            shutdownOutput0(promise);
            //        }
            //    });
            //} else {
            IEventLoop loop = this.EventLoop;

            if (loop.InEventLoop)
            {
                this.ShutdownOutput0(tcs);
            }
            else
            {
                loop.Execute(promise => this.ShutdownOutput0((TaskCompletionSource)promise), tcs);
            }
            //}
            return(tcs.Task);
        }
예제 #11
0
        public ProudServer(Configuration configuration)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            if (configuration.Version == null)
            {
                throw new ArgumentNullException(nameof(configuration.Version));
            }

            if (configuration.HostIdFactory == null)
            {
                throw new ArgumentNullException(nameof(configuration.HostIdFactory));
            }

            if (configuration.MessageFactories == null)
            {
                throw new ArgumentNullException(nameof(configuration.MessageFactories));
            }

            _socketListenerThreads = configuration.SocketListenerThreads ?? new MultithreadEventLoopGroup(1);
            _socketWorkerThreads   = configuration.SocketWorkerThreads ?? new MultithreadEventLoopGroup();
            _workerThread          = configuration.WorkerThread ?? new SingleThreadEventLoop();

            Configuration      = configuration;
            Rsa                = new RSACryptoServiceProvider(1024);
            P2PGroupManager    = new P2PGroupManager(this);
            SessionsByUdpId    = new ConcurrentDictionary <uint, ProudSession>();
            UdpSocketManager   = new UdpSocketManager(this);
            ServerInstanceGuid = Guid.NewGuid();
        }
예제 #12
0
        protected override void ChannelRead0(IChannelHandlerContext ctx, IMessage msg)
        {
            if (!Settings.Ins.AppRunning)
            {
                return;
            }

            //直接在当前io线程处理
            IEventLoop group = ctx.Channel.EventLoop;

            group.Execute(async() =>
            {
                var handler = TcpHandlerFactory.GetHandler(msg.GetMsgId());
                LOGGER.Debug($"-------------server msg {msg.GetMsgId()} {msg.GetType()}");

                if (handler == null)
                {
                    LOGGER.Error("找不到对应的handler " + msg.GetMsgId());
                    return;
                }

                //握手
                var channel = ctx.Channel.GetAttribute(ChannelManager.Att_Channel).Get();
                if (channel != null)
                {
                    var actor = await ActorManager.Get <ComponentActor>(channel.Id);
                    if (actor != null)
                    {
                        if (actor is IChannel ise)
                        {
                            _ = actor.SendAsync(ise.Hand);
                        }
                        if (actor.TransformAgent <IChannel>(out var seAgent))
                        {
                            _ = actor.SendAsync(seAgent.Hand);
                        }
                    }
                }

                handler.Time = DateTime.Now;
                handler.Ctx  = ctx;
                handler.Msg  = msg;
                if (handler is TcpActorHandler actorHandler)
                {
                    actorHandler.Actor = await actorHandler.CacheActor();
                    if (actorHandler.Actor != null)
                    {
                        await actorHandler.Actor.SendAsync(actorHandler.ActionAsync);
                    }
                    else
                    {
                        LOGGER.Error($"handler actor 为空 {msg.GetMsgId()} {handler.GetType()}");
                    }
                }
                else
                {
                    await handler.ActionAsync();
                }
            });
        }
예제 #13
0
        /// <summary>Creates a new instance of <see cref="MultithreadEventLoopGroup"/>.</summary>
        public MultithreadEventLoopGroup(Func <IEventLoopGroup, IEventLoop> eventLoopFactory, int eventLoopCount)
        {
            _eventLoops = new IEventLoop[eventLoopCount];
            var terminationTasks = new Task[eventLoopCount];

            for (int i = 0; i < eventLoopCount; i++)
            {
                IEventLoop eventLoop = null;
                bool       success   = false;
                try
                {
                    eventLoop = eventLoopFactory(this);
                    success   = true;
                }
                catch (Exception ex)
                {
                    ThrowHelper.ThrowInvalidOperationException(ex);
                }
                finally
                {
                    if (!success)
                    {
                        Task.WhenAll(_eventLoops
                                     .Take(i)
                                     .Select(loop => loop.ShutdownGracefullyAsync()))
                        .Wait();
                    }
                }

                _eventLoops[i]      = eventLoop;
                terminationTasks[i] = eventLoop.TerminationCompletion;
            }
            TerminationCompletion = Task.WhenAll(terminationTasks);
        }
예제 #14
0
        public async Task TestMap()
        {
            IEventLoopGroup group = new MultithreadEventLoopGroup();
            LocalAddress    addr  = new LocalAddress(ChannelPoolTestUtils.GetLocalAddrId());

            // Start server
            IChannel sc = await StartServerBootstrapAsync(group, addr);

            Bootstrap cb = new Bootstrap();

            cb.RemoteAddress(addr);
            cb.Group(group).Channel <LocalChannel>();
            var poolMap = new TestChannelPoolMap0(cb);

            IEventLoop loop = group.GetNext();

            Assert.True(poolMap.IsEmpty);
            Assert.Equal(0, poolMap.Count);

            SimpleChannelPool pool = poolMap.Get(loop);

            Assert.Equal(1, poolMap.Count);

            Assert.Same(pool, poolMap.Get(loop));
            Assert.True(poolMap.Remove(loop));
            Assert.False(poolMap.Remove(loop));

            Assert.Equal(0, poolMap.Count);

            await pool.AcquireAsync();

            poolMap.Close();

            await sc.CloseAsync();
        }
예제 #15
0
 //RetransmitPublish->Timer->WriteAndFlush
 public void RetransmitPublish(IEventLoop eventLoop, Func <Packet, Task> sendPacket)
 {
     publishRetransmissionAction.Action = (publishPacket) =>
     {
         return(sendPacket(duplicateRetainPublishPacket(publishPacket)));
     };
     publishRetransmissionAction.Start(eventLoop);
 }
예제 #16
0
 public void Retransmit(IEventLoop eventLoop, Func <Packet, Task> sendPacket)
 {
     if (Sent)//If the packet is sent, we can start the retransmit timer
     {
         retransmissionAction.Action = sendPacket;
     }
     retransmissionAction.Start(eventLoop);
 }
예제 #17
0
 private void startTimer(IEventLoop eventLoop)
 {
     timer = eventLoop.Schedule(async() =>
     {
         timeout += 5;
         await Action(OriginalPacket);
         startTimer(eventLoop);
     }, TimeSpan.FromSeconds(timeout));
 }
예제 #18
0
            private Task <IChannel> ConnectToDestination(IEventLoop loop, IChannelHandler handler)
            {
                var b = new Bootstrap()
                        .Channel <TcpSocketChannel>()
                        .Group(loop)
                        .Handler(handler);

                return(b.ConnectAsync(IntermediaryDestination));
            }
예제 #19
0
        public Task StartAsync(CancellationToken cancellationToken)
        {
            if (_workerThread != null)
            {
                throw new InvalidOperationException("Scheduler is already running");
            }

            _workerThread = _options.WorkerThreadFactory?.Invoke() ?? new SingleThreadEventLoop();
            return(Task.CompletedTask);
        }
예제 #20
0
 public override void RegisterLoop(IEventLoop loop)
 {
     _loop = loop;
     if (Interlocked.CompareExchange(ref _active, 1, 0) == 0)
     {
         OnBeforeActive();
         _pipe.FireChannelActive();
         OnAfterActive();
     }
 }
예제 #21
0
        public async Task StopAsync(CancellationToken cancellationToken)
        {
            if (_workerThread == null)
            {
                return;
            }

            await _workerThread.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(300), TimeSpan.FromSeconds(2));

            _workerThread = null;
        }
예제 #22
0
 public RabbitQueueListener(IChannelProxy proxy, IDispatcher dispatch, RabbitEndpoint endpoint)
 {
     Serializer = Assimilate.GetInstanceOf(endpoint.SerializerType) as IMessageSerializer;
     Loop       = new EventLoop();
     Loop.Start(8);
     Running        = true;
     Proxy          = proxy;
     Dispatch       = dispatch;
     RabbitEndpoint = endpoint;
     proxy.InitConsumer(this);
 }
예제 #23
0
 /// <summary>
 /// Enqueues another action without considering the cancellation token.
 /// </summary>
 /// <param name="loop">The loop to extend.</param>
 /// <param name="action">The action to enqueue.</param>
 /// <param name="priority">The priority of the item.</param>
 public static void Enqueue(this IEventLoop loop, Action action, TaskPriority priority = TaskPriority.Normal)
 {
     if (loop != null)
     {
         loop.Enqueue(c => action.Invoke(), priority);
     }
     else
     {
         action.Invoke();
     }
 }
예제 #24
0
 private void Deregister(IChannelHandlerContext ctx, IEventLoop loop)
 {
     // As soon as the channel becomes active re-register it to another
     // EventLoop. After this is done we should still receive the data that
     // was written to the channel.
     ctx.DeregisterAsync().ContinueWith(t =>
     {
         IChannel channel = ctx.Channel;
         Assert.NotSame(loop, channel.EventLoop);
         _group.GetNext().RegisterAsync(channel);
     }, TaskContinuationOptions.ExecuteSynchronously);
 }
예제 #25
0
            public override void ChannelActive(IChannelHandlerContext ctx)
            {
                IEventLoop loop = _group.GetNext();

                if (_sameEventLoop)
                {
                    Deregister(ctx, loop);
                }
                else
                {
                    loop.Execute(() => Deregister(ctx, loop));
                }
            }
예제 #26
0
 public void Start(IEventLoop eventLoop)
 {
     if (eventLoop == null)
     {
         throw new ArgumentNullException("eventLoop");
     }
     if (Action == null)
     {
         throw new ArgumentNullException("action");
     }
     timeout = 10;
     startTimer(eventLoop);
 }
예제 #27
0
        private void TestScheduleTask(IEventLoop loopA)
        {
            long       startTime = Stopwatch.GetTimestamp();
            AtomicLong endTime   = new AtomicLong();
            var        f         = loopA.Schedule(() =>
            {
                endTime.Value = Stopwatch.GetTimestamp();
            }, TimeSpan.FromMilliseconds(500));

            f.Completion.GetAwaiter().GetResult();

            Assert.True(endTime.Value - startTime >= PreciseTime.ToDelayNanos(TimeSpan.FromMilliseconds(500)));
        }
예제 #28
0
            public Task RegisterAsync(IEventLoop eventLoop)
            {
                Contract.Requires(eventLoop != null);
                if (this._channel.Registered)
                {
                    return(TaskEx.FromException(new InvalidOperationException("registered to an event loop already")));
                }
                if (!this._channel.IsCompatible(eventLoop))
                {
                    return
                        (TaskEx.FromException(
                             new InvalidOperationException("incompatible event loop type: " + eventLoop.GetType().Name)));
                }

                // It's necessary to reuse the wrapped eventloop object. Otherwise the user will end up with multiple
                // objects that do not share a common state.
                if (this._channel._eventLoop == null)
                {
                    this._channel._eventLoop = new PausableChannelEventLoop(this._channel, eventLoop);
                }
                else
                {
                    this._channel._eventLoop.Unwrapped = eventLoop;
                }

                var promise = new TaskCompletionSource();

                if (eventLoop.InEventLoop)
                {
                    this.Register0(promise);
                }
                else
                {
                    try
                    {
                        eventLoop.Execute(() => this.Register0(promise));
                    }
                    catch (Exception ex)
                    {
                        Logger.Warning(
                            "Force-closing a channel whose registration task was not accepted by an event loop: {0}; Cause: {1}",
                            _channel,
                            ex);
                        CloseForcibly();
                        _channel._closeTask.TryComplete();
                        PromiseUtil.SafeSetFailure(promise, ex, Logger);
                    }
                }

                return(promise.Task);
            }
예제 #29
0
 /// <summary>
 /// Initialize a new instance <see cref="ApplicationHandler"/>
 /// </summary>
 public ApplicationHandler(IEventLoop eventLoop,
                           IPseudographicsProvider pseudographicsProvider,
                           ISystemColors systemColors,
                           IEnvironment environment)
 {
     this.eventLoop = eventLoop ?? throw new ArgumentNullException(nameof(eventLoop));
     this.pseudographicsProvider = pseudographicsProvider
                                   ?? throw new ArgumentNullException(nameof(pseudographicsProvider));
     this.systemColors           = systemColors ?? throw new ArgumentNullException(nameof(systemColors));
     this.environment            = environment ?? throw new ArgumentNullException(nameof(environment));
     this.eventLoop.OnLoopEmpty += OnLoopEmptyHandler;
     windows    = new WindowCollection();
     screenRect = new Rect(0, 0, this.environment.WindowWidth, this.environment.WindowHeight);
 }
예제 #30
0
        private void TestScheduleLaggyTaskAtFixedRate(IEventLoop loopA)
        {
            var timestamps         = new BlockingCollection <long>();
            int expectedTimeStamps = 5;
            var allTimeStampsLatch = new CountdownEvent(expectedTimeStamps);
            var f = loopA.ScheduleAtFixedRate(() =>
            {
                var empty = timestamps.Count == 0;
                timestamps.Add(Stopwatch.GetTimestamp());
                if (empty)
                {
                    try
                    {
                        Thread.Sleep(401);
                    }
                    catch { }
                }
                allTimeStampsLatch.Signal();
            }, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(100));

            Assert.True(allTimeStampsLatch.Wait(TimeSpan.FromMinutes(1)));
            Assert.True(f.Cancel());
            Thread.Sleep(300);
            Assert.Equal(expectedTimeStamps, timestamps.Count);

            // Check if the task was run with lag.
            int  i = 0;
            long?previousTimestamp = null;

            foreach (long t in timestamps)
            {
                if (previousTimestamp == null)
                {
                    previousTimestamp = t;
                    continue;
                }

                long diff = t - previousTimestamp.Value;
                if (i == 0)
                {
                    Assert.True(diff >= PreciseTime.ToDelayNanos(TimeSpan.FromMilliseconds(400)));
                }
                else
                {
                    Assert.True(diff <= PreciseTime.ToDelayNanos(TimeSpan.FromMilliseconds(10)));
                }
                previousTimestamp = t;
                i++;
            }
        }
예제 #31
0
 public ThreadQueue(IEventLoop the_loop)
 {
     loop = the_loop;
     evt = Native.Factory.CreateWaitEvent();
     msg_src = loop.AddWatch(evt.Handle, WatchEventKind.In, OnPingReceived);
 }
예제 #32
0
 protected override bool IsCompatible(IEventLoop eventLoop)
 {
     return eventLoop is SingleThreadEventLoop;
 }
예제 #33
0
            public Task RegisterAsync(IEventLoop eventLoop)
            {
                Contract.Requires(eventLoop != null);

                if (this.channel.Registered)
                {
                    return TaskEx.FromException(new InvalidOperationException("registered to an event loop already"));
                }

                if (!this.channel.IsCompatible(eventLoop))
                {
                    return TaskEx.FromException(new InvalidOperationException("incompatible event loop type: " + eventLoop.GetType().Name));
                }

                this.channel.eventLoop = eventLoop;

                var promise = new TaskCompletionSource();

                if (eventLoop.InEventLoop)
                {
                    this.Register0(promise);
                }
                else
                {
                    try
                    {
                        eventLoop.Execute((u, p) => ((AbstractUnsafe)u).Register0((TaskCompletionSource)p), this, promise);
                    }
                    catch (Exception ex)
                    {
                        Logger.Warn("Force-closing a channel whose registration task was not accepted by an event loop: {}", this.channel, ex);
                        this.CloseForcibly();
                        this.channel.closeFuture.Complete();
                        Util.SafeSetFailure(promise, ex, Logger);
                    }
                }

                return promise.Task;
            }
예제 #34
0
        private void Dispose(bool disposing)
        {
            //if(! disposing)
            //    Monitor.Enter(olock);

            try
            {
                if(m_disposed)
                    return;

                if(disposing)
                    GC.SuppressFinalize(this);

                loop.RemoveSource(msg_src);

                while(msgs.Count > 0)
                    Dispatch();

                evt.Dispose();
                evt = null;
                loop = null;

                m_disposed = true;
            }
            catch(Exception ex)
            {
                throw ex;
            }
            finally
            {
                Application.WriteDebug("ThreadQueue.Dispose({0}) [Thread {1}]",
                                       disposing, Thread.CurrentThread.GetHashCode());
                //if(! disposing)
                //    Monitor.Exit(olock);
            }
        }
예제 #35
0
 protected override bool IsCompatible(IEventLoop eventLoop)
 {
     return true;
 }
예제 #36
0
 public PausableChannelEventLoop(IChannel channel, IEventLoop unwrapped)
 {
     this.channel = channel;
     this.Unwrapped = unwrapped;
 }
예제 #37
0
 /// <summary>
 /// Return {@code true} if the given {@link EventLoop} is compatible with this instance.
 /// </summary>
 protected abstract bool IsCompatible(IEventLoop eventLoop);
예제 #38
0
            public Task RegisterAsync(IEventLoop eventLoop)
            {
                Contract.Requires(eventLoop != null);
                if (this._channel.Registered)
                {
                    return TaskEx.FromException(new InvalidOperationException("registered to an event loop already"));
                }
                if (!this._channel.IsCompatible(eventLoop))
                {
                    return
                        TaskEx.FromException(
                            new InvalidOperationException("incompatible event loop type: " + eventLoop.GetType().Name));
                }

                // It's necessary to reuse the wrapped eventloop object. Otherwise the user will end up with multiple
                // objects that do not share a common state.
                if (this._channel._eventLoop == null)
                {
                    this._channel._eventLoop = new PausableChannelEventLoop(this._channel, eventLoop);
                }
                else
                {
                    this._channel._eventLoop.Unwrapped = eventLoop;
                }

                var promise = new TaskCompletionSource();

                if (eventLoop.InEventLoop)
                {
                    this.Register0(promise);
                }
                else
                {
                    try
                    {
                        eventLoop.Execute(() => this.Register0(promise));
                    }
                    catch (Exception ex)
                    {
                        Logger.Warning(
                            "Force-closing a channel whose registration task was not accepted by an event loop: {0}; Cause: {1}",
                            _channel,
                            ex);
                        CloseForcibly();
                        _channel._closeTask.TryComplete();
                        PromiseUtil.SafeSetFailure(promise, ex, Logger);
                    }
                }

                return promise.Task;
            }
예제 #39
0
 public PausableChannelEventLoop(IChannel channel, IEventLoop unwrapped)
 {
     _channel = channel;
     Unwrapped = unwrapped;
 }
예제 #40
0
 public MutationHost(IEventLoop loop)
 {
     _observers = new List<MutationObserver>();
     _queued = false;
     _loop = loop;
 }
예제 #41
0
 /// <summary>
 /// Creates a new document node.
 /// </summary>
 /// <param name="context">The context of the document.</param>
 /// <param name="source">The underlying source.</param>
 internal Document(IBrowsingContext context, TextSource source)
     : base(null, "#document", NodeType.Document)
 {
     _async = true;
     _designMode = false;
     _firedUnload = false;
     _salvageable = true;
     _shown = false;
     _preferredStyleSheetSet = String.Empty;
     _context = context;
     _source = source;
     _referrer = String.Empty;
     _contentType = MimeTypes.ApplicationXml;
     _ready = DocumentReadyState.Loading;
     _sandbox = Sandboxes.None;
     _quirksMode = QuirksMode.Off;
     _tasks = new CancellableTasks();
     _loadingScripts = new Queue<HtmlScriptElement>();
     _location = new Location(AboutBlank);
     _ranges = new List<WeakReference<Range>>();
     _location.Changed += LocationChanged;
     _styleSheets = this.CreateStyleSheets();
     _view = this.CreateWindow();
     _loader = this.CreateLoader();
     _loop = this.CreateLoop();
     _mutations = new MutationHost(_loop);
 }
예제 #42
0
 public RabbitQueueListener( IChannelProxy proxy, IDispatcher dispatch, RabbitEndpoint endpoint )
 {
     Serializer = Assimilate.GetInstanceOf(endpoint.SerializerType) as IMessageSerializer;
     Loop = new EventLoop();
     Loop.Start( 8 );
     Running = true;
     Proxy = proxy;
     Dispatch = dispatch;
     RabbitEndpoint = endpoint;
     proxy.InitConsumer( this );
 }
예제 #43
0
 protected override bool IsCompatible(IEventLoop eventLoop) => true;