gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

NSRunLoop Tidying


From: David Chisnall
Subject: NSRunLoop Tidying
Date: Fri, 8 Oct 2010 13:24:41 +0100

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?

David


reply via email to

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