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. >
signature.asc
Description: PGP signature