Skip to content

Commit

Permalink
winmm-thread branch was inadequately tested and needs more work. reve…
Browse files Browse the repository at this point in the history
…rted.

Revert "Merge branch 'winmm-thread'"

This reverts commit a6f53cd, reversing
changes made to b3c51b8.

Conflicts:

	src/cubeb_winmm.c
  • Loading branch information
kinetiknz committed Sep 26, 2011
1 parent 572c765 commit aa7e73c
Showing 1 changed file with 67 additions and 49 deletions.
116 changes: 67 additions & 49 deletions src/cubeb_winmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,20 @@

#define NBUFS 4

struct cubeb_stream_item {
SLIST_ENTRY head;
cubeb_stream * stream;
};

struct cubeb {
HANDLE event;
HANDLE thread;
unsigned int thread_id;
int shutdown;
PSLIST_HEADER work;
};

struct cubeb_stream {
cubeb * context;
cubeb_stream_params params;
cubeb_data_callback data_callback;
cubeb_state_callback state_callback;
Expand Down Expand Up @@ -109,55 +115,40 @@ cubeb_buffer_thread(void * user_ptr)
cubeb * ctx = (cubeb *) user_ptr;
assert(ctx);

/* force creation of thread's message queue. */
PeekMessage(NULL, NULL, 0, 0, PM_NOREMOVE);
SetEvent(ctx->event);

for (;;) {
DWORD rv;
struct cubeb_stream_item * item;

rv = WaitForSingleObject(ctx->event, INFINITE);
assert(rv == WAIT_OBJECT_0);

item = (struct cubeb_stream_item *) InterlockedPopEntrySList(ctx->work);
while (item) {
cubeb_stream * stm = item->stream;

EnterCriticalSection(&stm->lock);
stm->free_buffers += 1;
assert(stm->free_buffers > 0 && stm->free_buffers <= NBUFS);

rv = MsgWaitForMultipleObjects(1, &ctx->event, FALSE, INFINITE, QS_ALLEVENTS);
assert(rv == WAIT_OBJECT_0 || rv == WAIT_OBJECT_0 + 1);

if (rv == WAIT_OBJECT_0 + 1) {
MSG msg;
BOOL ok = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
assert(ok);
switch (msg.message) {
case MM_WOM_OPEN:
fprintf(stderr, "stream open\n");
break;
case MM_WOM_CLOSE:
fprintf(stderr, "stream close\n");
break;
case MM_WOM_DONE: {
cubeb_stream * stm = (cubeb_stream *)((WAVEHDR *) msg.lParam)->dwUser;
fprintf(stderr, "stream buffer done\n");

EnterCriticalSection(&stm->lock);
stm->free_buffers += 1;
assert(stm->free_buffers > 0 && stm->free_buffers <= NBUFS);

if (stm->draining || stm->shutdown) {
if (stm->free_buffers == NBUFS) {
if (stm->draining) {
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_DRAINED);
}
SetEvent(stm->event);
if (stm->draining || stm->shutdown) {
if (stm->free_buffers == NBUFS) {
if (stm->draining) {
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_DRAINED);
}
} else {
cubeb_submit_buffer(stm, cubeb_get_next_buffer(stm));
SetEvent(stm->event);
}
LeaveCriticalSection(&stm->lock);

break;
}
default:
fprintf(stderr, "weird message: %u\n", msg.message);
assert(0);
} else {
cubeb_submit_buffer(stm, cubeb_get_next_buffer(stm));
}
LeaveCriticalSection(&stm->lock);

_aligned_free(item);

item = (struct cubeb_stream_item *) InterlockedPopEntrySList(ctx->work);
}

assert(!InterlockedPopEntrySList(ctx->work));

if (ctx->shutdown) {
break;
}
Expand All @@ -166,6 +157,24 @@ cubeb_buffer_thread(void * user_ptr)
return 0;
}

static void CALLBACK
cubeb_buffer_callback(HWAVEOUT waveout, UINT msg, DWORD_PTR user_ptr, DWORD_PTR p1, DWORD_PTR p2)
{
cubeb_stream * stm = (cubeb_stream *) user_ptr;
struct cubeb_stream_item * item;

if (msg != WOM_DONE) {
return;
}

item = _aligned_malloc(sizeof(struct cubeb_stream_item), MEMORY_ALLOCATION_ALIGNMENT);
assert(item);
item->stream = stm;
InterlockedPushEntrySList(stm->context->work, &item->head);

SetEvent(stm->context->event);
}

int
cubeb_init(cubeb ** context, char const * context_name)
{
Expand All @@ -174,23 +183,24 @@ cubeb_init(cubeb ** context, char const * context_name)
ctx = calloc(1, sizeof(*ctx));
assert(ctx);

ctx->work = _aligned_malloc(sizeof(*ctx->work), MEMORY_ALLOCATION_ALIGNMENT);
assert(ctx->work);
InitializeSListHead(ctx->work);

ctx->event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!ctx->event) {
cubeb_destroy(ctx);
return CUBEB_ERROR;
}

ctx->thread = (HANDLE) _beginthreadex(NULL, 64 * 1024, cubeb_buffer_thread, ctx, 0, &ctx->thread_id);
ctx->thread = (HANDLE) _beginthreadex(NULL, 64 * 1024, cubeb_buffer_thread, ctx, 0, NULL);
if (!ctx->thread) {
cubeb_destroy(ctx);
return CUBEB_ERROR;
}

SetThreadPriority(ctx->thread, THREAD_PRIORITY_TIME_CRITICAL);

/* wait for thread to start; need thread message queue created before creating a stream. */
WaitForSingleObject(ctx->event, INFINITE);

*context = ctx;

return CUBEB_OK;
Expand All @@ -201,6 +211,8 @@ cubeb_destroy(cubeb * ctx)
{
DWORD rv;

assert(!InterlockedPopEntrySList(ctx->work));

if (ctx->thread) {
ctx->shutdown = 1;
SetEvent(ctx->event);
Expand All @@ -213,11 +225,13 @@ cubeb_destroy(cubeb * ctx)
CloseHandle(ctx->event);
}

_aligned_free(ctx->work);

free(ctx);
}

int
cubeb_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
cubeb_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name,
cubeb_stream_params stream_params, unsigned int latency,
cubeb_data_callback data_callback,
cubeb_state_callback state_callback,
Expand Down Expand Up @@ -268,6 +282,8 @@ cubeb_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
stm = calloc(1, sizeof(*stm));
assert(stm);

stm->context = context;

stm->params = stream_params;

stm->data_callback = data_callback;
Expand All @@ -285,7 +301,6 @@ cubeb_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
assert(stm->buffers[i].lpData);
stm->buffers[i].dwBufferLength = bufsz;
stm->buffers[i].dwFlags = 0;
stm->buffers[i].dwUser = (DWORD_PTR) stm;
}

InitializeCriticalSection(&stm->lock);
Expand All @@ -298,8 +313,11 @@ cubeb_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,

stm->free_buffers = NBUFS;

/* cubeb_buffer_callback will be called during waveOutOpen, so all
other initialization must be complete before calling it. */
r = waveOutOpen(&stm->waveout, WAVE_MAPPER, &wfx.Format,
(DWORD_PTR) NULL, (DWORD_PTR) ctx->thread_id, CALLBACK_THREAD);
(DWORD_PTR) cubeb_buffer_callback, (DWORD_PTR) stm,
CALLBACK_FUNCTION);
if (r != MMSYSERR_NOERROR) {
cubeb_stream_destroy(stm);
return CUBEB_ERROR;
Expand Down

0 comments on commit aa7e73c

Please sign in to comment.