Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit f8dd285

Browse files
authored
Merge pull request #362 from github/fixes/stackoverflow
Fix stackoverflow and resource disposal
2 parents 71e8a8d + d119d7c commit f8dd285

File tree

16 files changed

+51
-123
lines changed

16 files changed

+51
-123
lines changed

src/GitHub.App/Caches/ImageCache.cs

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -213,33 +213,8 @@ static string GetCacheKey(Uri url)
213213
return url.ToString();
214214
}
215215

216-
bool disposed;
217-
void Dispose(bool disposing)
218-
{
219-
if (disposing)
220-
{
221-
if (disposed) return;
222-
223-
try
224-
{
225-
cacheFactory.Select(x =>
226-
{
227-
x.Dispose();
228-
return x.Shutdown;
229-
}).Wait();
230-
}
231-
catch (Exception e)
232-
{
233-
log.Warn("Exception occured while disposing ImageCache", e);
234-
}
235-
disposed = true;
236-
}
237-
}
238-
239216
public void Dispose()
240-
{
241-
Dispose(true);
242-
}
217+
{}
243218

244219
class UriComparer : IEqualityComparer<Uri>
245220
{

src/GitHub.App/Caches/LoginCache.cs

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -56,28 +56,7 @@ public IObservable<Unit> Flush()
5656
return cache.Secure.Flush();
5757
}
5858

59-
bool disposed;
60-
void Dispose(bool disposing)
61-
{
62-
if (disposing)
63-
{
64-
if (disposed) return;
65-
66-
try
67-
{
68-
cache.Dispose();
69-
}
70-
catch (Exception e)
71-
{
72-
log.Warn("Exception occurred while disposing shared cache", e);
73-
}
74-
disposed = true;
75-
}
76-
}
77-
7859
public void Dispose()
79-
{
80-
Dispose(true);
81-
}
60+
{}
8261
}
8362
}

src/GitHub.App/Factories/HostCacheFactory.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,8 @@ public IBlobCache Create(HostAddress hostAddress)
4040
IOperatingSystem OperatingSystem { get { return operatingSystem.Value; } }
4141
IBlobCacheFactory BlobCacheFactory { get { return blobCacheFactory.Value; } }
4242

43-
bool disposed;
4443
protected virtual void Dispose(bool disposing)
45-
{
46-
if (disposing)
47-
{
48-
if (disposed) return;
49-
disposed = true;
50-
if (blobCacheFactory.IsValueCreated)
51-
blobCacheFactory.Value.Dispose();
52-
}
53-
}
44+
{}
5445

5546
public void Dispose()
5647
{

src/GitHub.App/Factories/RepositoryHostFactory.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using GitHub.Models;
66
using GitHub.Primitives;
77
using GitHub.Services;
8+
using System.Reactive.Disposables;
89

910
namespace GitHub.Factories
1011
{
@@ -17,6 +18,7 @@ public class RepositoryHostFactory : IRepositoryHostFactory
1718
readonly ILoginCache loginCache;
1819
readonly IAvatarProvider avatarProvider;
1920
readonly ITwoFactorChallengeHandler twoFactorChallengeHandler;
21+
readonly CompositeDisposable hosts = new CompositeDisposable();
2022

2123
[ImportingConstructor]
2224
public RepositoryHostFactory(
@@ -38,8 +40,14 @@ public IRepositoryHost Create(HostAddress hostAddress)
3840
var apiClient = apiClientFactory.Create(hostAddress);
3941
var hostCache = hostCacheFactory.Create(hostAddress);
4042
var modelService = new ModelService(apiClient, hostCache, avatarProvider);
43+
var host = new RepositoryHost(apiClient, modelService, loginCache, twoFactorChallengeHandler);
44+
hosts.Add(host);
45+
return host;
46+
}
4147

42-
return new RepositoryHost(apiClient, modelService, loginCache, twoFactorChallengeHandler);
48+
public void Remove(IRepositoryHost host)
49+
{
50+
hosts.Remove(host);
4351
}
4452

4553
bool disposed;
@@ -48,11 +56,8 @@ protected virtual void Dispose(bool disposing)
4856
if (disposing)
4957
{
5058
if (disposed) return;
51-
52-
loginCache.Dispose();
53-
avatarProvider.Dispose();
54-
hostCacheFactory.Dispose();
5559
disposed = true;
60+
hosts.Dispose();
5661
}
5762
}
5863

src/GitHub.App/Factories/SqlitePersistentBlobCacheFactory.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
using System;
55
using System.Collections.Generic;
66
using System.ComponentModel.Composition;
7-
using System.Reactive.Disposables;
7+
using System.Reactive.Linq;
8+
using System.Threading.Tasks;
89

910
namespace GitHub.Factories
1011
{
1112
[Export(typeof(IBlobCacheFactory))]
1213
[PartCreationPolicy(CreationPolicy.Shared)]
1314
public class SqlitePersistentBlobCacheFactory : IBlobCacheFactory
1415
{
15-
readonly CompositeDisposable disposables = new CompositeDisposable();
1616
static readonly Logger log = LogManager.GetCurrentClassLogger();
1717
Dictionary<string, IBlobCache> cache = new Dictionary<string, IBlobCache>();
1818

@@ -26,7 +26,6 @@ public IBlobCache CreateBlobCache(string path)
2626
{
2727
var c = new SQLitePersistentBlobCache(path);
2828
cache.Add(path, c);
29-
disposables.Add(c);
3029
return c;
3130
}
3231
catch(Exception ex)
@@ -43,7 +42,14 @@ protected virtual void Dispose(bool disposing)
4342
{
4443
if (disposed) return;
4544
disposed = true;
46-
disposables.Dispose();
45+
Task.Run(() =>
46+
{
47+
foreach (var c in cache.Values)
48+
{
49+
c.Dispose();
50+
c.Shutdown.Wait();
51+
}
52+
}).Wait(500);
4753
}
4854
}
4955

src/GitHub.App/Factories/UIFactory.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ public IUIPair CreateViewAndViewModel(UIViewType viewType)
3535
{
3636
return new UIPair(viewType, factory.GetView(viewType), factory.GetViewModel(viewType));
3737
}
38+
39+
protected virtual void Dispose(bool disposing)
40+
{}
41+
42+
public void Dispose()
43+
{
44+
Dispose(true);
45+
GC.SuppressFinalize(this);
46+
}
47+
3848
}
3949

4050
/// <summary>

src/GitHub.App/Models/RepositoryHost.cs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -268,24 +268,8 @@ IObservable<UserAndScopes> GetUserFromApi()
268268
return Observable.Defer(() => ApiClient.GetUser());
269269
}
270270

