After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 614039 - DapSync needs a lock on library_syncs for all modifications and iterations
DapSync needs a lock on library_syncs for all modifications and iterations
Status: RESOLVED FIXED
Product: banshee
Classification: Other
Component: general
git master
Other Linux
: Normal normal
: ---
Assigned To: Banshee Maintainers
Banshee Maintainers
: 549012 605253 613407 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2010-03-26 17:17 UTC by David Nielsen
Modified: 2015-07-07 23:26 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
log of the crash (222.24 KB, text/plain)
2010-03-26 17:17 UTC, David Nielsen
Details

Description David Nielsen 2010-03-26 17:17:07 UTC
Created attachment 157198 [details]
log of the crash

I disabled the podcast plugin and Banshee crashed. debug log attached.
Comment 1 Gabriel Burt 2010-03-26 17:25:26 UTC
Extracting the stacktrace, looks like an issue with the DAP/library-sync code:

System.InvalidOperationException: Operation is not valid due to the current state of the object
  at System.Linq.Enumerable.First[DapLibrarySync] (IEnumerable`1 source, System.Func`2 predicate, Fallback fallback) [0x00000] 
  at System.Linq.Enumerable.First[DapLibrarySync] (IEnumerable`1 source, System.Func`2 predicate) [0x00000] 
  at Banshee.Dap.DapSync.RemoveLibrary (Banshee.Sources.Source source) [0x0001e] in /build/buildd/banshee-1.5.7+git20100324.r1.501850e/src/Dap/Banshee.Dap/Banshee.Dap/DapSync.cs:196 
  at Banshee.Dap.DapSync.OnSourceRemoved (Banshee.Sources.SourceEventArgs a) [0x00000] in /build/buildd/banshee-1.5.7+git20100324.r1.501850e/src/Dap/Banshee.Dap/Banshee.Dap/DapSync.cs:128 
  at (wrapper delegate-invoke) Banshee.Sources.SourceEventHandler:invoke_void__this___SourceEventArgs (Banshee.Sources.SourceEventArgs)
  at Banshee.Sources.SourceManager+<RemoveSource>c__AnonStorey21.<>m__42 () [0x00050] in /build/buildd/banshee-1.5.7+git20100324.r1.501850e/src/Core/Banshee.Services/Banshee.Sources/SourceManager.cs:232 
  at Hyena.ThreadAssist.ProxyToMain (Hyena.InvokeHandler handler) [0x0001a] in /build/buildd/banshee-1.5.7+git20100324.r1.501850e/src/Libraries/Hyena/Hyena/ThreadAssist.cs:99 
  at Banshee.Sources.SourceManager.RemoveSource (Banshee.Sources.Source source, Boolean recursivelyDispose) [0x0012d] in /build/buildd/banshee-1.5.7+git20100324.r1.501850e/src/Core/Banshee.Services/Banshee.Sources/SourceManager.cs:223 
  at Banshee.Sources.SourceManager.RemoveSource (Banshee.Sources.Source source) [0x00000] in /build/buildd/banshee-1.5.7+git20100324.r1.501850e/src/Core/Banshee.Services/Banshee.Sources/SourceManager.cs:188 
  at Banshee.Podcasting.PodcastService.DisposeInterface () [0x0000b] in /build/buildd/banshee-1.5.7+git20100324.r1.501850e/src/Extensions/Banshee.Podcasting/Banshee.Podcasting/PodcastService_Interface.cs:68 
  at Banshee.Podcasting.PodcastService.Dispose () [0x000cd] in /build/buildd/banshee-1.5.7+git20100324.r1.501850e/src/Extensions/Banshee.Podcasting/Banshee.Podcasting/PodcastService.cs:306 
  at Banshee.ServiceStack.ServiceManager.OnExtensionChanged (System.Object o, Mono.Addins.ExtensionNodeEventArgs args) [0x00082] in /build/buildd/banshee-1.5.7+git20100324.r1.501850e/src/Core/Banshee.Services/Banshee.ServiceStack/ServiceManager.cs:231 
  at Mono.Addins.ExtensionNode.OnChildNodeRemoved (Mono.Addins.ExtensionNode node) [0x00000] 
  at Mono.Addins.ExtensionNode.NotifyChildChanged () [0x00000] 
  at Mono.Addins.TreeNode.NotifyChildrenChanged () [0x00000] 
  at Mono.Addins.TreeNode.Remove () [0x00000] 
  at Mono.Addins.ExtensionContext.RemoveAddinExtensions (System.String id) [0x00000] 
  at Mono.Addins.AddinSessionService.UnloadAddin (System.String id) [0x00000] 
  at Mono.Addins.Database.AddinDatabase.DisableAddin (System.String domain, System.String id) [0x00000] 
  at Mono.Addins.Addin.set_Enabled (Boolean value) [0x00000]
Comment 2 David Nielsen 2010-03-26 18:16:12 UTC
I have a sneaking feeling it is related to:
https://bugzilla.gnome.org/show_bug.cgi?id=613407

