Does FreeBSD have sendmmsg or recvmmsg system calls?

Konstantin Belousov kib at kib.kiev.ua
Sat Jan 16 20:25:41 UTC 2016


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.
> 
> 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 you
> > kb> need it at all ?  Is it to correctly handle cancellation, to not fall
> > kb> into sleepable syscall when previous loop step was cancelled ?
> > Yes. I initially thought it was better to use the interposing table.
> > 
> > kb> If yes, you _can_ use pthread_testcancel(3) etc in libc.  Libc provides
> > kb> stubs for them with trivial implementation, which is reset to the real
> > 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 libc 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().
> 
> > 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.
> 
> > 
> > kb> Again, the patch lacks man page updates.
> > I'll try to write some soon.
> 
> 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.
> 
> I also discussed this with jilles@ who is our POSIX expert, and who
> confirmed my conclusion.
> 
> 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().


> 		error = __sys_recvmsg(...);
> 		if (error != 0)
> 			goto out;
> 		...
> 	}
> out:
> 	if (any data received)
> 		return (0);
> 	pthread_testcancel(); /* no data received, cancel us if requested */
> 	handle errors
> 	...
> 
> Patch to implement pthread_cancel_is_pending_np() is below.
> 
> 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.
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-net/attachments/20160116/cb717370/attachment.sig>


More information about the freebsd-net mailing list