This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: losing events with EPOLLONESHOT and cancellation


On 12/06/13 18:56, Eric Wong wrote:
Thanks.  With pthread_cleanup_*, I can't see the return value of the
cancelled syscall.  So I think my alternative is to not rely on normal
syscalls being cancellable and explicitly put cancellation points in my
program around interruptible syscalls, using pthread_kill in a loop in
addition to pthread_cancel.

Something like this:

thread_1
--------
pthread_cancel(thread_2);

/*
  * trigger EINTR in any interruptible syscall
  * the loop seems icky, but this will be a rare code path
  */
while (pthread_kill(thread_2, ...) == 0)
	sched_yield();

thread_2
--------

pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

for (;;) {
	/* open a brief window for async cancellation */
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);

	/*
	 * We could lose cancellation requests here, so we loop in thread_1.
	 * I also have a similar loop doing blocking accept4 in a
	 * different thread.
	 */
	rc = epoll_wait(...);

	if (rc<  0&&  errno == EINTR) {
		/* open a brief window for async cancellation */
		pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
	}
	...
}
If you need to explicitely mark like that the points where you want to accept cancellation, I would probably find clearer a if (cancel_thread2) pthread_exit();

(and instead of pthread_cancel(thread_2); you would set to true the volatile
cancel_thread2 variable). But that should be equivalent. If you prefer that way,
it's up to the programmer.


Also note that you probably want to continue the for in the EINTR case, so you
don't need to copy the pthread_setcancelstate(), as continuing will hit them.

Regards




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]