Details
-
Bug
-
Resolution: Fixed
-
Major
-
2.4
-
None
Description
<p>The Plugin Manager can deadlock, causing a lock timeout and the building of plugin items to fail if multiple threads try to activate the same plugin concurrently when requesting plugin items.</p>
<p>If a plugin registers plugin items with multiple plugins, and those plugins request the plugin items concurrently, they will try and activate the plugin concurrently from different threads. This leads to a race condition due to the Plugin Manager holding its internal lock when trying to lock the plugins state.</p>
<p>The 1st thread locks the plugin's state by obtaining an ugradeable read lock for the plugin <a href="https://github.com/MediaPortal/MediaPortal-2/blob/0fc1b50739739dcfc72f976883f846cd70caca02/MediaPortal/Source/Core/MediaPortal.Common/Services/PluginManager/PluginManager.cs#L961">here</a>, the next thread then attempts to obtain the same lock, and is blocked until the 1st thread releases it. However, whilst waiting to obtain the plugin lock it is also holding the Plugin Manager's internal lock <a href="https://github.com/MediaPortal/MediaPortal-2/blob/0fc1b50739739dcfc72f976883f846cd70caca02/MediaPortal/Source/Core/MediaPortal.Common/Services/PluginManager/PluginManager.cs#L723">here</a>, this causes the 1st thread to deadlock when it attempts to obtain the same lock <a href="https://github.com/MediaPortal/MediaPortal-2/blob/0fc1b50739739dcfc72f976883f846cd70caca02/MediaPortal/Source/Core/MediaPortal.Common/Services/PluginManager/PluginManager.cs#L971">here</a>, causing the plugin lock to never be released until the 2nd thread times out.</p>
<p>If a plugin registers plugin items with multiple plugins, and those plugins request the plugin items concurrently, they will try and activate the plugin concurrently from different threads. This leads to a race condition due to the Plugin Manager holding its internal lock when trying to lock the plugins state.</p>
<p>The 1st thread locks the plugin's state by obtaining an ugradeable read lock for the plugin <a href="https://github.com/MediaPortal/MediaPortal-2/blob/0fc1b50739739dcfc72f976883f846cd70caca02/MediaPortal/Source/Core/MediaPortal.Common/Services/PluginManager/PluginManager.cs#L961">here</a>, the next thread then attempts to obtain the same lock, and is blocked until the 1st thread releases it. However, whilst waiting to obtain the plugin lock it is also holding the Plugin Manager's internal lock <a href="https://github.com/MediaPortal/MediaPortal-2/blob/0fc1b50739739dcfc72f976883f846cd70caca02/MediaPortal/Source/Core/MediaPortal.Common/Services/PluginManager/PluginManager.cs#L723">here</a>, this causes the 1st thread to deadlock when it attempts to obtain the same lock <a href="https://github.com/MediaPortal/MediaPortal-2/blob/0fc1b50739739dcfc72f976883f846cd70caca02/MediaPortal/Source/Core/MediaPortal.Common/Services/PluginManager/PluginManager.cs#L971">here</a>, causing the plugin lock to never be released until the 2nd thread times out.</p>