home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / fnb101.zip / Lib / site-packages / Fnorb / orb / GIOPServerWorkerReactive.py < prev    next >
Text File  |  1999-06-28  |  7KB  |  239 lines

  1. #!/usr/bin/env python
  2. #############################################################################
  3. # Copyright (C) DSTC Pty Ltd (ACN 052 372 577) 1997, 1998, 1999
  4. # All Rights Reserved.
  5. #
  6. # The software contained on this media is the property of the DSTC Pty
  7. # Ltd.  Use of this software is strictly in accordance with the
  8. # license agreement in the accompanying LICENSE.HTML file.  If your
  9. # distribution of this software does not contain a LICENSE.HTML file
  10. # then you have no rights to use this software in any manner and
  11. # should contact DSTC at the address below to determine an appropriate
  12. # licensing arrangement.
  13. #      DSTC Pty Ltd
  14. #      Level 7, GP South
  15. #      Staff House Road
  16. #      University of Queensland
  17. #      St Lucia, 4072
  18. #      Australia
  19. #      Tel: +61 7 3365 4310
  20. #      Fax: +61 7 3365 4311
  21. #      Email: enquiries@dstc.edu.au
  22. # This software is being provided "AS IS" without warranty of any
  23. # kind.  In no event shall DSTC Pty Ltd be liable for damage of any
  24. # kind arising out of or in connection with the use or performance of
  25. # this software.
  26. #
  27. # Project:      Fnorb
  28. # File:         $Source: /units/arch/src/Fnorb/orb/RCS/GIOPServerWorkerReactive.py,v $
  29. # Version:      @(#)$RCSfile: GIOPServerWorkerReactive.py,v $ $Revision: 1.5 $
  30. #
  31. #############################################################################
  32. """ GIOPServerWorkerReactive class. """
  33.  
  34.  
  35. # Fnorb modules.
  36. import CORBA, EventHandler, GIOPServerWorker, GIOPConnectionHandler, Reactor
  37.  
  38.  
  39. class GIOPServerWorkerReactive(GIOPServerWorker.GIOPServerWorker,
  40.                    EventHandler.EventHandler):
  41.     """ GIOPServerWorkerReactive class.
  42.  
  43.     A concrete 'EventHandler' in the 'Reactor' pattern.
  44.  
  45.     This class is *not* thread safe, but since the whole point of the 'Reactor'
  46.     pattern is to work in a single-threaded environment, I don't see this as
  47.     much of a problem ;^)
  48.  
  49.     """
  50.     def __init__(self, giop_server, connection):
  51.     """ Provide an interface to a remote object!
  52.  
  53.     'protocol'   is the protocol used by this worker.
  54.     'connection' is the aconnection to the remote object.
  55.  
  56.     """
  57.     self.__giop_server = giop_server
  58.     self.__connection = connection
  59.  
  60.     # Have we been closed down?
  61.     self.__closed = 0
  62.  
  63.     # Set the connection to NON-blocking mode.
  64.     self.__connection.blocking(0)
  65.  
  66.     # Queue of outgoing GIOP messages.
  67.     self.__outgoing = []
  68.  
  69.     # Get a reference to the active reactor.
  70.     self.__reactor = Reactor.Reactor_init()
  71.  
  72.     # Register our interest in read events (ie. operation requests) with
  73.     # the Reactor.
  74.     self.__reactor.register_handler(self, Reactor.READ)
  75.  
  76.     # Create a handler to look after the connection.
  77.     self.__handler = GIOPConnectionHandler.GIOPConnectionHandler \
  78.              (self, self.__connection)
  79.     return
  80.  
  81.     def pseudo__del__(self):
  82.     """ Pseudo destructor to remove circular references.
  83.  
  84.     This method is called from '__shutdown' only.
  85.  
  86.     """
  87.     # The GIOP server holds a (circular) reference to this instance so we
  88.     # have to explicitly clean it up.
  89.     self.__giop_server.pseudo__del__()
  90.  
  91.     # Clean up *our* reference to *it*!
  92.     del self.__giop_server
  93.  
  94.     # The handler also holds a (circular) reference to this instance so we
  95.     # have to explicitly clean it up.
  96.     self.__handler.pseudo__del__()
  97.  
  98.     # Clean up *our* reference to *it*!
  99.     del self.__handler
  100.  
  101.     return
  102.  
  103.     #########################################################################
  104.     # GIOPServerWorker interface.
  105.     #########################################################################
  106.  
  107.     def send(self, message):
  108.     """ Send a message to the 'client'.
  109.  
  110.     This method simply adds the message to the queue of outgoing messages
  111.     and registers out interest in write events with the Reactor.
  112.  
  113.     """
  114.     # Add the outgoing message to the queue.
  115.     self.__outgoing.append(message)
  116.         
  117.     # Register my interest in write events with the Reactor.
  118.     self.__reactor.register_handler(self, Reactor.WRITE)
  119.  
  120.     return
  121.  
  122.     def close_connection(self):
  123.     """ Close down the worker.
  124.  
  125.     Currently, Fnorb does not close down servers, so this is not used.
  126.  
  127.     """
  128.     if not self.__closed:
  129.         # Don't accept any more operation requests.
  130.         self.__reactor.unregister_handler(self, Reactor.READ)
  131.  
  132.         # Send all outstanding messages.
  133.         while len(self.__outgoing) > 0:
  134.         self.__reactor.do_one_event()
  135.  
  136.         # Close down the worker.
  137.         self.__close()
  138.  
  139.     return
  140.  
  141.     #########################################################################
  142.     # EventHandler interface.
  143.     #########################################################################
  144.  
  145.     def handle_event(self, mask):
  146.     """ Callback method to handle all events except close events. """
  147.  
  148.     # Read event.
  149.     if mask & Reactor.READ:
  150.         try:
  151.         self.__handler.recv()
  152.  
  153.         except CORBA.SystemException:
  154.         self.handle_close()
  155.  
  156.     # Write event.
  157.     elif mask & Reactor.WRITE:
  158.         try:
  159.         self.__handler.send(self.__outgoing[0])
  160.  
  161.         except CORBA.SystemException:
  162.         self.handle_close()
  163.  
  164.     # Exception event.
  165.     elif mask & Reactor.EXCEPTION:
  166.         self.handle_close()
  167.  
  168.     return
  169.  
  170.     def handle_close(self):
  171.     """ Callback method to handle close events. """
  172.  
  173.     # Close down the worker.
  174.     self.__close()
  175.  
  176.     return
  177.  
  178.     def handle(self):
  179.     """ Return my underlying I/O handle.
  180.  
  181.     In this case, my I/O handle is the file descriptor of my socket. 
  182.  
  183.     """
  184.     return self.__connection.handle()
  185.  
  186.     #########################################################################
  187.     # GIOPConnectionHandlerListener interface.
  188.     #########################################################################
  189.  
  190.     def message_received(self, message):
  191.     """ Called when a complete GIOP message has been received. """
  192.  
  193.     # Pass the message up to the GIOP server.
  194.     self.__giop_server.process_giop_message(message)
  195.  
  196.     return
  197.  
  198.     def message_sent(self):
  199.     """ Called when a complete GIOP message has been sent. """
  200.  
  201.     # Remove the message from the outgoing queue.
  202.     del self.__outgoing[0]
  203.  
  204.     # If there are no other messages left to send then tell the Reactor
  205.     # that I am no longer interested in write events.
  206.     if len(self.__outgoing) == 0:
  207.         self.__reactor.unregister_handler(self, Reactor.WRITE)
  208.  
  209.     return
  210.  
  211.     #########################################################################
  212.     # Private interface.
  213.     #########################################################################
  214.  
  215.     def __close(self):
  216.     """ Close down the worker. """
  217.  
  218.     if not self.__closed:
  219.         # Withdraw all of my Reactor registrations.
  220.         self.__reactor.unregister_handler(self, Reactor.ALL)
  221.  
  222.         # Set the connection to blocking mode.
  223.         self.__connection.blocking(1)
  224.  
  225.         # Close our connection.
  226.         self.__connection.disconnect()
  227.  
  228.         # All done!
  229.         self.__closed = 1
  230.  
  231.         # Remove circular references.
  232.         self.pseudo__del__()
  233.  
  234.     return
  235.  
  236. #############################################################################
  237.