On Wed, Sep 05, 2001 at 11:03:47AM +0200, jotham wrote:
> I am not at all certain how to handle Posts to sessions that no longer
> exist.  I mean, they exist at the time of the Post, but die before the post
> is received.  Can someone explain how to handle this?  I notice in the
> 'tutorial chat' example the author mentions; "With post, you get situations
> where the event is delivered after the user's wheel is gone, leading to
> runtime errors when the session tries to send the message"

The chat tutorial is abusing call() to simplify its design.  That
comment is misleading: the program stops working correctly when it
uses post(), but no runtime error messages are generated.

The problem occurs as an interaction between the "hear" state
(&chat_heard), the "line_input" state (&chat_input),the &say function,
the chat sessions' shutdown flag, and the "out_flushed" state
(&chat_flush).

As it stands now, when &say uses call(), other users' "hear" states
are called immediately when messages are generated:

  Client types "/quit".
  &chat_input calls &say to multiplex the quit message.
  &say calls &chat_heard for all sessions and returns.
  &chat_heard enqueues the quit message for flushing to clients.
  &chat_heard returns.
  &chat_input sets the session_is_shutting_down flag.
  &chat_input returns.

When it's post() instead, the call to &chat_heard is delayed:

  Client types "/quit".
  &chat_input calls &say to multiplex the quit message.
  &say enqueues "hear" events for all sessions and returns.
  &chat_input sets the session_is_shutting_down flag.
  &chat_input returns.
  &chat_heard states are called when "hear" events are dispatched.

Sessions aren't really stopped until &chat_flush is called.  This
gives them the opportunity to flush any waiting output (the quit
message) before they go away.

However, one of the roles of the shutdown flag is to stop I/O after
the user types "/quit".  In the post() version of &say, the shutdown
flag is set before the quitting session's &chat_heard is called.

So the quitting session never sends the quit message to its client,
&chat_flush is never called, and the client doesn't disconnect.

Switching post() to call() clears up that race condition.  It probably
isn't the best solution, but it was the most expedient.

-- Rocco Caputo / [EMAIL PROTECTED] / poe.perl.org / poe.sourceforge.net

  • Post jotham
    • Rocco Caputo

Reply via email to