Re: using select() without blocking the runloop


Jack Brindle
 

If file handlers were thread-specific you would not be able to read files on other threads. They are process-specific, not thread-specific.

At its core, select is very much synchronous. This haunted the Mac file system until the network folks started using KQueues to handle the descriptors. GCD made this much easier with dispatch sources based on KQueue elements. What I suspect you really want to do is to create a dispatch_source using DISPATCH_SOURCE_TYPE READ and DISPATCH_SOURCE_TYPE_WRITE. so that you don’t block, instead letting the system do the chore for you. Apple has some pretty good docs on this in their Dispatch guide. It is worth reading. They also have (or at least used to) an interesting sample source that demonstrates the use of various dispatch source features, done in command-line type programs. A search for it is definitely worth while.

This isn’t all that difficult to do, and if you really need to use select() is by far the best way to go.

- Jack

On Nov 24, 2017, at 1:36 AM, Roland King <rols@...> wrote:

yes of course file handles are thread-specific, you wouldn’t want random bits of code trying 0, 1, 2 … to see what it could get. Actually they are process-specific, but the process running your dispatch queue threads is not you and even if it was you the threads were probably created before you created the filehandles so it wouldn’t have inherited them.

the easiest way is to use a normal thread, start it, select on it, finish it again.

if you want to be properly dispatch_* about it, create a READ (or WRITE) dispatch source with the file descriptor and queue. Then add the handler block and resume it. To do the same thing the select() timeout does you can install a dispatch_after to cancel it again. It’s annoyingly more code but that’s how libdispatch supports filehandles natively. You could easily wrap that in a class and just use when required.

On 24 Nov 2017, at 16:57, Gerriet M. Denkmann <g@...> wrote:

I need to do select() with a rather large timeout value (several minutes).

So in order not to block the runLoop / mainThread I tried:

dispatch_queue_t myQueue = dispatch_get_global_queue( QOS_CLASS_BACKGROUND, 0 );
dispatch_async( myQueue, ^void(void)
{
selectResult = select(one_highest_fd, p_read_fds, p_write_fds, p_except_fds, ptv);
selectErrno = errno;
}
);

But I get EINVAL = Invalid argument.
Seems like file descriptors are thread specific.

How to do an asynchronous select() ?

Gerriet.





Join {cocoa@apple-dev.groups.io to automatically receive all group messages.