@@ -79,17 +79,65 @@ def to_class(self):
7979
8080
8181class ManticoreBase (Eventful ):
82- def __new__ (cls , * args , ** kwargs ):
83- if cls in (ManticoreBase , ManticoreSingle , ManticoreThreading , ManticoreMultiprocessing ):
84- raise ManticoreError ("Should not instantiate this" )
82+ def _manticore_single (self ):
83+ self ._worker_type = WorkerSingle
8584
86- cl = consts .mprocessing .to_class ()
87- # change ManticoreBase for the more specific class
88- bases = {cl if issubclass (base , ManticoreBase ) else base for base in cls .__bases__ }
89- cls .__bases__ = tuple (bases )
85+ class FakeLock :
86+ def _nothing (self , * args , ** kwargs ):
87+ pass
9088
91- random .seed (consts .seed )
92- return super ().__new__ (cls )
89+ acquire = _nothing
90+ release = _nothing
91+ __enter__ = _nothing
92+ __exit__ = _nothing
93+ notify_all = _nothing
94+ wait = _nothing
95+
96+ def wait_for (self , condition , * args , ** kwargs ):
97+ if not condition ():
98+ raise Exception ("Deadlock: Waiting for CTRL+C" )
99+
100+ self ._lock = FakeLock ()
101+ self ._killed = ctypes .c_bool (False )
102+ self ._running = ctypes .c_bool (False )
103+ self ._ready_states = []
104+ self ._terminated_states = []
105+ self ._busy_states = []
106+ self ._killed_states = []
107+ self ._shared_context = {}
108+
109+ def _manticore_threading (self ):
110+ self ._worker_type = WorkerThread
111+ self ._lock = threading .Condition ()
112+ self ._killed = ctypes .c_bool (False )
113+ self ._running = ctypes .c_bool (False )
114+ self ._ready_states = []
115+ self ._terminated_states = []
116+ self ._busy_states = []
117+ self ._killed_states = []
118+ self ._shared_context = {}
119+
120+ def _manticore_multiprocessing (self ):
121+ def raise_signal ():
122+ signal .signal (signal .SIGINT , signal .SIG_IGN )
123+
124+ self ._worker_type = WorkerProcess
125+ # This is the global manager that will handle all shared memory access
126+ # See. https://docs.python.org/3/library/multiprocessing.html#multiprocessing.managers.SyncManager
127+ self ._manager = SyncManager ()
128+ self ._manager .start (raise_signal )
129+ # The main manticore lock. Acquire this for accessing shared objects
130+ # THINKME: we use the same lock to access states lists and shared contexts
131+ self ._lock = self ._manager .Condition ()
132+ self ._killed = self ._manager .Value (bool , False )
133+ self ._running = self ._manager .Value (bool , False )
134+ # List of state ids of States on storage
135+ self ._ready_states = self ._manager .list ()
136+ self ._terminated_states = self ._manager .list ()
137+ self ._busy_states = self ._manager .list ()
138+ self ._killed_states = self ._manager .list ()
139+ self ._shared_context = self ._manager .dict ()
140+ self ._context_value_types = {list : self ._manager .list , dict : self ._manager .dict }
93141
94142 # Decorators added first for convenience.
95143 def sync (func : Callable ) -> Callable : # type: ignore
@@ -255,6 +303,11 @@ def __init__(self, initial_state, workspace_url=None, outputspace_url=None, **kw
255303 :param kwargs: other kwargs, e.g.
256304 """
257305 super ().__init__ ()
306+ random .seed (consts .seed )
307+ {consts .mprocessing .single : self ._manticore_single ,
308+ consts .mprocessing .threading : self ._manticore_threading ,
309+ consts .mprocessing .multiprocessing : self ._manticore_multiprocessing
310+ }[consts .mprocessing ]()
258311
259312 if any (
260313 not hasattr (self , x )
@@ -1008,82 +1061,3 @@ def save_run_data(self):
10081061 config .save (f )
10091062
10101063 logger .info ("Results in %s" , self ._output .store .uri )
1011-
1012-
1013- class ManticoreSingle (ManticoreBase ):
1014- _worker_type = WorkerSingle
1015-
1016- def __init__ (self , * args , ** kwargs ):
1017- class FakeLock :
1018- def _nothing (self , * args , ** kwargs ):
1019- pass
1020-
1021- acquire = _nothing
1022- release = _nothing
1023- __enter__ = _nothing
1024- __exit__ = _nothing
1025- notify_all = _nothing
1026- wait = _nothing
1027-
1028- def wait_for (self , condition , * args , ** kwargs ):
1029- if not condition ():
1030- raise Exception ("Deadlock: Waiting for CTRL+C" )
1031-
1032- self ._lock = FakeLock ()
1033- self ._killed = ctypes .c_bool (False )
1034- self ._running = ctypes .c_bool (False )
1035-
1036- self ._ready_states = []
1037- self ._terminated_states = []
1038- self ._busy_states = []
1039- self ._killed_states = []
1040-
1041- self ._shared_context = {}
1042- super ().__init__ (* args , ** kwargs )
1043-
1044-
1045- class ManticoreThreading (ManticoreBase ):
1046- _worker_type = WorkerThread
1047-
1048- def __init__ (self , * args , ** kwargs ):
1049- self ._lock = threading .Condition ()
1050- self ._killed = ctypes .c_bool (False )
1051- self ._running = ctypes .c_bool (False )
1052-
1053- self ._ready_states = []
1054- self ._terminated_states = []
1055- self ._busy_states = []
1056- self ._killed_states = []
1057-
1058- self ._shared_context = {}
1059-
1060- super ().__init__ (* args , ** kwargs )
1061-
1062-
1063- def raise_signal ():
1064- signal .signal (signal .SIGINT , signal .SIG_IGN )
1065-
1066-
1067- class ManticoreMultiprocessing (ManticoreBase ):
1068- _worker_type = WorkerProcess
1069-
1070- def __init__ (self , * args , ** kwargs ):
1071- # This is the global manager that will handle all shared memory access
1072- # See. https://docs.python.org/3/library/multiprocessing.html#multiprocessing.managers.SyncManager
1073- self ._manager = SyncManager ()
1074- self ._manager .start (raise_signal )
1075- # The main manticore lock. Acquire this for accessing shared objects
1076- # THINKME: we use the same lock to access states lists and shared contexts
1077- self ._lock = self ._manager .Condition ()
1078- self ._killed = self ._manager .Value (bool , False )
1079- self ._running = self ._manager .Value (bool , False )
1080-
1081- # List of state ids of States on storage
1082- self ._ready_states = self ._manager .list ()
1083- self ._terminated_states = self ._manager .list ()
1084- self ._busy_states = self ._manager .list ()
1085- self ._killed_states = self ._manager .list ()
1086- self ._shared_context = self ._manager .dict ()
1087- self ._context_value_types = {list : self ._manager .list , dict : self ._manager .dict }
1088-
1089- super ().__init__ (* args , ** kwargs )
0 commit comments