Hi,
On Wed, May 15, 2002 at 05:28:04PM +0530, K S Sreeram wrote:
> Hi
>
> This time, i have submitted the problem with the PRF. I have also attached
> sample code illustrating the problem.
Thanks!
> SYNOPSIS:
> When a event handler is registered with ACE_Reactor
> (WRITE_MASK) for a TCP
> socket, the event_handler gets called only once. Further
> notifications do not happen.
>
> DESCRIPTION:
> I am trying to develop a single-threaded multiclient server, and hence i
> need to get notified when a socket is ready for writing, so that i dont get
> blocked on a write due to flow-control. The ACE_Reactor class does
> not notify
> event_handlers which are registered for the WRITE_MASK event more
> than once.
To be more accurate, it is the ACE_WFMO_Reactor (the default for
Windows configurations) that is not notifying more than once.
> The sample code that i have attached is a simple echo server, which has the
> above problem.
>
> Another point to be noted is that, this problem does not exist on linux
> RedHat Linux 7.2
> gcc 2.96
On Linux, the default reactor is the ACE_Select_Reactor. It's
underlying event demultiplexing mechanism is the select() system
call. Since select() will report the same events more than once as
long as that event is active you can just "block in the reactor" as
often as you'd like. The WFMO_Reactor, on the other hand, uses
Windows' WaitForMultipleObjects() as the underlying event
demultiplexing, which has a different set of semantics. In
particular, select() is a "state monitoring" interface and
WaitForMultipleObjects() is as far as I know a "state change"
interface.
So this really isn't a Linux vs. Windows issue, but a "state
monitoring" vs. "state change" interface issue. Linux's, /dev/epoll
event demultiplexing mechanism, for example, has the same problem as
WaitForMultipleObjects(). Events are only reported once per change in
state of the given event on the file descriptor. This means that you
must perform "speculative" reads/writes (i.e. keep reading/writing
until EWOULDBLOCK occurs) when using event demultiplexing mechanisms
with state change interfaces.
If you change the default reactor on windows to be the
ACE_Select_Reactor, do you still have the same problem? In
particular, try defining the following macro:
ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL
or:
ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL
I'm assuming that Windows' select() implementation retains the "state
monitoring" semantics found in Unix select() implementations.
Otherwise, you're stuck with "speculative" reads/writes. One other
alternative is that you can use the ACE_Reactor::schedule_wakeup() and
ACE_Reactor::cancel_wakeup() methods to force events to be reported
the next time around (assuming the event is active).
Note that the "speculative" reads/writes style of programming will
work with both "state monitoring" and "state change" event
demultiplexing mechanisms.
HTH,
-Ossama
--
Ossama Othman <ossama@...>
Distributed Object Computing Laboratory, Univ. of California at Irvine
1024D/F7A394A8 - 84ED AA0B 1203 99E4 1068 70E6 5EB7 5E71 F7A3 94A8