Robert Reif : wineesd: Use pipe sync for events.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Mar 14 12:04:30 CST 2006
Module: wine
Branch: refs/heads/master
Commit: 2d15c8fb75bcc124f0c0f3d6b92f12de5290e1e6
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=2d15c8fb75bcc124f0c0f3d6b92f12de5290e1e6
Author: Robert Reif <reif at earthlink.net>
Date: Tue Mar 14 07:28:53 2006 -0500
wineesd: Use pipe sync for events.
Ues pipe sync code from OSS/ALSA rather than windows events.
---
dlls/winmm/wineesd/audio.c | 55 +++++++++++++++++++++++++++++++++++++++-----
1 files changed, 49 insertions(+), 6 deletions(-)
diff --git a/dlls/winmm/wineesd/audio.c b/dlls/winmm/wineesd/audio.c
index 70ddf17..6bb035b 100644
--- a/dlls/winmm/wineesd/audio.c
+++ b/dlls/winmm/wineesd/audio.c
@@ -44,6 +44,13 @@
# include <unistd.h>
#endif
#include <fcntl.h>
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
+#ifdef HAVE_SYS_POLL_H
+# include <sys/poll.h>
+#endif
+
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
@@ -65,6 +72,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(wave);
#include <esd.h>
+/* unless someone makes a wineserver kernel module, Unix pipes are faster than win32 events */
+#define USE_PIPE_SYNC
+
/* define if you want to use esd_monitor_stream instead of
* esd_record_stream for waveIn stream
*/
@@ -105,6 +115,21 @@ enum win_wm_message {
WINE_WM_UPDATE, WINE_WM_BREAKLOOP, WINE_WM_CLOSING, WINE_WM_STARTING, WINE_WM_STOPPING
};
+#ifdef USE_PIPE_SYNC
+#define SIGNAL_OMR(mr) do { int x = 0; write((mr)->msg_pipe[1], &x, sizeof(x)); } while (0)
+#define CLEAR_OMR(mr) do { int x = 0; read((mr)->msg_pipe[0], &x, sizeof(x)); } while (0)
+#define RESET_OMR(mr) do { } while (0)
+#define WAIT_OMR(mr, sleep) \
+ do { struct pollfd pfd; pfd.fd = (mr)->msg_pipe[0]; \
+ pfd.events = POLLIN; poll(&pfd, 1, sleep); } while (0)
+#else
+#define SIGNAL_OMR(mr) do { SetEvent((mr)->msg_event); } while (0)
+#define CLEAR_OMR(mr) do { } while (0)
+#define RESET_OMR(mr) do { ResetEvent((mr)->msg_event); } while (0)
+#define WAIT_OMR(mr, sleep) \
+ do { WaitForSingleObject((mr)->msg_event, sleep); } while (0)
+#endif
+
typedef struct {
enum win_wm_message msg; /* message identifier */
DWORD param; /* parameter for this message */
@@ -121,7 +146,11 @@ typedef struct {
int ring_buffer_size;
int msg_tosave;
int msg_toget;
- HANDLE msg_event;
+#ifdef USE_PIPE_SYNC
+ int msg_pipe[2];
+#else
+ HANDLE msg_event;
+#endif
CRITICAL_SECTION msg_crst;
} ESD_MSG_RING;
@@ -508,7 +537,15 @@ static int ESD_InitRingMessage(ESD_MSG_R
{
mr->msg_toget = 0;
mr->msg_tosave = 0;
+#ifdef USE_PIPE_SYNC
+ if (pipe(mr->msg_pipe) < 0) {
+ mr->msg_pipe[0] = -1;
+ mr->msg_pipe[1] = -1;
+ ERR("could not create pipe, error=%s\n", strerror(errno));
+ }
+#else
mr->msg_event = CreateEventW(NULL, FALSE, FALSE, NULL);
+#endif
mr->ring_buffer_size = ESD_RING_BUFFER_INCREMENT;
mr->messages = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,mr->ring_buffer_size * sizeof(RING_MSG));
InitializeCriticalSection(&mr->msg_crst);
@@ -522,7 +559,12 @@ static int ESD_InitRingMessage(ESD_MSG_R
*/
static int ESD_DestroyRingMessage(ESD_MSG_RING* mr)
{
+#ifdef USE_PIPE_SYNC
+ close(mr->msg_pipe[0]);
+ close(mr->msg_pipe[1]);
+#else
CloseHandle(mr->msg_event);
+#endif
HeapFree(GetProcessHeap(),0,mr->messages);
mr->messages=NULL;
DeleteCriticalSection(&mr->msg_crst);
@@ -587,8 +629,8 @@ static int ESD_AddRingMessage(ESD_MSG_RI
LeaveCriticalSection(&mr->msg_crst);
- SetEvent(mr->msg_event); /* signal a new message */
-
+ /* signal a new message */
+ SIGNAL_OMR(mr);
if (wait)
{
/* wait for playback/record thread to have processed the message */
@@ -620,6 +662,7 @@ static int ESD_RetrieveRingMessage(ESD_M
*param = mr->messages[mr->msg_toget].param;
*hEvent = mr->messages[mr->msg_toget].hEvent;
mr->msg_toget = (mr->msg_toget + 1) % mr->ring_buffer_size;
+ CLEAR_OMR(mr);
LeaveCriticalSection(&mr->msg_crst);
return 1;
}
@@ -943,7 +986,7 @@ static void wodPlayer_Reset(WINE_WAVEOUT
wodNotifyClient(wwo, WOM_DONE, param, 0);
}
- ResetEvent(wwo->msgRing.msg_event);
+ RESET_OMR(&wwo->msgRing);
LeaveCriticalSection(&wwo->msgRing.msg_crst);
} else {
if (wwo->lpLoopPtr) {
@@ -1108,7 +1151,7 @@ static DWORD CALLBACK wodPlayer(LPVOID p
*/
dwSleepTime = min(dwNextFeedTime, dwNextNotifyTime);
TRACE("waiting %lums (%lu,%lu)\n", dwSleepTime, dwNextFeedTime, dwNextNotifyTime);
- WaitForSingleObject(wwo->msgRing.msg_event, dwSleepTime);
+ WAIT_OMR(&wwo->msgRing, dwSleepTime);
wodPlayer_ProcessMessages(wwo);
if (wwo->state == WINE_WS_PLAYING) {
dwNextFeedTime = wodPlayer_FeedDSP(wwo);
@@ -1696,7 +1739,7 @@ static DWORD CALLBACK widRecorder(LPVOID
}
/* wait for dwSleepTime or an event in thread's queue */
- WaitForSingleObject(wwi->msgRing.msg_event, dwSleepTime);
+ WAIT_OMR(&wwi->msgRing, dwSleepTime);
while (ESD_RetrieveRingMessage(&wwi->msgRing, &msg, ¶m, &ev))
{
More information about the wine-cvs
mailing list