271-
bool disposed;
272271
protected virtual void Dispose(bool disposing)
273-
{
274-
if (disposing)
275-
{
276-
if (disposed) return;
277-
278-
try
279-
{
280-
ModelService.Dispose();
281-
}
282-
catch (Exception e)
283-
{
284-
log.Warn("Exception occured while disposing RepositoryHost's ModelService", e);
285-
}
286-
disposed = true;
287-
}
288-
}
272+
{}
289273

290274
public void Dispose()
291275
{

src/GitHub.App/Models/RepositoryHosts.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ public RepositoryHosts(
3939
this.connectionManager = connectionManager;
4040

4141
RepositoryHostFactory = repositoryHostFactory;
42-
disposables.Add(repositoryHostFactory);
4342
GitHubHost = DisconnectedRepositoryHost;
4443
EnterpriseHost = DisconnectedRepositoryHost;
4544

@@ -101,9 +100,7 @@ public RepositoryHosts(
101100
{
102101
var host = LookupHost(x.HostAddress);
103102
if (host.Address != x.HostAddress)
104-
{
105103
host = RepositoryHostFactory.Create(x.HostAddress);
106-
}
107104
return host;
108105
})
109106
.Select(h => LogOut(h))
@@ -147,7 +144,6 @@ public IObservable<AuthenticationResult> LogIn(
147144
{
148145
var isDotCom = HostAddress.GitHubDotComHostAddress == address;
149146
var host = RepositoryHostFactory.Create(address);
150-
disposables.Add(host);
151147
return host.LogIn(usernameOrEmail, password)
152148
.Catch<AuthenticationResult, Exception>(Observable.Throw<AuthenticationResult>)
153149
.Do(result =>
@@ -180,7 +176,6 @@ public IObservable<AuthenticationResult> LogInFromCache(HostAddress address)
180176
{
181177
var isDotCom = HostAddress.GitHubDotComHostAddress == address;
182178
var host = RepositoryHostFactory.Create(address);
183-
disposables.Add(host);
184179
return host.LogInFromCache()
185180
.Catch<AuthenticationResult, Exception>(Observable.Throw<AuthenticationResult>)
186181
.Do(result =>
@@ -210,7 +205,7 @@ public IObservable<Unit> LogOut(IRepositoryHost host)
210205
else
211206
EnterpriseHost = null;
212207
connectionManager.RemoveConnection(address);
213-
disposables.Remove(host);
208+
RepositoryHostFactory.Remove(host);
214209
});
215210
}
216211

src/GitHub.App/Services/AvatarProvider.cs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,8 @@ BitmapImage DefaultAvatar(IAvatarContainer apiAccount)
7777
return apiAccount.IsUser ? DefaultUserBitmapImage : DefaultOrgBitmapImage;
7878
}
7979

80-
bool disposed;
8180
protected virtual void Dispose(bool disposing)
82-
{
83-
if (disposing)
84-
{
85-
if (disposed) return;
86-
imageCache.Dispose();
87-
disposed = true;
88-
}
89-
}
81+
{}
9082

9183
public void Dispose()
9284
{

src/GitHub.App/Services/ModelService.cs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -280,15 +280,8 @@ public IObservable<Unit> InsertUser(AccountCacheItem user)
280280
return hostCache.InsertObject("user", user);
281281
}
282282

283-
bool disposed;
284283
protected virtual void Dispose(bool disposing)
285-
{
286-
if (disposing)
287-
{
288-
if (disposed) return;
289-
disposed = true;
290-
}
291-
}
284+
{}
292285

293286
public void Dispose()
294287
{

0 commit comments

Comments
 (0)