<gh_stars>0
import threading
import BB

class ParallelSender(object):
    '''
    Sends a command and waits for the answer in parallel to other thread's execution,
    allowing other thread's to poll if the response have been received.
    
    :param Command command: Command to be sent, must be an instance of class Command.
    :param int timeout: (Default 300000) How much time (in miliseconds) to wait for response before trying again or aborting.
    :param int attempts: (Default 1) How many attempts to send the command if no response is received after timeout.
                If attempts is 0, it will keep trying indefinitely until StopSending is called. (Use carefully)
    
    .. note::
    
        Notice the command is sent when the object is created.
    
    '''

    def __init__(self, command, timeout = 300000, attempts = 1):
        self.__sendingLock = threading.Lock()
        self.__sending = True
        
        self.__respLock = threading.Lock()
        self.__response = None
    
        self.__command = command
        
        self.__attemptsLock = threading.Lock()
        self.__attempts = attempts
        
        self.__timeout = timeout/1000.0
        
        self.__p = threading.Thread(target=self.__Execute)
        self.__p.daemon = True
        self.__p.start()
        
    @property
    def sending(self):
        '''
            A property that indicates whether the object is still waiting for a response.
        '''
        self.__sendingLock.acquire()
        r = self.__sending
        self.__sendingLock.release()
        return r
    
    def __setSending(self, s):
        self.__sendingLock.acquire()
        self.__sending = s
        self.__sendingLock.release()
    
    @property
    def response(self):
        '''
            A property for retrieving the response object generated by the command.
            
            This property should be used when *sending* is ``False``.
        '''
        if not self.__respLock.acquire(False):
            return None
        r = self.__response
        self.__respLock.release()
        return r
    
    def __setResponse(self, R):
        self.__respLock.acquire()
        self.__response = R
        self.__respLock.release()
    
    def StopSending(self):
        self.__attemptsLock.acquire()
        self.__attempts = 1
        self.__attemptsLock.release()
        
    def __Execute(self):
        
        response = None
        
        currentAttempt = 0
        
        self.__attemptsLock.acquire()
        att = self.__attempts
        self.__attemptsLock.release()
        
        while not response and (att == 0 or currentAttempt < att):
            currentAttempt += 1
            response = BB.SendAndWait(self.__command, self.__timeout)
            
            self.__attemptsLock.acquire()
            att = self.__attempts
            self.__attemptsLock.release()
        
        self.__setResponse(response)
        self.__setSending(False)
        

import threading
import BB

class ParallelSender(object):
    '''
    Sends a command and waits for the answer in parallel to other thread's execution,
    allowing other thread's to poll if the response have been received.
    
    :param Command command: Command to be sent, must be an instance of class Command.
    :param int timeout: (Default 300000) How much time (in miliseconds) to wait for response before trying again or aborting.
    :param int attempts: (Default 1) How many attempts to send the command if no response is received after timeout.
                If attempts is 0, it will keep trying indefinitely until StopSending is called. (Use carefully)
    
    .. note::
    
        Notice the command is sent when the object is created.
    
    '''

    def __init__(self, command, timeout = 300000, attempts = 1):
        self.__sendingLock = threading.Lock()
        self.__sending = True
        
        self.__respLock = threading.Lock()
        self.__response = None
    
        self.__command = command
        
        self.__attemptsLock = threading.Lock()
        self.__attempts = attempts
        
        self.__timeout = timeout/1000.0
        
        self.__p = threading.Thread(target=self.__Execute)
        self.__p.daemon = True
        self.__p.start()
        
    @property
    def sending(self):
        '''
            A property that indicates whether the object is still waiting for a response.
        '''
        self.__sendingLock.acquire()
        r = self.__sending
        self.__sendingLock.release()
        return r
    
    def __setSending(self, s):
        self.__sendingLock.acquire()
        self.__sending = s
        self.__sendingLock.release()
    
    @property
    def response(self):
        '''
            A property for retrieving the response object generated by the command.
            
            This property should be used when *sending* is ``False``.
        '''
        if not self.__respLock.acquire(False):
            return None
        r = self.__response
        self.__respLock.release()
        return r
    
    def __setResponse(self, R):
        self.__respLock.acquire()
        self.__response = R
        self.__respLock.release()
    
    def StopSending(self):
        self.__attemptsLock.acquire()
        self.__attempts = 1
        self.__attemptsLock.release()
        
    def __Execute(self):
        
        response = None
        
        currentAttempt = 0
        
        self.__attemptsLock.acquire()
        att = self.__attempts
        self.__attemptsLock.release()
        
        while not response and (att == 0 or currentAttempt < att):
            currentAttempt += 1
            response = BB.SendAndWait(self.__command, self.__timeout)
            
            self.__attemptsLock.acquire()
            att = self.__attempts
            self.__attemptsLock.release()
        
        self.__setResponse(response)
        self.__setSending(False)
Sends a command and waits for the answer in parallel to other thread's execution,     allowing other thread's to poll if the response have been received.          :param Command command: Command to be sent, must be an instance of class Command.     :param int timeout: (Default 300000) How much time (in miliseconds) to wait for response before trying again or aborting.     :param int attempts: (Default 1) How many attempts to send the command if no response is received after timeout.                 If attempts is 0, it will keep trying indefinitely until StopSending is called. (Use carefully)          .. note::              Notice the command is sent when the object is created. A property that indicates whether the object is still waiting for a response. A property for retrieving the response object generated by the command.                          This property should be used when *sending* is ``False``.