Hi all,
Since I'm trying to improve on winmm's timing scheduling, the best improvement I can find is getting rid of the wineserver calls, they add a huge delay to the timer and that is bad for something that should sleep all the time to get better scheduling. I tried sending in a patch that used linux sockets but it was rejected.
Similar patches already do exist: winealsa and wineoss use them, some other sound drivers might use them too. Instead of duplicating that code everywhere I think it's better to add a generic implementation of it that can very easily be changed back to a win32 implementation.
What are your thoughts on this?
Maarten
fevent patch attached.
From 5e5cb0a326f51dc2edef245fcaab4a071f9e0c42 Mon Sep 17 00:00:00 2001
From: Maarten Lankhorst m.b.lankhorst@gmail.com Date: Sat, 12 May 2007 15:19:45 +0200 Subject: [PATCH] wine headers: introduce fevent interface
--- include/wine/fevent.h | 145 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 145 insertions(+), 0 deletions(-)
diff --git a/include/wine/fevent.h b/include/wine/fevent.h new file mode 100644 index 0000000..e80391d --- /dev/null +++ b/include/wine/fevent.h @@ -0,0 +1,145 @@ +/* + * Fast event interface + * Use this for when default wineserver calls are extremely bad for time critical usages + * This is also REALLY *ONLY* useful in case of 1 thread doing a 'WaitForSingleObject' + * else weird effects might occur. If someone wants to use this in any other way, results + * are undetermined. + * + * Copyright (C) 2007 Maarten Lankhorst + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINESRC__ +#error This should only be used internally +#endif + +#ifndef __WINE_WINE_FEVENT_H +#define __WINE_WINE_FEVENT_H + +#if (defined(HAVE_POLL_H) || defined(HAVE_SYS_POLL_H)) && !defined(WINE_FEVENT_USE_EVENT) + +#ifdef HAVE_POLL_H +#include <poll.h> +#endif +#ifdef HAVE_SYS_POLL_H +#include <sys/poll.h> +#endif + +#include <errno.h> + +WINE_DECLARE_DEBUG_CHANNEL(fevent); + +struct TAGfevent { + int fd[2]; + DWORD manreset; +}; + +typedef struct TAGfevent *FEVENT; + +static void reset_fd(FEVENT fev) +{ + char readme; + struct pollfd pfd; + pfd.fd = fev->fd[0]; + pfd.events = POLLIN; + while (poll(&pfd, 1, 0) > 0) + read(fev->fd[0], &readme, sizeof(readme)); +} + +static void set_fd(FEVENT fev) +{ + char foo = 'A'; + + write(fev->fd[1], &foo, sizeof(foo)); +} + +static FEVENT create_fd(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName) +{ + FEVENT fev = HeapAlloc(GetProcessHeap(), 0, sizeof(*fev)); + + if (!fev) + goto err; + + if (lpEventAttributes || lpName) + FIXME_(fevent)("FEVENTS are meant to be internal and shouldn't have security attributes or a name\n"); + + if (pipe(fev->fd) < 0) + { + fev->fd[0] = fev->fd[1] = -1; + goto err; + } + fev->manreset = bManualReset; + if (bInitialState) + set_fd(fev); + return fev; + + err: + if (fev) + { + close(fev->fd[0]); + close(fev->fd[1]); + HeapFree(GetProcessHeap(), 0, fev); + } + return NULL; +} + +static void close_fd(FEVENT fev) +{ + close(fev->fd[0]); + close(fev->fd[1]); + fev->fd[0] = fev->fd[1] = -1; + HeapFree(GetProcessHeap(), 0, fev); +} + +static DWORD poll_fd(FEVENT fev, DWORD timeout) +{ + int err; + struct pollfd pfd; + pfd.fd = fev->fd[0]; + pfd.events = POLLIN; + + while ((err = poll(&pfd, 1, (int)timeout)) == -1) + if (errno != EAGAIN && errno != EINTR) + break; + switch (err) + { + case 0: return WAIT_TIMEOUT; + case -1: return WAIT_FAILED; + default: + if (!fev->manreset) + reset_fd(fev); + return WAIT_OBJECT_0; + } +} + +#define RESETEVENT reset_fd +#define SETEVENT set_fd +#define CREATEEVENT create_fd +#define CLOSEEVENT close_fd +#define WAITEVENT poll_fd + +#else + +#define FEVENT HANDLE +#define RESETEVENT ResetEvent +#define SETEVENT SetEvent +#define CREATEEVENT CreateEventW +#define CLOSEEVENT CloseHandle +#define WAITEVENT WaitForSingleObject + +#endif + +#endif /* __WINE_WINE_FEVENT_H */