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>