def __init__(self, sock, paging_handler = lambda x: None):
        #TODO: Put a meaningful timeout
        self._socket = sock
        self._protocol = AvatarLowlevelProtocol(self._socket, self._handle_received_message)

        self._terminate = threading.Event()
        self._state = None
        self._asynchronous_messages_handler = paging_handler
        self._queued_commands = Queue()
        self._received_synchronous_messages = Queue()
        self._send_thread = threading.Thread(target = self.run_send)
        self._send_lock = threading.Lock()
        self._send_thread.start()
Exemplo n.º 2
0
    def __init__(self, sock, paging_handler = lambda x: None):
        #TODO: Put a meaningful timeout
        self._socket = sock
        self._protocol = AvatarLowlevelProtocol(self._socket, self._handle_received_message)

        self._terminate = threading.Event()
        self._state = None
        self._asynchronous_messages_handler = paging_handler
        self._queued_commands = Queue()
        self._received_synchronous_messages = Queue()
        self._send_thread = threading.Thread(target = self.run_send)
        self._send_lock = threading.Lock()
        self._send_thread.start()
Exemplo n.º 3
0
class AvatarProtocol(object):
    CONNECT_TIMEOUT = 10
    def __init__(self, sock, paging_handler = lambda x: None):
        #TODO: Put a meaningful timeout
        self._socket = sock
        self._protocol = AvatarLowlevelProtocol(self._socket, self._handle_received_message)

        self._terminate = threading.Event()
        self._state = None
        self._asynchronous_messages_handler = paging_handler
        self._queued_commands = Queue()
        self._received_synchronous_messages = Queue()
        self._send_thread = threading.Thread(target = self.run_send)
        self._send_lock = threading.Lock()
        self._send_thread.start()
        
    def _handle_received_message(self, msg): 
        if msg.name in ASYNCHRONOUS_MESSAGES:
            self.handle_asynchronous_message(msg)
        else:
            self._received_synchronous_messages.put(msg)
                
    def run_send(self):
        while not self._terminate.is_set():
            result = None
            try:
                result = self._queued_commands.get(timeout = 1)
            except Empty:
                continue
            
            if not result:
                continue
            
            self._send_lock.acquire()
            self._protocol.send_message(result[0])
            self._send_lock.release()
            
            if result[1]:
                log.debug("Waiting for response to message %s", result[0].name)
                recv_msg = self._received_synchronous_messages.get(timeout = RESPONSE_TIMEOUT)
                if recv_msg and recv_msg.name in result[1]:
                    if result[2]:
                        result[2].acquire()
                        if result[3]:
                            result[3].set_value(recv_msg)
                        result[2].notify()
                        result[2].release()
                else:
                    log.warn("Unexpected message received: %s", recv_msg.name)
                
    def handle_asynchronous_message(self, msg):
        if msg.name == "AVATAR_RPC_DTH_PAGEFAULT":
            page_data = self._page_fault_handler(msg.page_address)
            self.insert_page(msg.page_address, page_data)
            self._send_lock.acquire()
            self._protocol.send_message(create_avatar_message("AVATAR_RPC_HTD_CONTINUE_FROM_PAGEFAULT", {}))
            self._send_lock.release()
        elif msg.name == "AVATAR_RPC_DTH_STATE":
            self._state = msg.state
            
        elif msg.name == "AVATAR_RPC_DTH_INFO_EXCEPTION":
            self._exception_handler(msg.exception)
        self._asynchronous_messages_handler(msg)

    def set_register(self, register, value):
        msg = create_avatar_message("AVATAR_RPC_HTD_SET_REGISTER", {"register": register, "value": value})
        expected_replies = ["AVATAR_RPC_DTH_REPLY_OK",  "AVATAR_RPC_DTH_REPLY_ERROR"]
        cv = threading.Condition()
        ref = Reference()
        
        cv.acquire()
        self._queued_commands.put((msg, expected_replies, cv, ref))
        cv.wait()
        cv.release()
        
    def get_register(self, register):
        msg = create_avatar_message("AVATAR_RPC_HTD_GET_REGISTER", {"register": register})
        expected_replies = ["AVATAR_RPC_DTH_REPLY_GET_REGISTER",  "AVATAR_RPC_DTH_REPLY_ERROR"]
        cv = threading.Condition()
        ref = Reference()
        
        cv.acquire()
        self._queued_commands.put((msg, expected_replies, cv, ref))
        cv.wait()
        cv.release()
        if ref.get_value().name == "AVATAR_RPC_DTH_REPLY_ERROR":
            raise AvatarRemoteError(ref.get_value().error)
        return ref.get_value().value
        
    def read_memory(self, address, size):
        msg = create_avatar_message("AVATAR_RPC_HTD_READ_MEMORY", {"address": address, "size": size})
        expected_replies = ["AVATAR_RPC_DTH_REPLY_READ_MEMORY",  "AVATAR_RPC_DTH_REPLY_ERROR"]
        cv = threading.Condition()
        ref = Reference()
        
        cv.acquire()
        self._queued_commands.put((msg, expected_replies, cv, ref))
        cv.wait()
        cv.release()
        if ref.get_value().name == "AVATAR_RPC_DTH_REPLY_ERROR":
            raise AvatarRemoteError(ref.get_value().error)
        
        return ref.get_value().value
        
    def write_memory(self, address, size, value):
        msg = create_avatar_message("AVATAR_RPC_HTD_WRITE_MEMORY", {"address": address, "size": size, "value": value})
        expected_replies = ["AVATAR_RPC_DTH_REPLY_OK",  "AVATAR_RPC_DTH_REPLY_ERROR"]
        cv = threading.Condition()
        ref = Reference()
        
        cv.acquire()
        self._queued_commands.put((msg, expected_replies, cv, ref))
        cv.wait()
        cv.release()
        if ref.get_value().name == "AVATAR_RPC_DTH_REPLY_ERROR":
            raise AvatarRemoteError(ref.get_value().error)
        
    def read_memory_untyped(self, address, size):
        assert(size <= 255)
        msg = create_avatar_message("AVATAR_RPC_HTD_READ_UNTYPED_MEMORY", {"address": address, "size": size})
        expected_replies = ["AVATAR_RPC_DTH_REPLY_READ_UNTYPED_MEMORY",  "AVATAR_RPC_DTH_REPLY_ERROR"]
        cv = threading.Condition()
        ref = Reference()
        
        cv.acquire()
        self._queued_commands.put((msg, expected_replies, cv, ref))
        cv.wait()
        cv.release()
        if ref.get_value().name == "AVATAR_RPC_DTH_REPLY_ERROR":
            raise AvatarRemoteError(ref.get_value().error)
        
        return ref.get_value().data
        
    def write_memory_untyped(self, address, data):
        assert(len(data) <= 255)
        assert(isinstance(data, bytes))
        msg = create_avatar_message("AVATAR_RPC_HTD_WRITE_UNTYPED_MEMORY", {"address": address, "data": data})
        expected_replies = ["AVATAR_RPC_DTH_REPLY_OK",  "AVATAR_RPC_DTH_REPLY_ERROR"]
        cv = threading.Condition()
        ref = Reference()
        
        cv.acquire()
        self._queued_commands.put((msg, expected_replies, cv, ref))
        cv.wait()
        cv.release()
        if ref.get_value().name == "AVATAR_RPC_DTH_REPLY_ERROR":
            raise AvatarRemoteError(ref.get_value().error)
        
    def execute_codelet(self, address):
        msg = create_avatar_message("AVATAR_RPC_HTD_CODELET_EXECUTE", {"address": address})
        expected_replies = ["AVATAR_RPC_DTH_REPLY_CODELET_EXECUTION_FINISHED",  "AVATAR_RPC_DTH_REPLY_ERROR"]
        cv = threading.Condition()
        ref = Reference()
        
        cv.acquire()
        self._queued_commands.put((msg, expected_replies, cv, ref))
        cv.wait()
        cv.release()
        if ref.get_value().name == "AVATAR_RPC_DTH_REPLY_ERROR":
            raise AvatarRemoteError(ref.get_value().error)
        
    def cont(self):   
        msg = create_avatar_message("AVATAR_RPC_HTD_RESUME_VM", {})
        expected_replies = ["AVATAR_RPC_DTH_REPLY_OK",  "AVATAR_RPC_DTH_REPLY_ERROR"]
        cv = threading.Condition()
        ref = Reference()
        
        cv.acquire()
        self._queued_commands.put((msg, expected_replies, cv, ref))
        cv.wait()
        cv.release()
        if ref.get_value().name == "AVATAR_RPC_DTH_REPLY_ERROR":
            raise AvatarRemoteError(ref.get_value().error)
        
    def stop(self):
        self._terminate.set()
        self._protocol.stop()
