Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 17 Jan 2016 22:38:10 +0100
From:      Jilles Tjoelker <jilles@stack.nl>
To:        Konstantin Belousov <kib@kib.kiev.ua>
Cc:        Boris Astardzhiev <boris.astardzhiev@gmail.com>, net@freebsd.org
Subject:   Re: Does FreeBSD have sendmmsg or recvmmsg system calls?
Message-ID:  <20160117213810.GA38279@stack.nl>
In-Reply-To: <20160117211853.GA37847@stack.nl>
References:  <20160108075815.3243.qmail@f5-external.bushwire.net> <CAJ-VmonYPhcN-gikuYQU_k5GaTAqTijoxR_0ORV4BZqsHMRJSg@mail.gmail.com> <20160108204606.G2420@besplex.bde.org> <CAJ-Vmom26mukSv3JmsmNiAONvpc6f1bQ%2BujO25qefGHY=5przA@mail.gmail.com> <CAP=KkTwG0SVUmrBuWm33EC-tG4tMTdF5rLZQ_u6G1=-ujnfjkA@mail.gmail.com> <20160113080349.GC72455@kib.kiev.ua> <CAP=KkTxVaqZvigg78Dg%2Bv8kuTCaZyky8x15NHqD9uabuRKRkMw@mail.gmail.com> <20160116195657.GJ3942@kib.kiev.ua> <20160116202534.GK3942@kib.kiev.ua> <20160117211853.GA37847@stack.nl>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, Jan 17, 2016 at 10:18:53PM +0100, Jilles Tjoelker wrote:
> On Sat, Jan 16, 2016 at 10:25:34PM +0200, Konstantin Belousov wrote:
> > On Sat, Jan 16, 2016 at 09:56:57PM +0200, Konstantin Belousov wrote:
> > > After thinking some more, I believe I managed to construct a possible
> > > way to implement this, in libc, with some libthr extensions.  Basically,
> > > the idea is to have function pthread_cancel_is_pending_np(), which
> > > would return the state of pending cancel.  For some time I thought that
> > > this cannot work, because cancellation could happen between call to
> > > the cancel_is_pending() and next recvmmsg().  But, libc has a privilege
> > > of having access to the syscalls without libthr interposing, just
> > > call __sys_recvmmsg(), which would give EINTR on the cancel attempt.
> > > This is an implementation detail, but we can rely on it in implementation.
> > > In other words, the structure of the code would be  like this
> > > 	for (i = 0; i < vlen; i++) {
> > > 		if (pthread_cancel_is_pending_np())
> > > 			goto out;
> > Right after writing the text and hitting send, I realized that the
> > pthread_cancel_is_pending_np() is not needed at all.  You get EINTR
> > from __sys_recvmsg() on the cancel attempt, so everything would just
> > work without the function.

> > The crusial part is to use __sys_recvmsg instead of interposable
> > _recvmsg().

> This will typically work (if the cancellation occurs while blocked
> inside __sys_recvmsg()) but has the usual problem of relying on [EINTR]:
> lost wakeups. This is certainly less bad than using the interposable
> recvmsg(), though, which would discard the already received data.

> As a slight modification, the first recvmsg could use the interposable
> version, since there is no pending data at that point. This avoids
> needing to call pthread_testcancel() manually.

> The regular cancellation code closes this race window using the
> undocumented thr_wake() system call, on the thread itself, in the signal
> handler for the cancellation signal. This causes the next attempt to
> sleep(9) to fail with [EINTR]. (On another note, it appears to be
> possible for user code (cleanup handlers and pthread_key_create()
> destructors) to be called with thr_wake() still active, if the
> cancellation signal handler is called immediately after the cancellation
> point system call returns.)

> The race in recvmmsg could be removed using this mechanism but it
> requires either a separate version of recvmmsg in libthr or a new
> interface in libthr. I imagine the new interface as a new cancellation
> type which causes cancellation point functions such as recvmsg() to fail
> with a new errno when cancelled while leaving cancellation pending. This
> seems conceptually possible but adds some code to the common path for
> cancellation points. A new version of pthread_testcancel() with a return
> value would be needed.

I realized that the above may be interpreted as requiring cancellation
to be completely fixed before recvmmsg/sendmmsg are "done". That is not
my intention. Given that cancellation is not commonly used in
applications, I think an approach based on __sys_recvmsg() is good
enough.

-- 
Jilles Tjoelker



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20160117213810.GA38279>