gnustep-dev
[Top][All Lists]
Advanced

[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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]