Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono-addins.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Mono.Addins/Mono.Addins/ExtensionContext.cs')
-rw-r--r--Mono.Addins/Mono.Addins/ExtensionContext.cs45
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