Re: Using alarm(3) on background NSOperationQueue threads
Re: Using alarm(3) on background NSOperationQueue threads
- Subject: Re: Using alarm(3) on background NSOperationQueue threads
- From: Carl Hoefs <email@hidden>
- Date: Fri, 21 Aug 2015 12:58:43 -0700
> On Aug 20, 2015, at 5:55 PM, Ken Thomases <email@hidden> wrote:
>
> On Aug 20, 2015, at 7:29 PM, Carl Hoefs <email@hidden> wrote:
>>
>> From within a background NSOperationQueue thread, the effects of alarm(3) seem to be ignored. (I use alarm() to interrupt certain system calls like connect() when they stall.) The alarm fires, the alarm handler is invoked, but the ongoing sys call is not interrupted, as it would be normally. Is there something inherent in NSOperationQueue that would block the delivery of alarms? Is there another way to effect this?
>
> You can't do this safely. alarm() was effectively obsoleted as soon as multiple threads were introduced. alarm() causes a signal to be delivered to the process, not necessary the calling thread. It may interrupt some system call, but not necessarily the one you want it to. Also, attempts to use alarm() from multiple threads will supersede each other.
>
> You should set your sockets to be non-blocking, initiate the connect() which should return -1 and set errno to EINPROGRESS, and then use a file-descriptor-readiness-testing API to determine when the attempt has either succeeded or failed. One approach is to use kqueue with an appropriate time out on the kevent() call. That is a blocking approach.
>
> Another approach is to use dispatch sources. You'd create one for the socket and another for a timer. Whichever fires first tells you what happened and you should cancel the other. This is non-blocking. The thread can do other things or be returned to the pool and maybe exit and, when the relevant event occurs, a task will be queued to a queue.
>
> If you want to stop a connect attempt that was initiated this way due to the timeout expiring, close() the socket.
kqueue() works perfectly! (I never knew what OS X's equivalent to Linux's epoll() was.). Very nice. I was thinking of using select() instead, but kqueue() is more flexible and works for numerous system events.
Thanks for the sagely advice!
-Carl
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden