Port to Windows. This is mostly glue layers for the poor POSIX support

on Windows. A few notes

 * Only sockets behave somewhat like file descriptors in UNIX.

 * There are no fixed paths. Closes thing is environment variables that point
   to system directories. We also figure out where the binary/dll is
   located and use that as configuration directory.


git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/ossman@418 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
Pierre Ossman 2006-01-05 22:51:37 +00:00
parent 2f74bb9d43
commit 19d9fcbda8
22 changed files with 712 additions and 58 deletions

View file

@ -32,6 +32,10 @@
#include <unistd.h>
#include <fcntl.h>
#ifdef HAVE_WINDOWS_H
#include <windows.h>
#endif
#include "mainloop-signal.h"
#include "util.h"
#include "xmalloc.h"
@ -53,19 +57,70 @@ struct pa_signal_event {
static struct pa_mainloop_api *api = NULL;
static int signal_pipe[2] = { -1, -1 };
static struct pa_io_event* io_event = NULL;
static struct pa_defer_event *defer_event = NULL;
static struct pa_signal_event *signals = NULL;
#ifdef OS_IS_WIN32
static unsigned int waiting_signals = 0;
static CRITICAL_SECTION crit;
#endif
static void signal_handler(int sig) {
#ifndef HAVE_SIGACTION
signal(sig, signal_handler);
#endif
write(signal_pipe[1], &sig, sizeof(sig));
#ifdef OS_IS_WIN32
EnterCriticalSection(&crit);
waiting_signals++;
LeaveCriticalSection(&crit);
#endif
}
static void dispatch(struct pa_mainloop_api*a, int sig) {
struct pa_signal_event*s;
for (s = signals; s; s = s->next)
if (s->sig == sig) {
assert(s->callback);
s->callback(a, s, sig, s->userdata);
break;
}
}
static void defer(struct pa_mainloop_api*a, struct pa_defer_event*e, void *userdata) {
ssize_t r;
int sig;
unsigned int sigs;
#ifdef OS_IS_WIN32
EnterCriticalSection(&crit);
sigs = waiting_signals;
waiting_signals = 0;
LeaveCriticalSection(&crit);
#endif
while (sigs) {
if ((r = read(signal_pipe[0], &sig, sizeof(sig))) < 0) {
pa_log(__FILE__": read(): %s\n", strerror(errno));
return;
}
if (r != sizeof(sig)) {
pa_log(__FILE__": short read()\n");
return;
}
dispatch(a, sig);
sigs--;
}
}
static void callback(struct pa_mainloop_api*a, struct pa_io_event*e, int fd, enum pa_io_event_flags f, void *userdata) {
ssize_t r;
int sig;
struct pa_signal_event*s;
assert(a && e && f == PA_IO_EVENT_INPUT && e == io_event && fd == signal_pipe[0]);
@ -81,19 +136,18 @@ static void callback(struct pa_mainloop_api*a, struct pa_io_event*e, int fd, enu
pa_log(__FILE__": short read()\n");
return;
}
for (s = signals; s; s = s->next)
if (s->sig == sig) {
assert(s->callback);
s->callback(a, s, sig, s->userdata);
break;
}
dispatch(a, sig);
}
int pa_signal_init(struct pa_mainloop_api *a) {
assert(!api && a && signal_pipe[0] == -1 && signal_pipe[1] == -1 && !io_event);
assert(!api && a && signal_pipe[0] == -1 && signal_pipe[1] == -1 && !io_event && !defer_event);
#ifdef OS_IS_WIN32
if (_pipe(signal_pipe, 200, _O_BINARY) < 0) {
#else
if (pipe(signal_pipe) < 0) {
#endif
pa_log(__FILE__": pipe() failed: %s\n", strerror(errno));
return -1;
}
@ -104,20 +158,36 @@ int pa_signal_init(struct pa_mainloop_api *a) {
pa_fd_set_cloexec(signal_pipe[1], 1);
api = a;
#ifndef OS_IS_WIN32
io_event = api->io_new(api, signal_pipe[0], PA_IO_EVENT_INPUT, callback, NULL);
assert(io_event);
#else
defer_event = api->defer_new(api, defer, NULL);
assert(defer_event);
InitializeCriticalSection(&crit);
#endif
return 0;
}
void pa_signal_done(void) {
assert(api && signal_pipe[0] >= 0 && signal_pipe[1] >= 0 && io_event);
assert(api && signal_pipe[0] >= 0 && signal_pipe[1] >= 0 && (io_event || defer_event));
while (signals)
pa_signal_free(signals);
#ifndef OS_IS_WIN32
api->io_free(io_event);
io_event = NULL;
#else
api->defer_free(defer_event);
defer_event = NULL;
DeleteCriticalSection(&crit);
#endif
close(signal_pipe[0]);
close(signal_pipe[1]);