… | |
… | |
42 | } |
42 | } |
43 | |
43 | |
44 | my $connections = new Coro::Semaphore $MAX_CONNECTS; |
44 | my $connections = new Coro::Semaphore $MAX_CONNECTS; |
45 | |
45 | |
46 | my @fh; |
46 | my @fh; |
47 | my @pool; |
|
|
48 | |
47 | |
49 | sub handler { |
48 | # move the event main loop into a coroutine |
|
|
49 | async { loop }; |
|
|
50 | |
|
|
51 | slog 1, "accepting connections"; |
50 | while () { |
52 | while () { |
51 | my $fh = pop @fh; |
53 | $connections->down; |
52 | if ($fh) { |
54 | if (my $fh = $port->accept) { |
|
|
55 | #slog 3, "accepted @$connections ".scalar(@pool); |
|
|
56 | async_pool { |
53 | eval { |
57 | eval { |
54 | conn->new($fh)->handle; |
58 | conn->new($fh)->handle; |
55 | }; |
59 | }; |
56 | close $fh; |
60 | close $fh; |
57 | slog 1, "$@" if $@ && !ref $@; |
61 | slog 1, "$@" if $@ && !ref $@; |
58 | $connections->up; |
62 | $connections->up; |
59 | } else { |
|
|
60 | last if @pool >= $MAX_POOL; |
|
|
61 | push @pool, $Coro::current; |
|
|
62 | schedule; |
|
|
63 | } |
63 | }; |
64 | } |
64 | } |
65 | } |
|
|
66 | |
|
|
67 | # move the event main loop into a coroutine |
|
|
68 | async { loop }; |
|
|
69 | |
|
|
70 | slog 1, "accepting connections"; |
|
|
71 | while () { |
|
|
72 | $connections->down; |
|
|
73 | push @fh, $port->accept; |
|
|
74 | #slog 3, "accepted @$connections ".scalar(@pool); |
|
|
75 | if (@pool) { |
|
|
76 | (pop @pool)->ready; |
|
|
77 | } else { |
|
|
78 | async \&handler; |
|
|
79 | } |
|
|
80 | |
|
|
81 | } |
65 | } |
82 | |
66 | |
83 | package conn; |
67 | package conn; |
84 | |
68 | |
85 | use Socket; |
69 | use Socket; |