class AvatarProtocol():
    CONNECT_TIMEOUT = 10
    def __init__(self, sock, paging_handler = lambda x: None):
        #TODO: Put a meaningful timeout
        self._socket = sock
        self._protocol = AvatarLowlevelProtocol(self._socket, self._handle_received_message)

        self._terminate = threading.Event()
        self._state = None
        self._asynchronous_messages_handler = paging_handler
        self._queued_commands = Queue()
        self._received_synchronous_messages = Queue()
        self._send_thread = threading.Thread(target = self.run_send)
        self._send_lock = threading.Lock()
        self._send_thread.start()
        
    def _handle_received_message(self, msg): 
        if msg.name in ASYNCHRONOUS_MESSAGES:
            self.handle_asynchronous_message(msg)
        else:
            self._received_synchronous_messages.put(msg)
                
    def run_send(self):
        while not self._terminate.is_set():
            result = None
            try:
                result = self._queued_commands.get(timeout = 1)
            except Empty:
                continue
            
            if not result:
                continue
            
            self._send_lock.acquire()
            self._protocol.send_message(result[0])
            self._send_lock.release()
            
            if result[1]:
                log.debug("Waiting for response to message %s", result[0].name)
                recv_msg = self._received_synchronous_messages.get(timeout = RESPONSE_TIMEOUT)
                if recv_msg and recv_msg.name in result[1]:
                    if result[2]:
                        result[2].acquire()
                        if result[3]:
                            result[3].set_value(recv_msg)
                        result[2].notify()
                        result[2].release()
                else:
                    log.warn("Unexpected message received: %s", recv_msg.name)
                
    def handle_asynchronous_message(self, msg):
        if msg.name == "AVATAR_RPC_DTH_PAGEFAULT":
            page_data = self._page_fault_handler(msg.page_address)
            self.insert_page(msg.page_address, page_data)
            self._send_lock.acquire()
            self._protocol.send_message(create_avatar_message("AVATAR_RPC_HTD_CONTINUE_FROM_PAGEFAULT", {}))
            self._send_lock.release()
        elif msg.name == "AVATAR_RPC_DTH_STATE":
            self._state = msg.state
            
        elif msg.name == "AVATAR_RPC_DTH_INFO_EXCEPTION":
            self._exception_handler(msg.exception)
        self._asynchronous_messages_handler(msg)

    def set_register(self, register, value):
        msg = create_avatar_message("AVATAR_RPC_HTD_SET_REGISTER", {"register": register, "value": value})
        expected_replies = ["AVATAR_RPC_DTH_REPLY_OK",  "AVATAR_RPC_DTH_REPLY_ERROR"]
        cv = threading.Condition()
        ref = Reference()
        
        cv.acquire()
        self._queued_commands.put((msg, expected_replies, cv, ref))
        cv.wait()
        cv.release()
        
    def get_register(self, register):
        msg = create_avatar_message("AVATAR_RPC_HTD_GET_REGISTER", {"register": register})
        expected_replies = ["AVATAR_RPC_DTH_REPLY_GET_REGISTER",  "AVATAR_RPC_DTH_REPLY_ERROR"]
        cv = threading.Condition()
        ref = Reference()
        
        cv.acquire()
        self._queued_commands.put((msg, expected_replies, cv, ref))
        cv.wait()
        cv.release()
        if ref.get_value().name == "AVATAR_RPC_DTH_REPLY_ERROR":
            raise AvatarRemoteError(ref.get_value().error)
        return ref.get_value().value
        
    def read_memory(self, address, size):
        msg = create_avatar_message("AVATAR_RPC_HTD_READ_MEMORY", {"address": address, "size": size})
        expected_replies = ["AVATAR_RPC_DTH_REPLY_READ_MEMORY",  "AVATAR_RPC_DTH_REPLY_ERROR"]
        cv = threading.Condition()
        ref = Reference()
        
        cv.acquire()
        self._queued_commands.put((msg, expected_replies, cv, ref))
        cv.wait()
        cv.release()
        if ref.get_value().name == "AVATAR_RPC_DTH_REPLY_ERROR":
            raise AvatarRemoteError(ref.get_value().error)
        
        return ref.get_value().value
        
    def write_memory(self, address, size, value):
        msg = create_avatar_message("AVATAR_RPC_HTD_WRITE_MEMORY", {"address": address, "size": size, "value": value})
        expected_replies = ["AVATAR_RPC_DTH_REPLY_OK",  "AVATAR_RPC_DTH_REPLY_ERROR"]
        cv = threading.Condition()
        ref = Reference()
        
        cv.acquire()
        self._queued_commands.put((msg, expected_replies, cv, ref))
        cv.wait()
        cv.release()
        if ref.get_value().name == "AVATAR_RPC_DTH_REPLY_ERROR":
            raise AvatarRemoteError(ref.get_value().error)
        
    def read_memory_untyped(self, address, size):
        assert(size <= 255)
        msg = create_avatar_message("AVATAR_RPC_HTD_READ_UNTYPED_MEMORY", {"address": address, "size": size})
        expected_replies = ["AVATAR_RPC_DTH_REPLY_READ_UNTYPED_MEMORY",  "AVATAR_RPC_DTH_REPLY_ERROR"]
        cv = threading.Condition()
        ref = Reference()
        
        cv.acquire()
        self._queued_commands.put((msg, expected_replies, cv, ref))
        cv.wait()
        cv.release()
        if ref.get_value().name == "AVATAR_RPC_DTH_REPLY_ERROR":
            raise AvatarRemoteError(ref.get_value().error)
        
        return ref.get_value().data
        
    def write_memory_untyped(self, address, data):
        assert(len(data) <= 255)
        assert(isinstance(data, bytes))
        msg = create_avatar_message("AVATAR_RPC_HTD_WRITE_UNTYPED_MEMORY", {"address": address, "data": data})
        expected_replies = ["AVATAR_RPC_DTH_REPLY_OK",  "AVATAR_RPC_DTH_REPLY_ERROR"]
        cv = threading.Condition()
        ref = Reference()
        
        cv.acquire()
        self._queued_commands.put((msg, expected_replies, cv, ref))
        cv.wait()
        cv.release()
        if ref.get_value().name == "AVATAR_RPC_DTH_REPLY_ERROR":
            raise AvatarRemoteError(ref.get_value().error)
        
    def execute_codelet(self, address):
        msg = create_avatar_message("AVATAR_RPC_HTD_CODELET_EXECUTE", {"address": address})
        expected_replies = ["AVATAR_RPC_DTH_REPLY_CODELET_EXECUTION_FINISHED",  "AVATAR_RPC_DTH_REPLY_ERROR"]
        cv = threading.Condition()
        ref = Reference()
        
        cv.acquire()
        self._queued_commands.put((msg, expected_replies, cv, ref))
        cv.wait()
        cv.release()
        if ref.get_value().name == "AVATAR_RPC_DTH_REPLY_ERROR":
            raise AvatarRemoteError(ref.get_value().error)
        
    def cont(self):   
        msg = create_avatar_message("AVATAR_RPC_HTD_RESUME_VM", {})
        expected_replies = ["AVATAR_RPC_DTH_REPLY_OK",  "AVATAR_RPC_DTH_REPLY_ERROR"]
        cv = threading.Condition()
        ref = Reference()
        
        cv.acquire()
        self._queued_commands.put((msg, expected_replies, cv, ref))
        cv.wait()
        cv.release()
        if ref.get_value().name == "AVATAR_RPC_DTH_REPLY_ERROR":
            raise AvatarRemoteError(ref.get_value().error)
        
    def stop(self):
        self._terminate.set()
        self._protocol.stop()