forked from platypush/platypush
Lock to prevent race conditions where multiple initializations of a plugin can occur
This commit is contained in:
parent
e5d67c9393
commit
105d5bb2fc
2 changed files with 17 additions and 10 deletions
|
@ -1,6 +1,8 @@
|
||||||
import importlib
|
import importlib
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from threading import Lock
|
||||||
|
|
||||||
from ..config import Config
|
from ..config import Config
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -11,6 +13,10 @@ backends = {}
|
||||||
# Map: plugin_name -> plugin_instance
|
# Map: plugin_name -> plugin_instance
|
||||||
plugins = {}
|
plugins = {}
|
||||||
|
|
||||||
|
# Map: plugin_name -> init_lock to make sure that a plugin isn't initialized
|
||||||
|
# multiple times
|
||||||
|
plugins_init_locks = {}
|
||||||
|
|
||||||
# Reference to the main application bus
|
# Reference to the main application bus
|
||||||
main_bus = None
|
main_bus = None
|
||||||
|
|
||||||
|
@ -63,6 +69,7 @@ def get_plugin(plugin_name, reload=False):
|
||||||
""" Registers a plugin instance by name if not registered already, or
|
""" Registers a plugin instance by name if not registered already, or
|
||||||
returns the registered plugin instance"""
|
returns the registered plugin instance"""
|
||||||
global plugins
|
global plugins
|
||||||
|
global plugins_init_locks
|
||||||
|
|
||||||
if plugin_name in plugins and not reload:
|
if plugin_name in plugins and not reload:
|
||||||
return plugins[plugin_name]
|
return plugins[plugin_name]
|
||||||
|
@ -84,7 +91,12 @@ def get_plugin(plugin_name, reload=False):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
plugin_class = getattr(plugin, cls_name)
|
plugin_class = getattr(plugin, cls_name)
|
||||||
plugin = plugin_class(**plugin_conf)
|
if plugin_name not in plugins_init_locks:
|
||||||
|
plugins_init_locks[plugin_name] = Lock()
|
||||||
|
|
||||||
|
with plugins_init_locks[plugin_name]:
|
||||||
|
plugin = plugin_class(**plugin_conf)
|
||||||
|
|
||||||
plugins[plugin_name] = plugin
|
plugins[plugin_name] = plugin
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
logger.warning('No such class in {}: {}'.format(plugin_name, cls_name))
|
logger.warning('No such class in {}: {}'.format(plugin_name, cls_name))
|
||||||
|
|
|
@ -84,16 +84,11 @@ class GpioZeroborgPlugin(Plugin):
|
||||||
self.directions = directions
|
self.directions = directions
|
||||||
self.auto_mode = False
|
self.auto_mode = False
|
||||||
self._direction = None
|
self._direction = None
|
||||||
self.zb = None
|
|
||||||
|
|
||||||
if self._init_in_progress.locked():
|
self.zb = ZeroBorg.ZeroBorg()
|
||||||
raise RuntimeError("ZeroBorg initialization already in progress")
|
self.zb.Init()
|
||||||
|
self.zb.SetCommsFailsafe(True)
|
||||||
with self._init_in_progress:
|
self.zb.ResetEpo()
|
||||||
self.zb = ZeroBorg.ZeroBorg()
|
|
||||||
self.zb.Init()
|
|
||||||
self.zb.SetCommsFailsafe(True)
|
|
||||||
self.zb.ResetEpo()
|
|
||||||
|
|
||||||
|
|
||||||
def _get_measurement(self, plugin, timeout):
|
def _get_measurement(self, plugin, timeout):
|
||||||
|
|
Loading…
Reference in a new issue