Пример #1
0
    def __init__(self, action=None):
        self.g = (self, action)

        # Id similar to channel name, to correctly select the chosen guard among the guard set.
        self.id = uuid.uuid1().hex

        # Necessary to allow for correct locking
        self.dispatch = SocketDispatcher().getThread()
        self.dispatch.registerGuard(self.id)
        self.LM = LockMessenger(self.id)
Пример #2
0
class Guard(object):
    """
    The empty interface of a guard.
    """
    def __init__(self, action=None):
        self.g = (self, action)

        # Id similar to channel name, to correctly select the chosen guard among the guard set.
        self.id = uuid.uuid1().hex
        self.id = self.id.encode()

        # Necessary to allow for correct locking
        self.dispatch = SocketDispatcher().getThread()
        self.dispatch.registerGuard(self.id)
        self.LM = LockMessenger(self.id)

    def _offer(self, req):
        try:
            # Acquire lock
            conn, state, seq = self.LM.remote_acquire_and_get_state(
                req.process)

            # Check sequence number
            if seq != req.seq_check:
                state = FAIL

            # Success?
            if (state == READY):
                self.LM.remote_notify(conn, req.process, req.ch_id, None)

            # Release lock
            self.LM.remote_release(conn, req.process)

        except AddrUnavailableException:
            # Unable to reach process during offer
            # The primary reason is probably because a request were part of an alting and the process have exited.
            if conf.get(SOCKETS_STRICT_MODE):
                raise FatalException(
                    "PyCSP unable to reach process during Guard.offer(%s)" %
                    str(self.process))
            else:
                sys.stderr.write(
                    "PyCSP unable to reach process during Guard.offer(%s)\n" %
                    str(self.process))

    def _close(self):
        # Invoked from Alternation
        self.dispatch.deregisterGuard(self.id)
Пример #3
0
    def __init__(self, action=None):
        self.g = (self, action)

        # Id similar to channel name, to correctly select the chosen guard among the guard set.
        self.id = uuid.uuid1().hex

        # Necessary to allow for correct locking
        self.dispatch = SocketDispatcher().getThread()
        self.dispatch.registerGuard(self.id)
        self.LM = LockMessenger(self.id)
Пример #4
0
class Guard:
    """
    The empty interface of a guard.
    """
    def __init__(self, action=None):
        self.g = (self, action)

        # Id similar to channel name, to correctly select the chosen guard among the guard set.
        self.id = uuid.uuid1().hex

        # Necessary to allow for correct locking
        self.dispatch = SocketDispatcher().getThread()
        self.dispatch.registerGuard(self.id)
        self.LM = LockMessenger(self.id)

    def _offer(self, req):
        try:
            # Acquire lock
            conn, state, seq = self.LM.remote_acquire_and_get_state(req.process)
            
            # Check sequence number
            if seq != req.seq_check:
                state = FAIL

            # Success?
            if (state == READY):
                self.LM.remote_notify(conn, req.process, req.ch_id, None)
                
            # Release lock
            self.LM.remote_release(conn, req.process)

        except AddrUnavailableException:
            # Unable to reach process during offer
            # The primary reason is probably because a request were part of an alting and the process have exited.
            if conf.get(SOCKETS_STRICT_MODE):
                raise FatalException("PyCSP unable to reach process during Guard.offer(%s)" % str(self.process))
            else:
                sys.stderr.write("PyCSP unable to reach process during Guard.offer(%s)\n" % str(self.process))

    def _close(self):
        # Invoked from Alternation
        self.dispatch.deregisterGuard(self.id)
Пример #5
0
    def run(self):        
        # Create remote lock
        self.cond = threading.Condition()        
        dispatch = SocketDispatcher().getThread()
        self.addr = dispatch.server_addr
        dispatch.registerProcess(self.id, RemoteLock(self))

        try:
            self.return_value = self.fn(*self.args, **self.kwargs)
        except ChannelPoisonException as e:
            # look for channels and channel ends
            self.__check_poison(self.args)
            self.__check_poison(self.kwargs.values())
        except ChannelRetireException as e:
            # look for channel ends
            self.__check_retire(self.args)
            self.__check_retire(self.kwargs.values())

        # Join spawned processes
        for p in self.spawned:
            p.join_report()

        # Initiate clean up and waiting for channels to finish outstanding operations.
        for channel in self.activeChanList:
            channel._CM.leave(channel, self)

        # Wait for channels        
        self.cond.acquire()
        X = len(self.activeChanList)
        while len(self.closedChanList) < X:
            self.cond.wait()
        self.cond.release()

        dispatch.deregisterProcess(self.id)

        # Deregister channel references
        for chan in self.registeredChanConnectList:
            chan._deregister()
        for chan in self.registeredChanHomeList:
            chan._deregister()

        for chan in self.registeredChanHomeList:
            chan._threadjoin()
