public void finish(EventHandler handler) { lock (this) { Debug.Assert(!_destroyed); handler._registered = SocketOperation.None; // // If there are no pending asynchronous operations, we can call finish on the handler now. // if (handler._pending == 0) { executeNonBlocking(() => { ThreadPoolCurrent current = new ThreadPoolCurrent(this, handler, SocketOperation.None); handler.finished(ref current); }); } else { handler._finish = true; } } }
public void finish(EventHandler handler) { _m.Lock(); try { Debug.Assert(!_destroyed); if (handler._pending == 0) { handler._registered = SocketOperation.None; executeNonBlocking(delegate() { ThreadPoolCurrent current = new ThreadPoolCurrent(this, handler, SocketOperation.None); handler.finished(ref current); }); } else { handler._finish = true; } } finally { _m.Unlock(); } }
public override void Finished(ref ThreadPoolCurrent current) { lock (this) { Debug.Assert(_state == State.Closed); SetState(State.Finished); } }
public void finishIOScope(ref ThreadPoolCurrent current) { if (_finishWithIO) { // This must be called with the handler locked. current.finishMessage(true); } }
public void finishIOScope(ref ThreadPoolCurrent current) { if(_finishWithIO) { // This must be called with the handler locked. current.finishMessage(true); } }
public bool startMessage(ref ThreadPoolCurrent current) { Debug.Assert((current._handler._pending & current.operation) != 0); if ((current._handler._started & current.operation) != 0) { Debug.Assert((current._handler._ready & current.operation) == 0); current._handler._ready |= current.operation; current._handler._started &= ~current.operation; if (!current._handler.finishAsync(current.operation)) // Returns false if the handler is finished. { current._handler._pending &= ~current.operation; if (current._handler._pending == 0 && current._handler._finish) { finish(current._handler); } return(false); } } else if ((current._handler._ready & current.operation) == 0 && (current._handler._registered & current.operation) != 0) { Debug.Assert((current._handler._started & current.operation) == 0); bool completed = false; if (!current._handler.startAsync(current.operation, getCallback(current.operation), ref completed)) { current._handler._pending &= ~current.operation; if (current._handler._pending == 0 && current._handler._finish) { finish(current._handler); } return(false); } else { current.completedSynchronously = completed; current._handler._started |= current.operation; return(false); } } if ((current._handler._registered & current.operation) != 0) { Debug.Assert((current._handler._ready & current.operation) != 0); current._handler._ready &= ~current.operation; return(true); } else { current._handler._pending &= ~current.operation; if (current._handler._pending == 0 && current._handler._finish) { finish(current._handler); } return(false); } }
public void finishIOScope(ref ThreadPoolCurrent current) { if(_finishWithIO) { lock(_mutex) { current.finishMessage(true); } } }
public void finishIOScope(ref ThreadPoolCurrent current) { if (_finishWithIO) { lock (_mutex) { current.finishMessage(true); } } }
public void completed(ref ThreadPoolCurrent current) { // // Call finishMessage once IO is completed only if serialization is not enabled. // Otherwise, finishMessage will be called when the event handler is done with // the message (it will be called from destroy below). // Debug.Assert(_finishWithIO); if (current.ioCompleted()) { _finishWithIO = false; _finish = true; } }
public void completed(ref ThreadPoolCurrent current) { // // Call finishMessage once IO is completed only if serialization is not enabled. // Otherwise, finishMessage will be called when the event handler is done with // the message (it will be called from destroy below). // Debug.Assert(_finishWithIO); if(current.ioCompleted()) { _finishWithIO = false; _finish = true; } }
public void destroy(ref ThreadPoolCurrent current) { if(_finish) { // // A ThreadPoolMessage instance must be created outside the synchronization // of the event handler. We need to lock the event handler here to call // finishMessage. // lock(_mutex) { current.finishMessage(false); Debug.Assert(!current.completedSynchronously); } } }
public void destroy(ref ThreadPoolCurrent current) { if (_finish) { // // A ThreadPoolMessage instance must be created outside the synchronization // of the event handler. We need to lock the event handler here to call // finishMessage. // lock (_mutex) { current.finishMessage(false); Debug.Assert(!current.completedSynchronously); } } }
public void messageCallback(ThreadPoolCurrent current) { try { do { current.completedSynchronously = false; current._handler.message(ref current); }while(current.completedSynchronously); } catch (System.Exception ex) { string s = "exception in `" + _prefix + "':\n" + ex + "\nevent handler: " + current._handler.ToString(); _instance.initializationData().logger.error(s); } }
public void finishMessage(ref ThreadPoolCurrent current, bool fromIOThread) { if ((current._handler._registered & current.operation) != 0) { if (fromIOThread) { Debug.Assert((current._handler._ready & current.operation) == 0); bool completed = false; if (!current._handler.startAsync(current.operation, getCallback(current.operation), ref completed)) { current._handler._pending &= ~current.operation; } else { Debug.Assert((current._handler._pending & current.operation) != 0); current.completedSynchronously = completed; current._handler._started |= current.operation; } } else { ThreadPoolCurrent c = current; executeNonBlocking(() => { messageCallback(c); }); } } else { current._handler._pending &= ~current.operation; } if (current._handler._pending == 0 && current._handler._finish) { // There are no more pending async operations, it's time to call finish. finish(current._handler); } }
public void finishMessage(ref ThreadPoolCurrent current, bool fromIOThread) { if((current._handler._registered & current.operation) != 0) { if(fromIOThread) { Debug.Assert((current._handler._ready & current.operation) == 0); bool completed = false; if(!current._handler.startAsync(current.operation, getCallback(current.operation), ref completed)) { current._handler._pending &= ~current.operation; } else { Debug.Assert((current._handler._pending & current.operation) != 0); current.completedSynchronously = completed; current._handler._started |= current.operation; } } else { ThreadPoolCurrent c = current; executeNonBlocking(() => { messageCallback(c); }); } } else { current._handler._pending &= ~current.operation; } if(current._handler._pending == 0 && current._handler._finish) { // There are no more pending async operations, it's time to call finish. finish(current._handler); } }
public void finish(EventHandler handler) { lock(this) { Debug.Assert(!_destroyed); // // If there are no pending asynchronous operations, we can call finish on the handler now. // if(handler._pending == 0) { handler._registered = SocketOperation.None; executeNonBlocking(() => { ThreadPoolCurrent current = new ThreadPoolCurrent(this, handler, SocketOperation.None); handler.finished(ref current); }); } else { handler._finish = true; } } }
public bool startIOScope(ref ThreadPoolCurrent current) { // This must be called with the handler locked. _finishWithIO = current.startMessage(); return _finishWithIO; }
// // Called when there's a message ready to be processed. // abstract public void message(ref ThreadPoolCurrent op);
// // Called when the event handler is unregistered. // abstract public void finished(ref ThreadPoolCurrent op);
public bool startIOScope(ref ThreadPoolCurrent current) { // This must be called with the handler locked. _finishWithIO = current.startMessage(); return(_finishWithIO); }
public void finish(EventHandler handler) { _m.Lock(); try { Debug.Assert(!_destroyed); if(handler._pending == 0) { handler._registered = SocketOperation.None; executeNonBlocking(delegate() { ThreadPoolCurrent current = new ThreadPoolCurrent(this, handler, SocketOperation.None); handler.finished(ref current); }); } else { handler._finish = true; } } finally { _m.Unlock(); } }
public void messageCallback(ThreadPoolCurrent current) { try { do { current.completedSynchronously = false; current._handler.message(ref current); } while(current.completedSynchronously); } catch(System.Exception ex) { string s = "exception in `" + _prefix + "':\n" + ex + "\nevent handler: " + current._handler.ToString(); _instance.initializationData().logger.error(s); } }
public bool startMessage(ref ThreadPoolCurrent current) { Debug.Assert((current._handler._pending & current.operation) != 0); if((current._handler._started & current.operation) != 0) { Debug.Assert((current._handler._ready & current.operation) == 0); current._handler._ready |= current.operation; current._handler._started &= ~current.operation; if(!current._handler.finishAsync(current.operation)) // Returns false if the handler is finished. { current._handler._pending &= ~current.operation; if(current._handler._pending == 0 && current._handler._finish) { finish(current._handler); } return false; } } else if((current._handler._ready & current.operation) == 0 && (current._handler._registered & current.operation) != 0) { Debug.Assert((current._handler._started & current.operation) == 0); bool completed = false; if(!current._handler.startAsync(current.operation, getCallback(current.operation), ref completed)) { current._handler._pending &= ~current.operation; if(current._handler._pending == 0 && current._handler._finish) { finish(current._handler); } return false; } else { current.completedSynchronously = completed; current._handler._started |= current.operation; return false; } } if((current._handler._registered & current.operation) != 0) { Debug.Assert((current._handler._ready & current.operation) != 0); current._handler._ready &= ~current.operation; return true; } else { current._handler._pending &= ~current.operation; if(current._handler._pending == 0 && current._handler._finish) { finish(current._handler); } return false; } }
public override void Message(ref ThreadPoolCurrent current) { Connection?connection = null; var msg = new ThreadPoolMessage(this); lock (this) { if (!msg.StartIOScope(ref current)) { return; } try { if (_state >= State.Closed) { return; } // Reap closed connections foreach (Connection c in _monitor.SwapReapedConnections()) { _connections.Remove(c); } // Now accept a new connection. ITransceiver transceiver; try { if (_acceptorException != null) { throw _acceptorException; } transceiver = _acceptor !.Accept(); if (_communicator.TraceLevels.Network >= 2) { _communicator.Logger.Trace(_communicator.TraceLevels.NetworkCat, $"trying to accept {_endpoint.Name} connection\n{transceiver}"); } } catch (System.Exception ex) { _communicator.Logger.Error($"can't accept more connections:\n{ex}\n{_acceptor}"); _acceptorException = null; // Ignore socket exceptions. return; } Debug.Assert(transceiver != null); try { connection = new Connection(_communicator, _monitor, transceiver, null, _endpoint, _adapter); } catch (System.Exception ex) { try { transceiver.Close(); } catch (System.Exception) { // Ignore } if (_warn) { _communicator.Logger.Warning($"connection exception:\n{ex}\n{_acceptor}"); } return; } _connections.Add(connection); } finally { msg.FinishIOScope(ref current); } } Debug.Assert(connection != null); connection.Start(null); }