Previous Table of Contents Next


4.2.5 Thread-Related Operations


   To support single-threaded ORBs, as well as multi-threaded ORBs that run multi-thread-unaware code, several operations are included in the ORB interface. These operations can be used by single-threaded and multi-threaded applications. An application that is a pure ORB client would not need to use these operations. Both the ORB::run and ORB::shutdown are useful in fully multi-threaded programs.

   These operations are defined on the ORB rather than on an object adapter to allow the main thread to be used for all kinds of asynchronous processing by the ORB. Defining these operations on the ORB also allows the ORB to support multiple object adapters, without requiring the application main to know about all the object adapters. The interface between the ORB and an object adapter is not standardized.

   4.2.5.1 work_pending

   boolean work_pending( );

   This operation returns an indication of whether the ORB needs the main thread to perform some work.

   A result of TRUE indicates that the ORB needs the main thread to perform some work and a result of FALSE indicates that the ORB does not need the main thread.

   4.2.5.2 perform_work

   void perform_work();

   If called by the main thread, this operation performs an implementation-defined unit of work; otherwise, it does nothing.

   It is platform-specific how the application and ORB arrange to use compatible threading primitives.

   The work_pending() and perform_work() operations can be used to write a simple polling loop that multiplexes the main thread among the ORB and other activities. Such a loop would most likely be needed in a single-threaded server. A multi-threaded server would need a polling loop only if there were both ORB and other code that required use of the main thread.

   Here is an example of such a polling loop:

   // C++for (;;) {if (orb->work_pending()) {

   orb->perform_work();};// do other things// sleep?

   };

   Once the ORB has shutdown, work_pending and perform_work will raise the BAD_INV_ORDER exception with minor code 4. An application can detect this exception to determine when to terminate a polling loop.

   4.2.5.3 run

   void run();

   This operation provides execution resources to the ORB so that it can perform its internal functions. Single threaded ORB implementations, and some multi-threaded ORB implementations, need the use of the main thread in order to function properly. For maximum portability, an application should call either run or perform_work on its main thread. run may be called by multiple threads simultaneously.

   This operation will block until the ORB has completed the shutdown process, initiated when some thread calls shutdown.

   4.2.5.4 shutdown

   void shutdown(in boolean wait_for_completion);

   This operation instructs the ORB to shut down, that is, to stop processing in preparation for destruction.

   Shutting down the ORB causes all object adapters to be destroyed, since they cannot exist in the absence of an ORB.

   In the case of the POA, all POAManagers are deactivated prior to destruction of all POAs. The deactivation that the ORB performs should be the equivalent of calling deactivate with the value TRUE for etherealize_objects and with the wait_for_completion parameter same as what shutdown was called with.

   Shut down is complete when all ORB processing has completed and the object adapters have been destroyed. ORB processing is defined as including request processing and object deactivation or other operations associated with object adapters, and the forwarding of the responses from deferred synchronous invocations to their associated reply handlers. In the case of the POA, this means that all object etherealizations have finished and root POA has been destroyed (implying that all descendent POAs have also been destroyed)

   If the wait_for_completion parameter is TRUE, this operation blocks until the shut down is complete. If an application does this in a thread that is currently servicing an invocation, the ORB will not shutdown, and the BAD_INV_ORDER system exception will be raised with the OMG minor code 3, and completion status COMPLETED_NO, since blocking would result in a deadlock.

   If the wait_for_completion parameter is FALSE, then shutdown may not have completed upon return. An ORB implementation may require the application to call (or have a pending call to) run or perform_work after shutdown has been called with its parameter set to FALSE, in order to complete the shutdown process.

   Additionally in systems that have Portable Object Adapters (see Chapter 11) shutdown behaves as if POA::destroy is called on the Root POA with its first parameter set to TRUE and the second parameter set to the value of the wait_for_completion parameter that shutdown is invoked with.

   While the ORB is in the process of shutting down, the ORB operates as normal, servicing incoming and outgoing requests until all requests have been completed. An implementation may impose a time limit for requests to complete while a shutdown is pending.

   Once an ORB has shutdown, only object reference management operations(duplicate, release and is_nil) may be invoked on the ORB or any object reference obtained from it. An application may also invoke the destroy operation on the ORB itself. Invoking any other operation will raise the BAD_INV_ORDER system exception with the OMG minor code 4.

   4.2.5.5 destroy

   void destroy();

   This operation destroys the ORB so that its resources can be reclaimed by the application. Any operation invoked on a destroyed ORB reference will raise the OBJECT_NOT_EXIST exception. Once an ORB has been destroyed, another call to ORB_init with the same ORBid will return a reference to a newly constructed ORB.

   If destroy is called on an ORB that has not been shut down, it will start the shut down process and block until the ORB has shut down before it destroys the ORB. The behavior is similar to that achieved by calling shutdown with the wait_for_completion parameter set to TRUE. If an application calls destroy in a thread that is currently servicing an invocation, the BAD_INV_ORDER system exception will be raised with the OMG minor code 3, since blocking would result in a deadlock.

   For maximum portability and to avoid resource leaks, an application should always call shutdown and destroy on all ORB instances before exiting.