diff options
Diffstat (limited to 'Mono.Addins/Mono.Addins/ExtensionContext.cs')
-rw-r--r-- | Mono.Addins/Mono.Addins/ExtensionContext.cs | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/Mono.Addins/Mono.Addins/ExtensionContext.cs b/Mono.Addins/Mono.Addins/ExtensionContext.cs index e46e657..5468179 100644 --- a/Mono.Addins/Mono.Addins/ExtensionContext.cs +++ b/Mono.Addins/Mono.Addins/ExtensionContext.cs @@ -1365,25 +1365,26 @@ namespace Mono.Addins } /// <summary> - /// A queue that can be used to dispatch callbacks sequentially + /// A queue that can be used to dispatch callbacks sequentially. /// </summary> class NotificationQueue { readonly AddinEngine addinEngine; - readonly Queue<(Action Action,object Source)> notificationQueue = new Queue<(Action,object)>(); + readonly Queue<(Action Action, object Source)> notificationQueue = new Queue<(Action, object)>(); bool sending; + int frozenCount; public NotificationQueue(AddinEngine addinEngine) { this.addinEngine = addinEngine; } - internal void Invoke(Action action, object source) + public void Invoke(Action action, object source) { lock (notificationQueue) { - if (sending) + if (sending || frozenCount > 0) { // Already sending, enqueue the action so whoever is sending will take it notificationQueue.Enqueue((action,source)); @@ -1397,23 +1398,55 @@ namespace Mono.Addins } SafeInvoke(action, source); + DispatchPendingCallbacks(); + } + void DispatchPendingCallbacks() + { do { + Action action; + object source; + lock (notificationQueue) { - if (notificationQueue.Count == 0) + if (notificationQueue.Count == 0 || frozenCount > 0) { sending = false; return; } - (action,source) = notificationQueue.Dequeue(); + + (action, source) = notificationQueue.Dequeue(); } SafeInvoke(action, source); } while (true); } + public void Freeze() + { + lock (notificationQueue) + { + frozenCount++; + } + } + + public void Unfreeze() + { + bool dispatch = false; + + lock (notificationQueue) + { + if (--frozenCount == 0 && !sending) + { + dispatch = true; + sending = true; + } + } + if (dispatch) + DispatchPendingCallbacks(); + } + void SafeInvoke(Action action, object source) { try |