[libdispatch-dev] Windows compatibility
Mark Heily
mark at heily.com
Fri Sep 25 20:25:01 PDT 2009
Robert N. M. Watson wrote:
>
> This is an interesting idea. My first thought was to look at whether
> pthreads + libevent would provide a reasonable foundation for a
> libnqkqueue ("not quite kqueue") wrapper library implementing (roughly)
> the kqueue interface on non-supporting systems. There are some problems
> with this idea, not least that libevent can't provided a unified event
> source for some of the types of events supported by kqueue. On the other
> hand, it would offer significantly more portability (at the cost of less
> efficiency and fewer capabilities).
APR and libevent aren't mutually exclusive. You could use APR to emulate
pthreads on Windows, and libevent to emulate kqueue(2) on non-BSD systems.
You might also want to look at a library I wrote called pnotify. This
provides a wrapper around BSD's kqueue and Linux's inotify to monitor
filesystem events. The website is here:
http://mark.heily.com/pnotify/
If portability to non-POSIX platforms is a goal, libevent doesn't provide
any emulation of pthreads, so you would need something like APR.
Regards,
- Mark
P.S. Here are my notes from examining libevent and APR and thinking about
the requirements of libdispatch. Hope this is helpful.
Requirements for portability
---
In order to support non-POSIX operating systems like MS Windows, libdispatch
needs to utilize the following operating system primitives in a portable way:
1. threads
2. mutexes
3. time functions; e.g. gettimeofday(2)
4. semaphores
5. threadsafe atomic operations
6. thread pools
Suitability of APR
---
APR is very well suited to writing portable applications.
1. threads
Supported.
See:
apr_thread_create()
2. mutexes
Supported.
See:
apr_thread_mutex_create()
apr_thread_mutex_lock()
apr_thread_mutex_unlock()
3. time functions; e.g. gettimeofday(2)
Supported.
See:
apr_time_now()
4. semaphores
Not supported directly; however, condition variables are supported
which may work. Semaphores are also trivial to implement as follows[1]:
sem_wait(...) {
if (apr_atomic_dec32 (&count) < 0)
apr_thread_mutex_lock (mutex);
}
sem_post(...) {
if ((apr_int32_t) apr_atomic_inc32 (&count) <= 0)
apr_thread_mutex_unlock (mutex);
}
[1] Credit to http://markmail.org/message/qqp7nni2gyltvyrd
5. threadsafe atomic operations
APR provides a wide range of atomic aperations.
See:
apr_atomic_inc32
apr_atomic_dec32
apr_atomic_cas32
6. thread pools
APR 1.3 provides a very sophisticated thread pool implementation.
See:
apr_thread_pool_create()
apr_thread_pool_push()
Suitability of libevent
---
libevent does not provide any abstractions for operating system
primitives.
=======================================================================
Requirements for dispatch sources
---
libdispatch needs to support the following dispatch sources:
1. socket readiness
2. signals
3. filesystem changes
4. timers
5. subprocess changes (fork, exit, etc.)
6. user-defined event sources
Suitability of APR
---
1. socket readiness
APR provides a generic polling mechanism that uses kqueue, epoll,
poll, select, or WSApoll.
See:
apr_pollset_add()
apr_pollset_remove()
apr_pollset_poll()
2. signals
APR allows you to setup a dedicated thread to perform signal handling.
This is generally better than using signal handlers, because it avoids
the need to add EINTR checks after every system call.
See:
apr_setup_signal_thread();
apr_signal_thread();
3. timers
Not supported.
One solution would be to have a dedicated timekeeper thread that
wakes up at regular intervals and generates timer events.
4. filesystem changes
Not supported.
One solution would be to have a dedicated filesystem event thread that
uses platform-specific facilities for monitoring filesystem events.
5. subprocess changes (fork, exit, etc.)
Not supported.
I'm not sure how this event source is useful.
6. user-defined event sources
This could be implemented in separate threads.
Suitability of libevent
---
1. socket readiness
libevent can uses kqueue, epoll, poll, select, or WSApoll.
See:
event_set()
event_add()
2. signals
signal handling is performed using a signal handler that writes to a
pipe that is monitored by poll(2) or the platform-specific alternative.
See:
signal_set()
signal_add()
3. timers
Timers are supported.
See:
evtimer_set()
evtimer_add()
4. filesystem changes
Not supported.
One solution would be to have a dedicated filesystem event thread that
uses platform-specific facilities for monitoring filesystem events.
A socketpair(2) would be needed to notify the event_dispatch() loop
of new events.
5. subprocess changes (fork, exit, etc.)
Not supported.
I'm not sure how this event source is useful.
6. user-defined event sources
This could be implemented in separate threads.
A socketpair(2) would be needed to notify the event_dispatch() loop
of new events.
More information about the libdispatch-dev
mailing list