Re: How to kill a camping kqueue thread? Was: close() hangs … in 10.5 only
Re: How to kill a camping kqueue thread? Was: close() hangs … in 10.5 only
- Subject: Re: How to kill a camping kqueue thread? Was: close() hangs … in 10.5 only
- From: Terry Lambert <email@hidden>
- Date: Fri, 20 Aug 2010 01:28:31 -0700
On Aug 20, 2010, at 12:43 AM, Steve Checkoway wrote:
> On Aug 19, 2010, at 22:56 , Jerry Krinock wrote:
>
>>
>> Thank you, Terry. Fortunately for my feeble brain the problem was none of the rocket science you explained, just this one:
>>
>> On 2010 Aug 16, at 17:38, Terry Lambert wrote:
>>> you have another thread camping out on the fd in kevent().
>>
>> Indeed, my app operates by creating a kqueue in the main thread with kevent(…,EV_ADD|EV_ENABLE,…), and then spinning off a new thread via -[NSThread detachNewThreadSelector:::]. The new thread camps out on kevent() in a loop like this:
>
> Why not have a timeout on the kevent? If kevent returns with a timeout, then check some state (for exmaple the isCancelled method of NSThread) and exit if appropriate. Otherwise, loop.
This is _a_ way, but your timeout would need to be tight to ensure that it was more or less responsive when you did the close. This would cause it to consume CPU cycles unnecessarily. I'm not sure how active the application is normally, so I have no idea if this would prevent power management, consume excessivle (relatively) CPU or could run opportunistically, etc..
Alternately, the NSThread in 10.5.x is based on a pthread, so you could do:
...
// volatile global
volatile pthread_t kqueue_thread;
...
// called within the thread before looping
kqueue_thread = pthread_self();
...
// called before the close
// I picked SIGUSR1, but you could use any signal for which you've
// established a handler, preferrably via sigaction(), without
// setting the SA_RESTART flag; this assumes the signal is
// otherwise unused; the point is to cause kevent() to return -1
// with an errno of EINTR, which you then check for when kevent()
// returns and pthread_exit() normally. The signal will only go
// to the specific thread.
if (kqueue_thread)
pthread_kill(kqueue_thread, SIGUSR1);
There's no guarantee that future versions of NSThread will be based on the same primitives, but you can be pretty sure that there's not going to be a change in that regard in a 10.5.x, so as long as you check your OS version at runtime before using this method, you should be fine, and it should be immediately responsive.
Technically, you could also subclass it as myNSThread so that you could access the tid member directly, and then add a method to kill it internally, but that's a lot of work for not a lot of benefit, since it's going to be 10.5 specific code anyway.
-- Terry _______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden