#!/usr/bin/env python ############################################################################# # Copyright (C) DSTC Pty Ltd (ACN 052 372 577) 1997, 1998, 1999 # All Rights Reserved. # # The software contained on this media is the property of the DSTC Pty # Ltd. Use of this software is strictly in accordance with the # license agreement in the accompanying LICENSE.HTML file. If your # distribution of this software does not contain a LICENSE.HTML file # then you have no rights to use this software in any manner and # should contact DSTC at the address below to determine an appropriate # licensing arrangement. # # DSTC Pty Ltd # Level 7, GP South # Staff House Road # University of Queensland # St Lucia, 4072 # Australia # Tel: +61 7 3365 4310 # Fax: +61 7 3365 4311 # Email: enquiries@dstc.edu.au # # This software is being provided "AS IS" without warranty of any # kind. In no event shall DSTC Pty Ltd be liable for damage of any # kind arising out of or in connection with the use or performance of # this software. # # Project: Fnorb # File: $Source: /cvsroot/fnorb/fnorb/orb/GIOPServerWorkerThreaded.py,v $ # Version: @(#)$RCSfile: GIOPServerWorkerThreaded.py,v $ $Revision: 1.8 $ # ############################################################################# """ GIOPServerWorkerThreaded class. """ # For obvious reasons we import the *real* thread module, not 'fnorb_thread'! import thread # Fnorb modules. import CORBA, GIOPConnectionHandler, GIOPServerWorker class GIOPServerWorkerThreaded(GIOPServerWorker.GIOPServerWorker): """ IIOP Worker class. """ def __init__(self, giop_version, giop_server, connection): """ Constructor. 'giop_version' is the GIOP version of this ORB 'giop_server' is the GIOPServer server that is creating the worker. 'connection' is a connection to the 'client' ORB. """ self.__giop_version = giop_version self.__giop_server = giop_server self.__connection = connection # Set the connection to BLOCKING mode. self.__connection.blocking(1) # Create a handler to look after the connection. self.__handler = GIOPConnectionHandler.GIOPConnectionHandler \ (self.__giop_version, self, self.__connection) # Flag used to detect closure in the worker thread. self.__closed = 0 # Mutex for the '__closed' flag. self.__lk = thread.allocate_lock() # Start the worker thread. thread.start_new_thread(self.__worker_thread, ()) return def pseudo__del__(self): """ Pseudo destructor to remove circular references. This method is called from '__close' only. """ # The GIOP server holds a (circular) reference to this instance so we # have to explicitly clean it up. self.__giop_server.pseudo__del__() # Clean up *our* reference to *it*! del self.__giop_server # The handler also holds a (circular) reference to this instance so we # have to explicitly clean it up. self.__handler.pseudo__del__() # Clean up *our* reference to *it*! del self.__handler return ######################################################################### # GIOPServerWorker interface. ######################################################################### def send(self, message): """ Send a message. """ self.__lk.acquire() try: try: # Send the entire message. n = 0 while n < len(message): n = n + self.__handler.send(message) # We can simply ignore any exceptions when sending a message # as the worker thread will detect the error and close down # the connection. except CORBA.SystemException: pass finally: self.__lk.release() def close_connection(self): """ Close down the server. Currently, Fnorb does not close down servers, so this is not used. """ # Close down the worker. self.__close() return ######################################################################### # GIOPConnectionHandlerListener interface. ######################################################################### def message_received(self, message): """ Called when a complete GIOP message has been received. """ # Pass the message up to the GIOP layer. self.__giop_server.process_giop_message(message) return def message_sent(self): """ Called when a complete GIOP message has been sent. """ pass ######################################################################### # Private interface. ######################################################################### def __worker_thread(self): """ Read operation requests from the client. """ try: while not self.__is_closed(): # Blocking receive. self.__handler.recv() except CORBA.SystemException: pass # Close down the worker. self.__close() # Explicitly exit the thread! # Not sure why we do this, and it causes Jython to exit, so I've # take it out (dthomson) # thread.exit() def __is_closed(self): """ Are we closing down? """ self.__lk.acquire() closed = self.__closed self.__lk.release() return closed def __close(self): """ Close down the worker. """ # Notify the worker thread that we are closing down. self.__lk.acquire() try: if not self.__closed: # Close down the connection (via the handler) self.__connection.disconnect() # All done! self.__closed = 1 # Remove circular reference. self.pseudo__del__() finally: self.__lk.release() #############################################################################