ACE reactor demonstration
=========================

Martin Kolleck
Tino Riethmuller



1. Introduction

This program demonstrates what we think is a bug in the ACE library. The
affected component is the ACE_TP_Reactor. According to the documentation, the
reactor ensures that only one of the handle_*() methods of an event handler is
called at a time. Tino found this to be not true and I wrote this example
program showing the behavior. I do not exclude the possibility that we are
using the ACE library in an unintended/wrong way. So comments on the code as
well as any other remarks are welcome.



2. The program

The program consists of a client and a server. The general implementation is
taken from the example solution to exercise 4c of the ACE course. The client
will send a request to the server. This request is interpreted to be the size
of the following data. The server allocates the memory required to hold the
client's data and then sends a confirmation to the client, that it may
proceed. The the client sends the large data chunk and the server again
confirms it.

The client runs in a loop which can be configured to run indefinitely or a
previously set amount of times. The configuration i done from the command
line. To invoke the client type:

    $ ./client size [count]

<size> sets the size (in MiB) of the buffer sent to the server. Depending on
the systems, values between 60 and 100 have been used for testing. <count>
determines how often the buffer is sent. If left out, the clients send the
buffer until interrupted.

The server is started without arguments. Both programs will print a dot for
each successful connection. I found this an easy and unintrusive way of showing
progress whithout flooding the console too fast. This also makes it easier to
see when an error has occurred.



3. Building the program

This example was created on a Linux box. You will need the environment
variable ACE_ROOT set up to the location where ACE is installed. It might be
possible, that the path where the ACE libraries are found, needs to be adjusted
in the Makefile.

To compile simply type 'make' on the command prompt.

    $ make

This will create two executable files. One for the server and one for the
client. (named respectively)



4. Running the program

The error seems to be of statistical nature. Occurring only under certain
conditions (which I am not sure of, what they are). I successfully produced
the error on the four machines given below (architecture, ACE and compiler
version). I tested the program with localhost connections, as well as over
a real network connection and could always reproduce the error.

To detect the error I introduced a member variable to the read event handler.
This counter is initialized to zero in the constructor. When handle_input() of
the event handler is called, the counter is increased and decreased, when
handle_input() returns. Before increasing the counter, It is compared to zero
(which it should alway be, if only one invocation to handle_input() is made
at a time) and an error message is printed if it is not zero.

To test for the error, I ran one instance of the server program and TWO
instances of the client program. The sizes of the buffers were between 60 and
100 MiB and no count was given (running until stopped) The three Linux boxes
showed the error within one minute of starting both clients. For the Windows
box I decreased the buffer size to 15 and 20 MiB (Windows does not seem to have
very performant localhost connectivity) and it took about half an
hour until the error occurred the first time.
