async signal queue can miss events

Project:GNU Smalltalk
Component:VM
Category:bug
Priority:normal
Assigned:Unassigned
Status:fixed
Description

I had this once on a deployed image but can more easily reproduce it right now.

The symptom:
A Process is stuck reading from a socket while data is available.

$ netstat -np | grep gst
tcp 20 0 127.0.0.1:48944 127.0.0.1:3002 ESTABLISHED 21642/gst

This happens on this code:

Eval [

   1 to: 100 do:[:each | | socket |
       socket := Sockets.StreamSocket
           remote: 'localhost' port: 3002.
       socket next.
       socket close.
   ].

]

it occurs with 3.2.4+ from the stable-3.2 branch.

Updates

#1 submitted by Holger Hans Pet... on Tue, 08/28/2012 - 21:10

The 23:00 analysis... and hypothesis...

_gst_async_file_polling

1.) check for polling...
                             2.) new data arrives
3.) re-alloc
4.) set_filter_interrupt...

It has been some time bit SIGIO/fasync is just edge triggered? isn't it?

Strace with success:
socket(PF_INET, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_TCP) = 4
fcntl64(4, F_GETFL) = 0x2 (flags O_RDWR)
fcntl64(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0
connect(4, {sa_family=AF_INET, sin_port=htons(3002), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
poll([{fd=4, events=POLLOUT}], 1, 0) = 1 ([{fd=4, revents=POLLOUT}])
poll([{fd=4, events=POLLOUT}], 1, 0) = 1 ([{fd=4, revents=POLLOUT}])
getpeername(4, {sa_family=AF_INET, sin_port=htons(3002), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
poll([{fd=4, events=POLLIN}], 1, 0) = 1 ([{fd=4, revents=POLLIN}])
poll([{fd=4, events=POLLIN}], 1, 0) = 1 ([{fd=4, revents=POLLIN}])
poll([{fd=4, events=POLLIN}], 1, 0) = 1 ([{fd=4, revents=POLLIN}])
poll([{fd=4, events=POLLIN}], 1, 0) = 1 ([{fd=4, revents=POLLIN}])
recvfrom(4, "\0\21\376\4\1\10\1\7\1\2\1\3\1\4\1\5\1\1\1\0", 1024, 0, NULL, NULL) = 20
close(4)

Strace with failure:
socket(PF_INET, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_TCP) = 4
fcntl64(4, F_GETFL) = 0x2 (flags O_RDWR)
fcntl64(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0
connect(4, {sa_family=AF_INET, sin_port=htons(3002), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
poll([{fd=4, events=POLLOUT}], 1, 0) = 1 ([{fd=4, revents=POLLOUT}])
poll([{fd=4, events=POLLOUT}], 1, 0) = 1 ([{fd=4, revents=POLLOUT}])
getpeername(4, {sa_family=AF_INET, sin_port=htons(3002), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
poll([{fd=4, events=POLLIN}], 1, 0) = 0 (Timeout)
fcntl64(4, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl64(4, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC) = 0
fcntl64(4, F_SETOWN, 22087) = 0

User login