/** * Stops all edge listeners for the node. * Useful for connect/disconnect operations */ protected virtual void StopAllEdgeListeners() { bool changed = false; try { SetConState(Node.ConnectionState.Disconnected, out changed); foreach (EdgeListener el in _edgelistener_list) { el.Stop(); } _edgelistener_list.Clear(); Interlocked.Exchange(ref _running, 0); //This makes sure we don't block forever on the last packet _packet_queue.Enqueue(NullAction.Instance); } finally { if (changed) { SendStateChange(Node.ConnectionState.Disconnected); Dictionary <EventHandler, Brunet.Util.FuzzyEvent> hbhands = null; lock (_sync) { hbhands = _heartbeat_handlers; _heartbeat_handlers = null; //Clear out the subscription table DemuxHandler.Clear(); } foreach (KeyValuePair <EventHandler, Brunet.Util.FuzzyEvent> de in hbhands) { //Stop running the event de.Value.TryCancel(); } _check_edges.TryCancel(); } } }
/** * There can only safely be one of these threads running */ protected void AnnounceThread() { Brunet.Util.FuzzyEvent fe = null; try { int millisec_timeout = 5000; //log every 5 seconds. IAction queue_item = null; bool timedout = false; if (ProtocolLog.Monitor.Enabled) { IAction log_act = new LogAction(_packet_queue); Action <DateTime> log_todo = delegate(DateTime dt) { EnqueueAction(log_act); }; fe = Brunet.Util.FuzzyTimer.Instance.DoEvery(log_todo, millisec_timeout, millisec_timeout / 2); } while (1 == _running) { queue_item = _packet_queue.Dequeue(millisec_timeout, out timedout); if (!timedout) { _current_action = queue_item; queue_item.Start(); } } } catch (System.InvalidOperationException x) { //This is thrown when Dequeue is called on an empty queue //which happens when the BlockingQueue is closed, which //happens on Disconnect if (1 == _running) { ProtocolLog.WriteIf(ProtocolLog.Exceptions, String.Format( "Running in AnnounceThread got Exception: {0}", x)); } } catch (Exception x) { ProtocolLog.WriteIf(ProtocolLog.Exceptions, String.Format( "ERROR: Exception in AnnounceThread: {0}", x)); } finally { //Make sure we stop logging: if (fe != null) { fe.TryCancel(); } } ProtocolLog.Write(ProtocolLog.Monitor, String.Format("Node: {0} leaving AnnounceThread", this.Address)); }