From fb4ce33375bd4693e418089e2f379554ee52df67 Mon Sep 17 00:00:00 2001 From: Chow Loong Jin Date: Mon, 7 Nov 2011 08:15:27 +0800 Subject: [PATCH] Add TrapSignals and UntrapSignals to Connection.cs This allows for locking signals from the bus while connecting to signals on a BusObject, and releasing them after. This is needed for Mono.Zeroconf's implementation of Avahi's DBus protocol. --- src/Connection.cs | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/Connection.cs b/src/Connection.cs index e593db9..1e577e3 100644 --- a/src/Connection.cs +++ b/src/Connection.cs @@ -176,6 +176,25 @@ internal virtual uint Send (Message msg) //temporary hack internal void DispatchSignals () { + lock (delayed_signals) + lock (delayed_signals_recycle) { + if (trap_signals_flush) { + delayed_signals.Clear (); + delayed_signals_recycle.Clear (); + trap_signals_flush = false; + } else { + while (delayed_signals.Count != 0) { + Message msg = delayed_signals.Dequeue (); + HandleSignal (msg); + } + + while (delayed_signals_recycle.Count != 0) { + delayed_signals.Enqueue (delayed_signals_recycle.Dequeue ()); + } + } + } + + lock (Inbound) { while (Inbound.Count != 0) { Message msg = Inbound.Dequeue (); @@ -268,6 +287,23 @@ internal virtual void HandleMessage (Message msg) Dictionary pendingCalls = new Dictionary (); + private Queue delayed_signals = new Queue (); + private Queue delayed_signals_recycle = new Queue (); + private int trap_signals_ref; + private bool trap_signals_flush; + + public void TrapSignals () + { + Interlocked.Increment (ref trap_signals_ref); + } + + public void UntrapSignals () + { + if (Interlocked.Decrement (ref trap_signals_ref) == 0) { + trap_signals_flush = true; + } + } + //this might need reworking with MulticastDelegate internal void HandleSignal (Message msg) { @@ -304,6 +340,12 @@ internal void HandleSignal (Message msg) //TODO: how should we handle this condition? sending an Error may not be appropriate in this case if (Protocol.Verbose) Console.Error.WriteLine ("Warning: No signal handler for " + signal.Member); + + if (trap_signals_ref > 0) { + lock (delayed_signals_recycle) { + delayed_signals_recycle.Enqueue (msg); + } + } } }