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(a)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 */
--
1.4.4.2