<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">15 октября 2015 г., 23:55 пользователь Ivan Petrov <span dir="ltr"><<a href="mailto:i.petro.77.00@gmail.com" target="_blank">i.petro.77.00@gmail.com</a>></span> написал:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class=""><br>
> did you try to block inside an event loop callback?<br>
<br>
</span>основная идея - из калбаков AE не делать ничего кроме уведомлений.<br>
<br>
соответственно что нельзя делать<br>
- писать в Channel<br>
- трогать что угодно что может позвать cede/schedule<br></blockquote><div><br></div><div>Это понял. <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
то есть идеология такая<br>
<br>
- если пишем однократный ожидальщик то используем стандартный<br>
механизм Coro::rouse_*<br></blockquote><div><br></div><div>Не подходит, хотелось бы не однократно получать подключения по сети.<br> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
- если пишем многократный ожидальщик (например сервер), то лучше<br>
всего использовать совокупность schedule + ready<br></blockquote><br><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
то есть заводим<br>
<br>
my $watcher;<br>
my @tasks;<br>
<br>
<br>
sub do_task {<br>
тут можно создавать async, писать в каналы итп<br>
}<br>
<br>
async {<br>
while (1) {<br>
$watcher = $Coro::current;<br>
Coro::schedule;<br>
while(@tasks) {<br>
do_task(shift @tasks);<br>
}<br>
}<br>
};<br>
<br>
В калбеке приема соединения как-то так:<br>
<br>
sub {<br>
my ($fh) = @_;<br>
push @tasks => $fh;<br>
$watcher->ready if $watcher;<br>
$watcher->undef;<br>
<div class=""><div class="h5">}<br></div></div></blockquote><div><br>А вот тут я завис. <br><br><div>Вылетает с ошибкой DEADLOCK detected. <br></div><div>Зависает на Coro::schedule.<br><br></div>Переписал на Coro::Socket.<br>======================================<br>use Coro;<br>use Coro::Signal;<br>use Coro::AnyEvent;<br>use Coro::Handle;<br>use Coro::Socket;<br>use AnyEvent::Socket qw(tcp_server);<br><br><br>my @msg;<br>my $sem = Coro::Signal->new();<br>my $l = Coro::Socket->new( LocalPort => 2000, Listen => 1, ReuseAddr=>1 );<br>while () {<br> my $fh = $l->accept();<br> my $no = fileno $fh;<br> Coro::async {<br> while ( defined( my $line = $fh->readline ) ) {<br> chomp $line;<br> push @msg, "$no $line";<br> $sem->broadcast();<br> }<br> };<br> Coro::async {<br> my $i = @msg;<br> while () {<br> $sem->wait();<br> while ( $i < @msg ) {<br> my $id = (split " ", $msg[$i],2)[0];<br> $fh->print("$msg[$i]\n") if $id ne $no;<br> ++$i;<br> }<br> }<br> };<br>}<br>====================================<br><br></div><div>Т.е. проблему свою я решил, но не так гладко как хотелось. <br></div><div>Остался вопрос можно ли совместить обычные повторяющие колбэки с Coro, чтобы например <br>сервер написаный на голом AnyEvent использоватьс Coro без его переписывания к примеру tcp_server.<br><br></div><div>Есть ли рабочие примеры?<br></div><div><br><br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class=""><div class="h5">
--<br>
Moscow.pm mailing list<br>
<a href="mailto:moscow-pm@pm.org">moscow-pm@pm.org</a> | <a href="http://moscow.pm.org" rel="noreferrer" target="_blank">http://moscow.pm.org</a><br>
</div></div></blockquote></div><br></div></div>