Hello POE experts,

I am just a bloody beginner with POE (though not with Perl),
and I would like to create an application which
- is steered via a GUI (Tk)
- should run lots of asynchronous/parallel stuff
- reports results/states etc via HTTP

However, when I try to start up both the Tk example and one of the
Web servers from the cookbook within one POE session
(code see attachment), the first HHTP request causes a POE crash,
with the output listed below.

Of course the standalone cookbook examples do work very well.
Any help/comment is appreciated.

I am using Perl 5.8.0 on Solaris, with PerlIO.

Best regards,

        Markus



        (in cleanup) whoops; no tk file io object at 
/vobs/eccs_dev_perl/perl_for_sixtyfive_characters_max_pathlength/prod/lib/site_p
erl/5.8.0/POE/Loop/Tk.pm line 242.
Tk::Error: fileno not same for read 6  and write 7 at 
/vobs/eccs_dev_perl/perl_for_sixtyfive_characters_max_pathlength/prod/lib/site_p
erl/5.8.0/sun4-solaris/Tk/Event/IO.pm line 115.
        (in cleanup) whoops; no tk file io object at 
/vobs/eccs_dev_perl/perl_for_sixtyfive_characters_max_pathlength/prod/lib/site_p
erl/5.8.0/POE/Loop/Tk.pm line 242.
 Tk::After::once at 
/vobs/eccs_dev_perl/perl_for_sixtyfive_characters_max_pathlength/prod/lib/site_p
erl/5.8.0/sun4-solaris/Tk/After.pm line 83
 [once,[{},after#21,0,once,[\&POE::Kernel::_loop_event_callback]]]
 ("after" script)
!!! Leaked fileno: 6 (total refcnt=1)
!!!     Read:
!!!             refcnt  = 0
!!!             ev cnt  = 0
!!!     Write:
!!!             refcnt  = 0
!!!             ev cnt  = 0
Not an ARRAY reference at 
/vobs/eccs_dev_perl/perl_for_sixtyfive_characters_max_pathlength/prod/lib/site_p
erl/5.8.0/POE/Kernel.pm line 934.


--
Markus Jansen                      Senior IS/IT Support Engineer, EED/IT
Ericsson Eurolab Deutschland GmbH  Email : [EMAIL PROTECTED]
Ericsson Allee 1                   Phone : +49 2407 575 5157
52134 Herzogenrath                 Fax   : +49 2407 575 7289
Germany                            Mobile: +49 172 274 2003

#! /vobs/eccs_dev_perl/perl_for_sixtyfive_characters_max_pathlength/prod/bin/perl -w

# http://poe.perl.org/?POE_Cookbook/Tk_Interfaces
#
# This sample program creates a very simple Tk counter.  Its interface
# consists of three widgets: A rapidly increasing counter, and a
# button to reset that counter.

use warnings;
use strict;

# Tk support is enabled if the Tk module is used before POE itself.

use Tk;
use POE;

use POE qw(Component::Server::TCP Filter::HTTPD);
use HTTP::Response;

# Spawn a web server on port 8088 of all interfaces.

POE::Component::Server::TCP->new
  ( Alias => "web_server",
    Port         => 8088,
    ClientFilter => 'POE::Filter::HTTPD',

    # The ClientInput function is called to deal with client input.
    # Because this server uses POE::Filter::HTTPD to parse input,
    # ClientInput will receive HTTP requests.

    ClientInput => sub {
        my ( $kernel, $heap, $request ) = @_[ KERNEL, HEAP, ARG0 ];

        # Filter::HTTPD sometimes generates HTTP::Response objects.
        # They indicate (and contain the response for) errors that occur
        # while parsing the client's HTTP request.  It's easiest to send
        # the responses as they are and finish up.

        if ( $request->isa("HTTP::Response") ) {
            $heap->{client}->put($request);
            $kernel->yield("shutdown");
            return;
        }

        # The request is real and fully formed.  Build content based on
        # it.  Insert your favorite template module here, or write your
        # own. :)

        my $request_fields = '';
        $request->headers()->scan
          ( sub {
                my ( $header, $value ) = @_;
                $request_fields .= "<tr><td>$header</td><td>$value</td></tr>";
              }
          );

        my $response = HTTP::Response->new(200);
        $response->push_header( 'Content-type', 'text/html' );
        $response->content
          ( "<html><head><title>Your Request</title></head>" .
              "<body>Details about your request:" .
              "<table border='1'>$request_fields</table>" .
              "</body></html>"
          );

        # Once the content has been built, send it back to the client
        # and schedule a shutdown.

        $heap->{client}->put($response);
        $kernel->yield("shutdown");
      }
  );



# Create the session that will drive the user interface.

POE::Session->create
  ( inline_states =>
      { _start => \&ui_start,
        ev_count => \&ui_count,
        ev_clear => \&ui_clear,
      }
  );

# Run the program until it is exited.

$poe_kernel->run();
exit 0;

# Create the user interface when the session starts.  This assumes
# some familiarity with Tk.  ui_start() illustrates four important
# points.
#
# 1. Tk events require a main window.  POE creates one for internal
# use and exports it as $poe_main_window.  ui_start() uses that as the
# basis for its user interface.
#
# 2. Widgets we need to work with later, such as the counter display,
# must be stored somewhere.  The heap is a convenient place for them.
#
# 3. Tk widgets expect callbacks in the form of coderefs.  The
# session's postback() method provides coderefs that post events when
# called.  The Button created in ui_start() fires an "ev_clear" event
# when it is pressed.
#
# 4. POE::Kernel methods such as yield(), post(), delay(), signal(),
# and select() (among others) work the same as they would without Tk.
# This feature makes it possible to write back end sessions that
# support multiple GUIs with a single code base.

sub ui_start {
    my ( $kernel, $session, $heap ) = @_[ KERNEL, SESSION, HEAP ];

    $poe_main_window->Label( -text => "Counter" )->pack;

    $heap->{counter_widget} =
      $poe_main_window->Label( -textvariable => \$heap->{counter} )->pack;

    $poe_main_window->Button
      ( -text => "Count",
        -command => $session->postback("ev_count")
      )->pack;

    $poe_main_window->Button
      ( -text => "Clear",
        -command => $session->postback("ev_clear")
      )->pack;

    # $kernel->yield("ev_count");
    $kernel->yield("ev_clear"); # display '0'
}

# Handle the "ev_count" event by increasing a counter and displaying
# its new value.

sub ui_count {
    $_[HEAP]->{counter}++;
    # $_[KERNEL]->yield("ev_count");
}

# Handle the "ev_clear" event by clearing and redisplaying the
# counter.

sub ui_clear {
    $_[HEAP]->{counter} = 0;
}

Reply via email to