[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: NSRunLoop Tidying
From: |
Dr. H. Nikolaus Schaller |
Subject: |
Re: NSRunLoop Tidying |
Date: |
Fri, 8 Oct 2010 14:49:04 +0200 |
Am 08.10.2010 um 14:24 schrieb David Chisnall:
> Hi Everyone,
>
> One of the things that has been on my to-do list for a long time is tidying
> up NSRunLoop. The current implementation predates modern event delivery
> mechanisms and tries to shoe-horn the UNIX approach everywhere.
>
> Modern systems include a unified mechanism for event delivery, and a lot of
> the hacks to work around the fact that older *NIX systems didn't have these
> are complicating the code a lot on these platforms.
>
> My main motivation for doing this is to support the KQueue APIs on *BSD.
> This provides a single function for waiting on every kind of event. Windows
> has had something similar forever, Linux can do the same thing with timerfd
> in recent versions, and Solaris has completion ports, which provide similar
> functionality.
>
> As I understand it, there are four kinds of things that a runloop has to
> handle:
>
> 1) Events on a file descriptor (read / write).
> 2) Timers expiring.
> 3) Timeout expiring (e.g. -runMode:beforeDate:)
> 4) Messages from threads.
>
> Of these, (3) is trivial. All wait mechanisms support this, so implementing
> it is trivial with any underlying mechanism. Similarly, (1) is the default
> case for pretty much all of the event-waiting calls, so it's simple.
>
> Currently, (2) is implemented in terms of (3). This is quite untidy. It
> means that we need to maintain an ordered list of timers in the runloop code,
> find the one closest to the present, and then use this as the timeout. This
> is required with traditional select() and poll(), but Win32 has SetTimer,
> Linux has timerfd(), and *BSD has kevent(), all of which allow you to
> schedule timer events and wait on them just like fd events.
>
> (4) is trivial on Windows, via PostThreadMessage(), which allows you to
> deliver a message to a specific thread. Kqueue has a EVFILT_USER, which
> allows you to deliver events to other threads, and Solaris 10 event ports
> have something similar.
>
> To properly support efficient native APIs, we should move the handling of all
> of these into the per-platform code and remove anything platform-specific
> from the general code in -base. There are lots of random #ifdefs scattered
> about the place currently.
>
> My overall plan is:
>
> - Move -addTimer:forMode: into the platform-specific code.
> - Tidy up the GSRunLoopCtx stuff so it isn't quite so full of #ifdefs.
> - Make the NSObject methods in NSThread.m call (private) runloop methods that
> delegate to the platform-specific code.
> - Remove classes like GSPerformHolder from the generic code.
> - Implement a kqueue back end for *BSD.
> - Make the win32 back end use SetTimer() and PostThreadMessage().
>
> Comments / suggestions?
Two aspects come to my mind that I think you have to consider:
a) keep semantics of:
-[NSRunLoop acceptInputForMode:beforeDate:]
-[NSRunLoop limitDateForMode:]
So I think you still need the sorted list of timers.
b) API
It could be helpful to use the CFRunLoop API between "Frontend" and
"Platform-Specific".
There may already be open source implementations in CFLite and PureDarwin.
BR,
Nikolaus