[mono/monodevelop] 1ad55564: [VersionControl] Never invoke VCS queries with the lock held
| Newsgroups | gmane.comp.gnome.mono.patches |
|---|---|
| Message-ID | <00000141e3306ffc-87998258-89c4-4bcf-92e6-e179b4fe2e6d-000000@email.amazonses.com> |
Branch: refs/heads/master
Home: https://github.com/mono/monodevelop
Compare: https://github.com/mono/monodevelop/compare/703e63cbe76d...1ad55564c3c4
Commit: 1ad55564c3c489e725a83732b7dbb00d54929f5e
Author: Alan McGovern <[email protected]> (alanmcgovern)
Date: 2013-10-23 02:32:47 GMT
URL: https://github.com/mono/monodevelop/commit/1ad55564c3c489e725a83732b7dbb00d54929f5e
[VersionControl] Never invoke VCS queries with the lock held
The purpose of this lock is purely to provide threadsafe access
to the collections holding the version control queries. We should
not execute any query with that lock held as that will result in
the IDE hanging until it has completely executed all VCS queries
in the current batch.
I kept the current intent of the code while respecting the semanatics
of the lock by duplicating the collections while the lock was held.
Changed paths:
M main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl/Repository.cs
Modified: main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl/Repository.cs
===================================================================
@@ -292,23 +292,37 @@ void RunQueries (object ob)
// DateTime t = DateTime.Now;
// Console.WriteLine ("RunQueries started");
try {
- lock (queryLock) {
- var groups = fileQueryQueue.GroupBy (q => (q.QueryFlags & VersionInfoQueryFlags.IncludeRemoteStatus) != 0);
+ while (true) {
+ VersionInfoQuery [] fileQueryQueueClone;
+ DirectoryInfoQuery [] directoryQueryQueueClone;
+
+ lock (queryLock) {
+ if (fileQueryQueue.Count == 0 && directoryQueryQueue.Count == 0) {
+ queryRunning = false;
+ return;
+ }
+
+ fileQueryQueueClone = fileQueryQueue.ToArray ();
+ fileQueryQueue.Clear ();
+ filesInQueryQueue.Clear ();
+
+ directoryQueryQueueClone = directoryQueryQueue.ToArray ();
+ directoriesInQueryQueue.Clear ();
+ directoryQueryQueue.Clear ();
+ }
+
+ // Ensure we do not execute this with the query lock held, otherwise the IDE can hang while trying to add
+ // new queries to the queue while long-running VCS operations are being performed
+ var groups = fileQueryQueueClone.GroupBy (q => (q.QueryFlags & VersionInfoQueryFlags.IncludeRemoteStatus) != 0);
foreach (var group in groups) {
var status = OnGetVersionInfo (group.SelectMany (q => q.Paths), group.Key);
infoCache.SetStatus (status);
}
- filesInQueryQueue.Clear ();
- foreach (var item in directoryQueryQueue) {
+ foreach (var item in directoryQueryQueueClone) {
var status = OnGetDirectoryVersionInfo (item.Directory, item.GetRemoteStatus, false);
infoCache.SetDirectoryStatus (item.Directory, status, item.GetRemoteStatus);
}
- directoriesInQueryQueue.Clear ();
-
- fileQueryQueue.Clear ();
- directoryQueryQueue.Clear ();
- queryRunning = false;
}
} catch (Exception ex) {
LoggingService.LogError ("Version control status query failed", ex);
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches