windows-nt/Source/XPSP1/NT/multimedia/media/mciseq/support.c
2020-09-26 16:20:57 +08:00

151 lines
3.2 KiB
C

/*******************************Module*Header*********************************\
* Module Name: support.c
*
* MultiMedia Systems MIDI Sequencer DLL
*
* Created: 27-Feb-1992
* Author: ROBINSP
*
* History:
*
* Copyright (c) 1985-1998 Microsoft Corporation
*
\******************************************************************************/
#define UNICODE
#include <windows.h>
#include <mmsystem.h>
#include <mmsys.h>
CRITICAL_SECTION CritSec;
CRITICAL_SECTION SeqCritSec;
//
// Cut-down critical section stuff
//
VOID InitCrit(VOID)
{
InitializeCriticalSection(&CritSec);
InitializeCriticalSection(&SeqCritSec);
}
VOID DeleteCrit(VOID)
{
DeleteCriticalSection(&CritSec);
DeleteCriticalSection(&SeqCritSec);
}
VOID EnterCrit(VOID)
{
EnterCriticalSection(&CritSec);
}
VOID LeaveCrit(VOID)
{
LeaveCriticalSection(&CritSec);
}
VOID EnterSeq(VOID)
{
EnterCriticalSection(&SeqCritSec);
}
VOID LeaveSeq(VOID)
{
LeaveCriticalSection(&SeqCritSec);
Sleep(4); // Give someone else a chance
}
/*************************************************************************
*
* @doc MCISEQ
*
* @func UINT | TaskBlock | This function blocks the current
* task context if its event count is 0.
*
* @rdesc Returns the message value of the signal sent.
*
************************************************************************/
UINT TaskBlock(VOID)
{
MSG msg;
LeaveSeq();
/*
* Loop until we get the message we want
*/
for (;;) {
/*
* Retrieve any message for task
*/
GetMessage(&msg, NULL, 0, 0);
/*
* If the message is for a window dispatch it
*/
if (msg.hwnd != NULL) {
DispatchMessage(&msg);
} else {
break;
}
}
EnterSeq();
return msg.message;
}
/*************************************************************************
*
* @doc MCISEQ
*
* @func BOOL | TaskSignal | This function signals the specified
* task, incrementing its event count and unblocking
* it.
*
* @parm DWORD | dwThreadId | Thread ID from <f mmGetCurrentTask>.
*
* @parm UINT | Msg | Signal message to send.
*
* @rdesc Returns TRUE if the signal was sent, else FALSE if the message
* queue was full.
*
* @xref mmTaskBlock mmTaskCreate
*
* @comm For predictable results, must only be called from a task
* created with <f mmTaskCreate>.
*
************************************************************************/
BOOL TaskSignal(DWORD dwThreadId, UINT Msg)
{
return PostThreadMessage(dwThreadId, Msg, 0, 0);
}
/*************************************************************************
*
* @doc MCISEQ
*
* @func VOID | TaskWaitComplete | This function waits for the
* specified task to terminate.
*
* @parm HANDLE | h | Task handle. For predictable results, get the
* task handle from <f mmGetCurrentTask>.
*
* @rdesc No return code
*
************************************************************************/
VOID TaskWaitComplete(HANDLE h)
{
LeaveSeq();
WaitForSingleObject(h, INFINITE); // Wait (no timeout) for thread to complete
CloseHandle(h);
// Note that the handle will be freed by thread itself.
EnterSeq();
}