This is a simple example of a peer-to-peer application that uses
nested function calls.

"Peer_impl" implements the "decrement" operation of the interface
"Peer" as follows: First, "inout long value" is printed, then
decremented. If the decremented value is larger than zero, the
"decrement" operation will be called on the object reference "in Peer
peer".

The process "peer1" must be started first. It creates a new
"Peer_impl", saves the IOR of this object in the file "Peer.ref" and
than enters the dispatch loop with "impl_is_ready". The "peer2"
process, which must be started next, creates a new "Peer_impl" (p2)
and loads the IOR of the "peer1" process (p1). The user can now enter
a number. With this number and the "p2" object reference as argument,
the "decrement" operation of the "p1" object reference is called
(which resides in process "peer1"). This operation will print the
passed value and then call the "decrement" operation of "p2" in the
"peer2" process. This will continue until the value is decremented to
zero. For example, if the user enters the number 3, the calling tree
looks like this:

Process Peer2             Process Peer1             Process Peer2
main()                    Reference p1              Reference p2

    |                          |                          |
    | p1 -> decrement(3, p2)   |                          |
    | -----------------------> |                          |
    |                          |                          |
    |                       prints 3                      |
    |                          |                          |
    |                          | p2 -> decrement(2, p1)   |
    |                          | -----------------------> |
    |                          |                          |
    |                          |                       prints 2
    |                          |                          |
    |                          |   p1 -> decrement(1, p2) |
    |                          | <----------------------- |
    |                          |                          |
    |                       prints 1                      |
    |                          |                          |
    |                          | return                   |
    |                          | -----------------------> |
    |                          |                          |
    |                          |                          |
    |                          |                          |
    |                          |                   return |
    |                          | <----------------------- |
    |                          |                          |
    |                          |                          |
    |                          |                          |
    |                   return |                          |
    | <----------------------- |                          |

As you can see, with ORBacus it is possible to make nested function
calls even if the functions are implemented in two different
processes. To use this feature, the following concurrency model
combination must be used:

	For the ORB:	For the BOA:
	threaded        thread per request


This can be done by either using the options -ORBthreaded and
-OAthread_per_request or by using the operations:

CORBA_ORB::thread_model(CORBA_ORB::ConcModelThreaded)
CORBA_BOA::thread_model(CORBA_BOA::ConcModelThreadPerRequest)

To start this demo under Unix, first run "peer1" with:

CLASSPATH=../../lib:classes:$CLASSPATH java nested.Peer1

And then "peer2" with:

CLASSPATH=../../lib:classes:$CLASSPATH java nested.Peer2

Under Windows, use:

set CLASSPATH=..\..\lib;classes;%CLASSPATH%
java nested.Peer1

And:

set CLASSPATH=..\..\lib;classes;%CLASSPATH%
java nested.Peer2

If you use the Microsoft Visual J++, use the command "jview" instead
of "java".