The N900 was indeed connected at the time so perhaps there was some undesirable autosync behavior. The crash though occured directly after disabling the podcast extension.. very odd.
Comment 3 Jeroen Budts 2010-03-26 18:54:17 UTC
I tested this with the following steps:
- enable the podcast extension
- add 1 gig of files to my playlist which is synced to my N900
- connect N900
- Start to sync
- disable the podcast

During the syncing I enabled and disabled the Podcast plugin different times, but i could not really reproduce your error.
However after syncing finished, Banshee crashed with the following exception:

Unhandled Exception: System.InvalidOperationException: Collection was modified;enumeration operation may not execute.
  at System.Collections.Generic.List`1+Enumerator[Banshee.Dap.DapLibrarySync].MoveNext () [0x00066] in /build/buildd/mono-2.4.2.3+dfsg/mcs/class/corlib/System.Collections.Generic/List.cs:773 
  at Banshee.Dap.DapSync.RateLimitedSync () [0x00157] in /media/cryptdata/dev/banshee/src/Dap/Banshee.Dap/Banshee.Dap/DapSync.cs:356 
  at Banshee.Base.RateLimiter.InnerExecute () [0x0001b] in /media/cryptdata/dev/banshee/src/Core/Banshee.Services/Banshee.Base/RateLimiter.cs:64 
  at Banshee.Base.RateLimiter.Execute () [0x00036] in /media/cryptdata/dev/banshee/src/Core/Banshee.Services/Banshee.Base/RateLimiter.cs:55 
  at Banshee.Dap.DapSync.<Sync>m__12 () [0x00000] in /media/cryptdata/dev/banshee/src/Dap/Banshee.Dap/Banshee.Dap/DapSync.cs:331 

So something definitely seems wrong in DapSync...
Comment 4 Alexander Kojevnikov 2010-06-08 04:22:51 UTC
DapSync needs a lock on library_syncs for all modifications and iterations. Confirming and marking as gnome-love.
Comment 5 David Nielsen 2010-08-30 20:49:01 UTC
Not Podcasting, assigning to general
Comment 6 David Nielsen 2010-09-22 12:55:42 UTC
*** Bug 613407 has been marked as a duplicate of this bug. ***
Comment 7 David Nielsen 2010-11-26 18:56:54 UTC
*** Bug 549012 has been marked as a duplicate of this bug. ***
Comment 8 David Nielsen 2010-12-09 22:55:32 UTC
*** Bug 605253 has been marked as a duplicate of this bug. ***
Comment 9 Shipra Banga 2014-02-18 16:58:48 UTC
I am new to banshee and wanted to ask what do I need to do to solve this bug. How do you put a lock on library_syncs?
Comment 10 Andrés G. Aragoneses (IRC: knocte) 2014-02-18 17:57:26 UTC
Hello Shipra, thanks for your interest and welcome!

(In reply to comment #9)
> wanted to ask what do I need to do to solve this bug.

Do you want to fix it because you reproduced the bug? If yes, can you post an updated log of the crash? (Banshee codebase might have changed a bit since this bug was filed, so it's always better to have updated stacktraces, with updated line numbers!)

> How do you put a lock on library_syncs?

Are you familiar with C#? You need to use a lock(foo){} block, where foo is your synchronization object. You can look at other places of the codebase to see how this lock blocks can be implemented, for reference.
Comment 11 Andrés G. Aragoneses (IRC: knocte) 2015-07-07 20:16:18 UTC
There are actually two problems to fix here (hence it should be a 2-commits bugfix):

 a) locking around library_syncs, as Alex already said in comment#4 (otherwise the exception in comment#3 could happen).

 To do this is a bit tricky because there's also a Libraries public property that can access the library_syncs field. In this particular case, I would just call .ToArray() in the property, apart from using a lock() as well on it (this way the external consumers of DapSync::Libraries would be dealing with a copy, without the worry about they iterating it when the lock is not held (because it's desirable that the lock_object we use is private, not exposed externally). To prevent them from modifying the collection, we could also change it to IEnumerable<X> instead of IList<X>.

 b) change the LINQ call in DapSync.RemoveLibrary() to use FirstOrDefault() instead of First(), to prevent the exception from comment#1 from happening.

 The reason for this is that the old version of Mono that David Nielsen was using, probably had a wrong LINQ error message (I know this because I actually fixed this bug upstream! look: https://github.com/mono/mono/commit/caf7a8b2c0b0288b19f90b1e43092d4da4083d22 ). So what Mono meant there was not a race condition but an empty sequence (if you use FirstOrDefault(), the result is null, but if you just use First(), an IOE is thrown if no elements are found, kind of like an assert).

Given the above reasons, this bug should maybe have never been a gnome-love one. But now that I looked into it and digested it, it should be easy to fix :) David, you wanted to try, or shall I go ahead?
Comment 12 Andrés G. Aragoneses (IRC: knocte) 2015-07-07 23:26:27 UTC
Fixed in https://git.gnome.org/browse/banshee/commit/?id=286d29896afebc48da4684d8e4d366fb41288c49 and https://git.gnome.org/browse/banshee/commit/?id=14c02083d01ce82467361bafb4bfc902c8e9eaaf.

This problem has been fixed in the unstable development version. The fix will be available in the next major software release. You may need to upgrade your Linux distribution to obtain that newer version.