Open wangvisual opened 1 week ago
Well… This looks like a valid fix, but it's unclear is it good idea to fix this at all - after all current behaviour helps you to find a bug (forgotten close() call).
I do not remember is Perl supports half-closed file handles. If yes, and you'll provide a test case which shows this issue in a real use-case then I agree this issue must be fixed. Such test might work this way:
agree, maybe just put a notice in the doc, that one have to close the stream once got EOF.
Well, it looks like Perl does support half-closed sockets: shutdown($socket, 0);
. This means it's valid to continue using socket after EOF, but probably you should somehow react on EOF - either with close
or with shutdown
.
In any case to make any changes (even doc fix) I need a code example which reproduces this issue. It let me test is proposed solutions (including shutdown()
) actually works. Doc fix sounds trivial, but we need to consider other possible use cases and consequences: e.g. how this will work with a chain of a plugins (which has their own sockets and thus shutdown for a top one might not fix CPU issue in a plugin, etc.).
One of my program has a bug, it forget to call close() after got EOF, then the program use 100% CPU, strace shows it continue to call read():
clock_gettime(CLOCK_MONOTONIC, {tv_sec=2453951, tv_nsec=921150570}) = 0 epoll_wait(4, [{EPOLLIN, {u32=17, u64=21474836497}}], 64, 3416) = 1 clock_gettime(CLOCK_MONOTONIC, {tv_sec=2453951, tv_nsec=921167046}) = 0 read(17, "", 8192) = 0 clock_gettime(CLOCK_MONOTONIC, {tv_sec=2453951, tv_nsec=921183697}) = 0 epoll_wait(4, [{EPOLLIN, {u32=17, u64=21474836497}}], 64, 3416) = 1 clock_gettime(CLOCK_MONOTONIC, {tv_sec=2453951, tv_nsec=921215171}) = 0 read(17, "", 8192) = 0 clock_gettime(CLOCK_MONOTONIC, {tv_sec=2453951, tv_nsec=921232568}) = 0 epoll_wait(4, [{EPOLLIN, {u32=17, u64=21474836497}}], 64, 3416) = 1 clock_gettime(CLOCK_MONOTONIC, {tv_sec=2453951, tv_nsec=921249128}) = 0 read(17, "", 8192) = 0 clock_gettime(CLOCK_MONOTONIC, {tv_sec=2453951, tv_nsec=921265710}) = 0 epoll_wait(4, [{EPOLLIN, {u32=17, u64=21474836497}}], 64, 3416) = 1 clock_gettime(CLOCK_MONOTONIC, {tv_sec=2453951, tv_nsec=921282208}) = 0
undef $self->{_r} can solve this issue: elsif (!$m->{is_eof}) { # EOF delivered only once $m->{is_eof} = 1; $m->EVENT(EOF); $self->{_r} = undef; # add this line }