Пример #6
0
    def run(self):

        # Multiprocessing inherits global objects like singletons. Thus we must reset!
        # Reset SocketDispatcher Singleton object to force the creation of a new
        # SocketDispatcher

        # Host and Port address will be set for the SocketDispatcher (one per interpreter/multiprocess)
        if "pycsp_host" in self.kwargs:
            self.host = self.kwargs.pop("pycsp_host")
        else:
            self.host = ''

        if "pycsp_port" in self.kwargs:
            self.port = self.kwargs.pop("pycsp_port")
        else:
            self.port = None

        if self.host != '':
            conf.set(PYCSP_HOST, self.host)
        if self.port != None:
            conf.set(PYCSP_PORT, self.port)

        try:
            SocketDispatcher(reset=True)
        except SocketBindException as e:
            self._error.value = 1001
            self.return_pipe[1].send(None)
            return

        # Create remote lock
        self.cond = threading.Condition()
        dispatch = SocketDispatcher().getThread()
        self.addr = dispatch.server_addr
        dispatch.registerProcess(self.id, RemoteLock(self))

        return_value = None
        try:
            return_value = self.fn(*self.args, **self.kwargs)
        except ChannelPoisonException as e:
            # look for channels and channel ends
            self.__check_poison(self.args)
            self.__check_poison(list(self.kwargs.values()))
        except ChannelRetireException as e:
            # look for channel ends
            self.__check_retire(self.args)
            self.__check_retire(list(self.kwargs.values()))
        finally:
            self.return_pipe[1].send(return_value)

        # Join spawned processes
        for p in self.spawned:
            p.join_report()

        # Initiate clean up and waiting for channels to finish outstanding operations.
        for channel in self.activeChanList:
            channel._CM.leave(channel, self)

        # Wait for channels
        self.cond.acquire()
        X = len(self.activeChanList)
        while len(self.closedChanList) < X:
            self.cond.wait()
        self.cond.release()

        dispatch.deregisterProcess(self.id)

        # Deregister namespace references
        for chan in self.registeredChanConnectList:
            chan._deregister()
        for chan in self.registeredChanHomeList:
            chan._deregister()

        for chan in self.registeredChanHomeList:
            chan._threadjoin()

        # Wait for sub-processes as these may not yet have quit.
        for processchild in multiprocessing.active_children():
            processchild.join()

        # Wait for sub-threads as these may not yet have quit. When threads are run in multiprocesses (daemon setting is ignored)
        skip = threading.currentThread()
        for threadchild in threading.enumerate():
            if not threadchild == skip:
                threadchild.join()
Пример #7
0
    def run(self):
        
        # Multiprocessing inherits global objects like singletons. Thus we must reset!
        # Reset SocketDispatcher Singleton object to force the creation of a new
        # SocketDispatcher

        # Host and Port address will be set for the SocketDispatcher (one per interpreter/multiprocess)
        if self.kwargs.has_key("pycsp_host"):
            self.host = self.kwargs.pop("pycsp_host")
        else:
            self.host = ''
            
        if self.kwargs.has_key("pycsp_port"):
            self.port = self.kwargs.pop("pycsp_port")
        else:
            self.port = None

        if self.host != '':
            conf.set(PYCSP_HOST, self.host)
        if self.port != None:
            conf.set(PYCSP_PORT, self.port)

        try:            
            SocketDispatcher(reset=True)
        except SocketBindException as e:
            self._error.value = 1001
            self.return_pipe[1].send(None)
            return

        # Create remote lock
        self.cond = threading.Condition()        
        dispatch = SocketDispatcher().getThread()
        self.addr = dispatch.server_addr
        dispatch.registerProcess(self.id, RemoteLock(self))

        return_value = None
        try:
            return_value = self.fn(*self.args, **self.kwargs)
        except ChannelPoisonException as e:
            # look for channels and channel ends
            self.__check_poison(self.args)
            self.__check_poison(self.kwargs.values())
        except ChannelRetireException as e:
            # look for channel ends
            self.__check_retire(self.args)
            self.__check_retire(self.kwargs.values())
        finally:
            self.return_pipe[1].send(return_value)
    
        # Join spawned processes
        for p in self.spawned:
            p.join_report()

        # Initiate clean up and waiting for channels to finish outstanding operations.
        for channel in self.activeChanList:
            channel._CM.leave(channel, self)

        # Wait for channels        
        self.cond.acquire()
        X = len(self.activeChanList)
        while len(self.closedChanList) < X:
            self.cond.wait()
        self.cond.release()

        dispatch.deregisterProcess(self.id)

        # Deregister namespace references
        for chan in self.registeredChanConnectList:
            chan._deregister()
        for chan in self.registeredChanHomeList:
            chan._deregister()

        for chan in self.registeredChanHomeList:
            chan._threadjoin()

        # Wait for sub-processes as these may not yet have quit.
        for processchild in multiprocessing.active_children():
            processchild.join()

        # Wait for sub-threads as these may not yet have quit. When threads are run in multiprocesses (daemon setting is ignored)
        skip = threading.currentThread()
        for threadchild in threading.enumerate():
            if not threadchild == skip:
                threadchild.join()
