in reply to Coro::Channel, worker thread and timeout

I havn't played much with AnyEvent, but from my experience with Glib and Gtk2 and threads, the way to go in a thread is to use an "idle" callback when calling something from a thread. So I looked at AnyEvent, and there is this in the README
# called when event loop idle (if applicable) my $w = AnyEvent->idle (cb => sub { ... }); my $w = AnyEvent->condvar; # stores whether a condition was fla +gged $w->send; # wake up current and all future recv's $w->recv; # enters "main loop" till $condvar gets ->send # use a condvar in callback mode: $w->cb (sub { $_[0]->recv });
I would try an play with those 2 methods.

I'm not really a human, but I play one on earth.
Old Perl Programmer Haiku ................... flash japh

Replies are listed 'Best First'.
Re^2: Coro::Channel, worker thread and timeout
by Anonymous Monk on Sep 13, 2011 at 05:13 UTC
    Thanks for your response. The AnyEvent->idle is definitely an interesting one to explore when you want invoke callbacks while your event becomes idle. Maybe I'm missing something, but I wasn't certain how it would relate to AnyEvent->timer though -- my understanding is that the watcher can legitimately go off when my event loop is doing tcp_connect (and it is taking a long time) -- and I wasn't certain how to have the Worker thread proceed onto the next host.
      my understanding is that the watcher can legitimately go off when my event loop is doing tcp_connect (and it is taking a long time)

      I don't know for sure how the AnyEvent timer works, but I know that a hung IO operation, as you describe will totally block a thread from running as expected, even signals won't make it in. My guess is the AnyEvent event-loop is being blocked by the hung IO operation, it just isn't getting any cpu time to function.

      I was just looking at a few modules that my be what you need, Async-Interrupt and EV-Loop-Async and [IO-Async-Loop-AnyEvent.

      Those modules put the eventloop in a separate thread, and it says somewhere in the README's that AnyEvent is a convenience module, for cases when you don't need the full power of EV and EV-Loop-Async.

      You could do something yourself manually, create a separate thread that won't be blocked by another thread's hung IO. Here is a crude example:

      #!/usr/bin/perl -w use strict; use threads; use threads::shared; my $timer_go:shared = 0; my $worker = threads->create(\&worker); my $timer = threads->create(\&timer,$worker); print "hit enter to start\n"; <>; $timer_go=1; <>; $timer->join(); $worker->join(); sub timer { my $worker = shift; while(1){ if($timer_go){ my $count = 0; while(1){ $count++; if($count > 5){ print "timed out\nHit enter to finish\n"; # Send a signal to a thread $worker->kill('INT'); return; } sleep 1; print "timing $count\n"; } }else{sleep 1} } } sub worker { $|++; $SIG{INT} = sub{ warn "Caught Zap!\n"; sleep 1; exit; }; my $worker_pid = open( READ, "top -d 1 -b |" ); print "\t$worker_pid\n"; while(<READ>){} return; }

      I'm not really a human, but I play one on earth.
      Old Perl Programmer Haiku ................... flash japh

        Actually, AnyEvent::Socket::tcp_connect is nonblocking, so other events can still fire while the connection is getting built.

        Wow, a lot of quality answers I was able to receive. You guys rock! >hung IO operation, as you describe will totally block a thread from running as expected, even signals won't make it in. This is true and I might be hitting this problem. Thank you for the tips on creating separate threads to avoid the hung IO. I am studying your example as I tried it on my box and it ran perfectly.