Skip to content

Commit 60e5b1f

Browse files
committed
More thead safety improvements
1 parent 9777946 commit 60e5b1f

File tree

2 files changed

+36
-14
lines changed

2 files changed

+36
-14
lines changed

Signal-Windows.Lib/SignalLibHandle.cs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public interface ISignalLibHandle
6767
Task Reacquire();
6868
void Release();
6969
bool AddFrontend(CoreDispatcher d, ISignalFrontend w);
70-
void RemoveFrontend(CoreDispatcher d);
70+
Task RemoveFrontend(CoreDispatcher d);
7171

7272
// Background API
7373
event EventHandler<SignalMessageEventArgs> SignalMessageEvent;
@@ -144,20 +144,25 @@ public bool AddFrontend(CoreDispatcher d, ISignalFrontend w)
144144
}
145145
}
146146

147-
public void RemoveFrontend(CoreDispatcher d)
147+
public async Task RemoveFrontend(CoreDispatcher d)
148148
{
149149
Logger.LogTrace("RemoveFrontend() locking");
150-
if (SynchronizationContext.Current != null)
150+
await SemaphoreSlim.WaitAsync(CancelSource.Token);
151+
try
151152
{
152-
Logger.LogCritical("RemoveFrontend must not be called with a syncchronization context");
153-
throw new InvalidOperationException();
153+
Logger.LogTrace("RemoveFrontend() locked");
154+
Logger.LogInformation("Unregistering frontend of dispatcher {0}", d.GetHashCode());
155+
Frames.Remove(d);
156+
}
157+
catch (Exception e)
158+
{
159+
Logger.LogCritical($"RemoveFrontend failed(): {e.Message} ({e.GetType()})\n{e.StackTrace}");
160+
}
161+
finally
162+
{
163+
SemaphoreSlim.Release();
164+
Logger.LogTrace("RemoveFrontend() released");
154165
}
155-
SemaphoreSlim.Wait(CancelSource.Token);
156-
Logger.LogTrace("RemoveFrontend() locked");
157-
Logger.LogInformation("Unregistering frontend of dispatcher {0}", d.GetHashCode());
158-
Frames.Remove(d);
159-
SemaphoreSlim.Release();
160-
Logger.LogTrace("RemoveFrontend() released");
161166
}
162167

163168
public void PurgeAccountData()
@@ -245,11 +250,13 @@ public async Task Reacquire()
245250
GlobalResetEvent.Reset();
246251
LibsignalDBContext.ClearSessionCache();
247252
Instance = this;
253+
Logger.LogTrace($"Reacquire() updating {Frames.Count} frames");
248254
await Task.Run(async () =>
249255
{
250256
List<Task> tasks = new List<Task>();
251257
foreach (var f in Frames)
252258
{
259+
Logger.LogTrace($"Reacquire() updating frame {f.Value}");
253260
var conversations = GetConversations();
254261
var taskCompletionSource = new TaskCompletionSource<bool>();
255262
await f.Key.RunAsync(CoreDispatcherPriority.Normal, () =>
@@ -273,6 +280,7 @@ await f.Key.RunAsync(CoreDispatcherPriority.Normal, () =>
273280
{
274281
await t;
275282
}
283+
Logger.LogTrace($"Reacquire() recovering downloads");
276284
await RecoverDownloads();
277285
Store = LibsignalDBContext.GetSignalStore();
278286
if (Store != null)
@@ -282,6 +290,7 @@ await f.Key.RunAsync(CoreDispatcherPriority.Normal, () =>
282290
});
283291
if (LikelyHasValidStore)
284292
{
293+
Logger.LogTrace($"Reacquire() initializing network");
285294
InitNetwork();
286295
}
287296
}

Signal-Windows/App.xaml.cs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,21 @@ sealed partial class App : Application
4242
public static string USER_AGENT = "Signal-Windows";
4343
public static uint PREKEY_BATCH_SIZE = 100;
4444
public static ISignalLibHandle Handle = SignalHelper.CreateSignalLibHandle(false);
45-
private Dictionary<int, SignalWindowsFrontend> Views = new Dictionary<int, SignalWindowsFrontend>();
45+
private Dictionary<int, SignalWindowsFrontend> _Views = new Dictionary<int, SignalWindowsFrontend>();
4646
public static int MainViewId;
4747
private IBackgroundTaskRegistration backgroundTaskRegistration;
4848

49+
private Dictionary<int, SignalWindowsFrontend> Views
50+
{
51+
get
52+
{
53+
lock (_Views)
54+
{
55+
return _Views;
56+
}
57+
}
58+
}
59+
4960
static App()
5061
{
5162
// TODO enforce these have begun before initializing and ensure the logger is working
@@ -272,6 +283,7 @@ await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
272283

273284
private void SetupTopBar()
274285
{
286+
Logger.LogTrace("SetupTopBar()");
275287
// mobile clients have a status bar
276288
if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
277289
{
@@ -353,11 +365,12 @@ private void BackgroundTaskRegistration_Completed(BackgroundTaskRegistration sen
353365
Debug.WriteLine("Background task completed");
354366
}
355367

356-
private void CurrView_Consolidated(ApplicationView sender, ApplicationViewConsolidatedEventArgs args)
368+
private async void CurrView_Consolidated(ApplicationView sender, ApplicationViewConsolidatedEventArgs args)
357369
{
370+
Logger.LogTrace($"CurrView_Consolidated() sender.Id = {sender.Id}");
358371
sender.Consolidated -= CurrView_Consolidated;
359372
var signalWindowsFrontend = Views[sender.Id];
360-
Task.Run(() => Handle.RemoveFrontend(signalWindowsFrontend.Dispatcher)).Wait();
373+
await Handle.RemoveFrontend(signalWindowsFrontend.Dispatcher);
361374
Views.Remove(sender.Id);
362375
if (sender.Id != MainViewId)
363376
{

0 commit comments

Comments
 (0)