svn commit: r313043 - head/sys/kern

Hartmut.Brandt at dlr.de Hartmut.Brandt at dlr.de
Thu Feb 2 08:29:26 UTC 2017


To be honest - I feared that when I saw your messages regarding this. Here is my original message from july. Attached is also a small test program.

Hi,

I'm trying to use asio (that's boost::asio without boost) to handle listening sockets asynchronuosly. This appears not to work. There are also some reports on the net about this problem. I was able to reproduce the problem with a small C-programm that does the same steps as asio. The relevant sequence of system calls is:

kqueue()					 = 3 (0x3)
socket(PF_INET,SOCK_STREAM,6)			 = 4 (0x4)
setsockopt(0x4,0xffff,0x800,0x7fffffffea2c,0x4)	 = 0 (0x0)
kevent(3,{ 4,EVFILT_READ,EV_ADD|EV_CLEAR,0x0,0x0,0x0 4,EVFILT_WRITE,EV_ADD|EV_CLEAR,0x0,0x0,0x0 },2,0x0,0,0x0) = 0 (0x0)
setsockopt(0x4,0xffff,0x4,0x7fffffffea2c,0x4)	 = 0 (0x0)
bind(4,{ AF_INET 0.0.0.0:8080 },16)		 = 0 (0x0)
listen(0x4,0x80)				 = 0 (0x0)
ioctl(4,FIONBIO,0xffffea2c)			 = 0 (0x0)
kevent(3,{ 4,EVFILT_READ,EV_ADD|EV_CLEAR,0x0,0x0,0x0 4,EVFILT_WRITE,EV_ADD|EV_CLEAR,0x0,0x0,0x0 },2,0x0,0,0x0) = 0 (0x0)
kevent(3,0x0,0,0x7fffffffe5a0,32,0x0)		 ERR#4 'Interrupted system call'

The problem here is that asio registers each file descriptor with EVFILT_READ and EVFILT_WRITE as soon as it is opened (first kevent call). 
After bringing the socket into the listening state and when async_accept() is called it registers the socket a second time. According to the man page this is perfectly legal and can be used to modify the registration.

With this sequence of calls kevent() does not return when a connection is established successfully.

I tracked down the problem and the reason is in soo_kqfilter(). This is called for the first EVFILT_READ registration and decides based on the SO_ACCEPTCONN flag which filter operations to use solisten_filtops or soread_filtops. In this case it chooses soread_filtops.

The second EVFILT_READ registration does not call soo_kqfilter() again, but just updates the filter from the data and fflags field so the listening socket ends up with the wrong filter operations.



-----Original Message-----
From: Gleb Smirnoff [mailto:glebius at FreeBSD.org] 
Sent: Wednesday, February 01, 2017 7:08 PM
To: Hartmut Brandt
Cc: src-committers at freebsd.org; svn-src-all at freebsd.org; svn-src-head at freebsd.org
Subject: Re: svn commit: r313043 - head/sys/kern

On Wed, Feb 01, 2017 at 01:12:07PM +0000, Hartmut Brandt wrote:
H> Author: harti
H> Date: Wed Feb  1 13:12:07 2017
H> New Revision: 313043
H> URL: https://svnweb.freebsd.org/changeset/base/313043
H> 
H> Log:
H>   Merge filt_soread and filt_solisten and decide what to do when checking
H>   for EVFILT_READ at the point of the check not when the event is registers.
H>   This fixes a problem with asio when accepting a connection.
H>   
H>   Reviewed by:	kib@, Scott Mitchell

This goes into opposite direction with what I am doing:

https://reviews.freebsd.org/D9356

Can you please explain the problem with asio when accepting a connection?

-- 
Totus tuus, Glebius.

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: k.c
URL: <http://lists.freebsd.org/pipermail/svn-src-head/attachments/20170202/99114e8f/attachment.c>


More information about the svn-src-head mailing list