Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 16 Jan 2016 22:25:34 +0200
From:      Konstantin Belousov <kib@kib.kiev.ua>
To:        Boris Astardzhiev <boris.astardzhiev@gmail.com>
Cc:        jilles@freebsd.org, net@freebsd.org
Subject:   Re: Does FreeBSD have sendmmsg or recvmmsg system calls?
Message-ID:  <20160116202534.GK3942@kib.kiev.ua>
In-Reply-To: <20160116195657.GJ3942@kib.kiev.ua>
References:  <20160107192840.GF3625@kib.kiev.ua> <20160108172323.W1815@besplex.bde.org> <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>

next in thread | previous in thread | raw e-mail | index | archive | help

--MW5yreqqjyrRcusr
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Sat, Jan 16, 2016 at 09:56:57PM +0200, Konstantin Belousov wrote:
> I am sorry for delay in answering, you will see the reason for it below.
>=20
> On Fri, Jan 15, 2016 at 01:53:14PM +0200, Boris Astardzhiev wrote:
> > kb>Big issue with the implementation is the interposing stuff, why do y=
ou
> > kb> need it at all ?  Is it to correctly handle cancellation, to not fa=
ll
> > kb> into sleepable syscall when previous loop step was cancelled ?
> > Yes. I initially thought it was better to use the interposing table.
> >=20
> > kb> If yes, you _can_ use pthread_testcancel(3) etc in libc.  Libc prov=
ides
> > kb> stubs for them with trivial implementation, which is reset to the r=
eal
> > kb> one if libthr is loaded.  Then you can simplify your patch
> > significantly,
> > kb> avoiding the need for interposing and writing the loops both in lib=
c and
> > kb> libthr.
> > Got it. See patch. I think I removed the interposing stuff as
> > suggested. I didn't know about the stubs. But how for instance
> > pthread_testcancel() will cope with sleeping recvmmsg for example? I'm
> > not sure about the cancellation stuff here. Probably my approach is
> > not correct? I looked through lib/ for an example and only stumbled on
> > lib/libc/gen/sem.c where pthread_testcancel() is used but again I'm
> > not sure if I'm tackling it correctly in the calls.
> pthread_testcancel() does not need to do anything WRT sleeps in recvmsg.
> It adds the cancellation point, which you already have by the call
> to recvmsg().
>=20
> > kb> BTW, do you have tests for the cancellation of the new functions ?
> > Unfortunately no. Ideas and guidelines how to stress test the calls
> > regarding functionality
> > and especially cancellation?
> Write a test which would do controlled sendmmsg or recvmmsg in one
> thread, e.g. over the unix domain socket, and another thread doing
> cancellation.  You should check both async and deferred modes.
>=20
> >=20
> > kb> Again, the patch lacks man page updates.
> > I'll try to write some soon.
>=20
> So I thought how to implement the desired behaviour of the recvmmsg and
> recvmmsg loops WRT cancellation using sendmsg(2) and POSIX pthread API
> and realized that it is impossible. In other words, if you want to write
> a loop with several calls to say recvmsg and not cancel the loop if
> anything was already read by previous recvmsg calls, you cannot.
>=20
> I also discussed this with jilles@ who is our POSIX expert, and who
> confirmed my conclusion.
>=20
> 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 =3D 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
=66rom __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().


> 		error =3D __sys_recvmsg(...);
> 		if (error !=3D 0)
> 			goto out;
> 		...
> 	}
> out:
> 	if (any data received)
> 		return (0);
> 	pthread_testcancel(); /* no data received, cancel us if requested */
> 	handle errors
> 	...
>=20
> Patch to implement pthread_cancel_is_pending_np() is below.
>=20
> We have three viable strategies, after all
> 1. Ignore cancellation at all for now, since cancellation is not very
>    popular among apps.  This means that your latest, libc only patch
>    should be finalized.
> 2. Implement cancellation with libthr interposing, i.e. finalize your
>    libc + libthr patch.
> 3. Implement cancellation in libc as outlined above.
> It is your choice of the approach.
>=20

--MW5yreqqjyrRcusr
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQIcBAEBCAAGBQJWmqc9AAoJEJDCuSvBvK1BIWoQAJjgKugUrVqUCpQZ0iLcsxhC
R5o5x5H1iVbnYtTSUi8Pm1CnFCGjWOMpqg7ZTdkkH55R0UPNpy9jscxoLy5L3KOg
xs8OSL+EAvh/40UFJWrHRbC9jIbj9L4ecy50fONR3DeqAKs5NRwn+wCpqJbDFvL2
IQa94pAf7sS+B1wIjCSYrfJF3ENPnKaKi52X2F8OAdYe+VTarrz/4uxEeFmDrakp
ck2FhFnuMZYbNuBbehNfJTnz06BrKWggBpTQazybRiL1gjCUQKq/AHCISnj/7+Pd
3DE8UyKi27c5m0pid5lUw+P1BBcK6esi4tMrYpXx3gGTNrS9HZhx0VdXT3wv7Jno
aXrp9OLTgCWH88qIT+J7ShAV++1apBJy1FD6VzhDtYI2gSoVQEd/PFpqPPipUkjO
bF1MH9jkTpPEN77W89N5Iy+VlhSTqoYq2YF+pEIQuM9IWuycMQwpT2G2gP4MQTm7
htIG6R2C0CjBzOg98U9M0RxcEyjawZ84gRN84z4dP0uK7M16q4VAQhqzRpX9VDa5
YGD69+FR6/wxzNNzpWIPjOuutc8aKZTDB8JCNGFKi+uN8zAs/m2NneVng7MH3p8X
Q2DblUyBYZCuW6MvrnDSSc+WU+ll/1gxphUxetPtz6lgT/TmF1q7+dza2T9IbHRa
GFMKDFH4KI0HUbpVd+qs
=njNG
-----END PGP SIGNATURE-----

--MW5yreqqjyrRcusr--



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