Пример #8
0
def shutdown():
    """
    Closing the PYCSP instance

    Every PyCSP application will create a server thread, to serve incoming communications
    on channels. For this reason, it is required to always end the PyCSP application with
    a call to shutdown()

    Usage:
      >>> shutdown()

    Performs a stable shutdown of hosted channels, waiting for local and remote
    processes to disconnect from the hosted channels.
    """
    global init_procs
    try:
        # compatible with Python 2.6+
        current_proc = threading.current_thread()
    except AttributeError:
        # compatible with Python 2.5- 
        current_proc = threading.currentThread()

    try:
        if current_proc.maintained:
            raise InfoException("pycsp.shutdown must not be called in PyCSP processes wrapped in a PyCSP.Process structure. PyCSP.Process processes have their own shutdown mechanism.")
    except AttributeError:
        pass

    try:
        dispatch = SocketDispatcher().getThread()

        for p in current_proc.spawned:
            p.join_report()

        # Initiate clean up and waiting for channels to finish outstanding operations.
        for channel in current_proc.activeChanList:
            channel._CM.leave(channel, current_proc)

        # Wait for channels        
        current_proc.cond.acquire()
        X = len(current_proc.activeChanList)
        while len(current_proc.closedChanList) < X:
            current_proc.cond.wait()
        current_proc.cond.release()

        dispatch.deregisterProcess(current_proc.id)

        # Deregister channel references
        for chan in current_proc.registeredChanConnectList:
            chan._deregister()        
        for chan in current_proc.registeredChanHomeList:
            chan._deregister()        
            
        # Wait for channelhomethreads to terminate
        for chan in current_proc.registeredChanHomeList:
            chan._threadjoin()

        # Cleaning structures
        current_proc.spawned = []
        current_proc.registeredChanHomeList = []
        current_proc.registeredChanConnectList = []
        current_proc.activeChanList = []
        current_proc.closedChanList = []

        # Reset current_proc id, to force a new init(), if required
        del current_proc.id


    except AttributeError:
        pass
Пример #9
0
def init():
    """
    Initialising state variables for channel communication made from an uninitialized thread/process (__main__).

    This function is invoked from const.getThreadAndName to initialise the current NON-CSP! process when necessary.
    """
    global init_procs
    try:
        # compatible with Python 2.6+
        current_proc = threading.current_thread()
    except AttributeError:
        # compatible with Python 2.5- 
        current_proc = threading.currentThread()        

    run = True
    try:
        if current_proc.id != None:
            run = False
    except AttributeError:
        pass

    if run:
        if not current_proc in init_procs:
            init_procs.append(current_proc)

        current_proc.id = uuid.uuid1().hex + ".__INIT__"
        current_proc.fn = None
        current_proc.state = FAIL
        current_proc.result_ch_idx = None
        current_proc.result_msg = None
        current_proc.ack = False

        current_proc.sequence_number = 1

        # Protect against early termination of mother-processes leaving childs in an invalid state
        current_proc.spawned = []

        # Protect against early termination of channelhomes leaving channel references in an invalid state
        current_proc.registeredChanHomeList = []
        current_proc.registeredChanConnectList = []

        # Protect against early termination of processes leaving channelhomes in an invalid state
        current_proc.activeChanList = []
        current_proc.closedChanList = []

        current_proc.cond = threading.Condition()
        dispatch = SocketDispatcher().getThread()
        current_proc.addr = dispatch.server_addr
        dispatch.registerProcess(current_proc.id, RemoteLock(current_proc))

        def wait_ack():
            current_proc.cond.acquire()
            while not current_proc.ack:
                current_proc.cond.wait()
            # Got ack, resetting
            current_proc.ack= False
            current_proc.cond.release()

        def wait():
            current_proc.cond.acquire()
            while current_proc.state == READY:
                current_proc.cond.wait()
            current_proc.cond.release()

        current_proc.wait = wait
        current_proc.wait_ack = wait_ack