Skip to content

Commit

Permalink
Synchronized dispose and subscription initialization within the Messa…
Browse files Browse the repository at this point in the history
…geBus to avoid memory leaks

SignalR#1993
  • Loading branch information
NTaylorMullen committed May 10, 2013
1 parent 8a84af8 commit 5d70038
Showing 1 changed file with 20 additions and 2 deletions.
22 changes: 20 additions & 2 deletions src/Microsoft.AspNet.SignalR.Core/Messaging/MessageBus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ public virtual IDisposable Subscribe(ISubscriber subscriber, string cursor, Func
subscriber.EventKeyRemoved += _removeEvent;
subscriber.WriteCursor = subscription.WriteCursor;

var disposable = new DisposableAction(_disposeSubscription, subscriber);
var subscriptionState = new SubscriptionState(subscriber);
var disposable = new DisposableAction(_disposeSubscription, subscriptionState);

// When the subscription itself is disposed then dispose it
subscription.Disposable = disposable;
Expand All @@ -254,6 +255,8 @@ public virtual IDisposable Subscribe(ISubscriber subscriber, string cursor, Func
topic.AddSubscription(subscription);
}

subscriptionState.Initialized.Set();

// If there's a cursor then schedule work for this subscription
if (!String.IsNullOrEmpty(cursor))
{
Expand Down Expand Up @@ -491,7 +494,8 @@ private void RemoveEvent(ISubscriber subscriber, string eventKey)
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Failure to invoke the callback should be ignored")]
private void DisposeSubscription(object state)
{
var subscriber = (ISubscriber)state;
var subscriptionState = (SubscriptionState)state;
var subscriber = subscriptionState.Subscriber;

// This will stop work from continuting to happen
subscriber.Subscription.Dispose();
Expand All @@ -507,6 +511,8 @@ private void DisposeSubscription(object state)
// so the terminal message isn't required.
}

subscriptionState.Initialized.Wait();

subscriber.EventKeyAdded -= _addEvent;
subscriber.EventKeyRemoved -= _removeEvent;
subscriber.WriteCursor = null;
Expand All @@ -517,5 +523,17 @@ private void DisposeSubscription(object state)
RemoveEvent(subscriber, eventKey);
}
}

private class SubscriptionState
{
public ISubscriber Subscriber { get; private set; }
public ManualResetEventSlim Initialized { get; private set; }

public SubscriptionState(ISubscriber subscriber)
{
Initialized = new ManualResetEventSlim();
Subscriber = subscriber;
}
}
}
}

0 comments on commit 5d70038

Please sign in to comment.