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