This console application demonstrates the holding of buffers.
#include "stdafx.h"
#include "CircHoldSimple.h"
#include "BFErApi.h"
#include <queue>
#include <conio.h>
#include "DSapi.h"
#include "BFIOApi.h"
#include <iomanip>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CWinApp theApp;
UINT WorkerThread(LPVOID lpdwParam);
UINT WaitForFrameThread(LPVOID lpdwParam);
typedef struct _DataStruct
{
queue<BiCirHandle>* pBufferHandleQueue;
HANDLE* pNewHandleSemaphore;
HANDLE* pBufferQueueMutex;
}DataStruct;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
#if defined(_MSC_VER) && defined(_DEBUG)
AfxEnableMemoryLeakDump(false);
DispSurfAfxCrtWorkaround_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
if (!AfxWinInit(::GetModuleHandle(
BFNULL),
BFNULL, ::GetCommandLine(), 0))
{
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
BFU32 boardType, boardNum, init, serNum;
BFU32 cirSetupOptions = 0;
queue<BiCirHandle> BufferHandleQueue;
CWinThread* pWorkerThread;
CWinThread* pWaitFrameThread;
MSG Msg;
if( DoBrdOpenDialog(BOD_BRD_NUM_NON_FAMILY|BOD_HIDEJUSTOPEN,
FF_BITFLOW_MODERN, &boardType, &boardNum, &init, &serNum))
{
return -1;
}
cout << "Enter the number of buffers to allocate: ";
scanf_s("%d", &numBuffers);
HANDLE NewHandleSemaphore = CreateSemaphore(
BFNULL, 0, 0x7FFFFFFF,
BFNULL);
srand( (
unsigned)time(
BFNULL ) );
BFU32 randNum = (
BFU32)(numBuffers * rand() / (RAND_MAX + 1.0));
try
{
{
cout << "Couldn't create display surface" << endl;
CloseHandle(BufferQueueMutex);
CloseHandle(NewHandleSemaphore);
return 1;
}
cout << "\nHit any key to end application." << endl;
DataStruct data;
data.pBufferQueueMutex = &BufferQueueMutex;
data.pCirc = circ;
data.pBufferHandleQueue = &BufferHandleQueue;
data.phDspSrf = &hDspSrf;
data.pNewHandleSemaphore = &NewHandleSemaphore;
data.pThreadDone = &ThreadDone;
data.numBuffers = numBuffers;
pWorkerThread = AfxBeginThread(WorkerThread, (LPVOID)&data, THREAD_PRIORITY_NORMAL);
pWaitFrameThread = AfxBeginThread(WaitForFrameThread, (LPVOID)&data, THREAD_PRIORITY_NORMAL);
}
{
nRetCode = -1;
}
while(!BFkbhit() && !ThreadDone)
{
if(PeekMessage(&Msg,
BFNULL,0,0,PM_REMOVE))
DispatchMessage(&Msg);
else
Sleep(10);
}
ReleaseSemaphore(NewHandleSemaphore, 1,
BFNULL);
DWORD exitCode;
while(GetExitCodeThread(pWorkerThread->m_hThread, &exitCode) &&
exitCode == STILL_ACTIVE)
{
Sleep(10);
}
while(GetExitCodeThread(pWaitFrameThread->m_hThread, &exitCode) &&
exitCode == STILL_ACTIVE)
{
Sleep(10);
}
DispSurfClose(hDspSrf);
CloseHandle(BufferQueueMutex);
CloseHandle(NewHandleSemaphore);
delete circ;
if (BFkbhit())
BFgetch();
cout << "\nHit any key to continue." << endl;
while(!BFkbhit())
{
Sleep(1);
}
}
return nRetCode;
}
UINT WorkerThread(LPVOID lpdwParam)
{
DataStruct* pData = (DataStruct*)lpdwParam;
while(*pData->pThreadDone ==
FALSE)
{
WaitForSingleObject(*pData->pNewHandleSemaphore, INFINITE);
if(*pData->pThreadDone)
break;
WaitForSingleObject(pData->pBufferQueueMutex, INFINITE);
cirHandle = pData->pBufferHandleQueue->front();
pData->pBufferHandleQueue->pop();
ReleaseMutex(pData->pBufferQueueMutex);
try
{
if(!DispSurfFormatBlit(*pData->phDspSrf, cirHandle.pBufData,
{
cout << "Error displaying the held buffer." << endl;
*pData->pThreadDone =
TRUE;
}
}
{
*pData->pThreadDone =
TRUE;
}
}
return 0;
}
UINT WaitForFrameThread(LPVOID lpdwParam)
{
DataStruct* pData = (DataStruct*)lpdwParam;
srand( (
unsigned)time(
BFNULL ) );
BFU32 randNum = (
BFU32)(pData->numBuffers * rand() / (RAND_MAX + 1.0));
try
{
while(*pData->pThreadDone ==
FALSE)
{
rv = pData->pCirc->waitDoneFrame(INFINITE, &cirHandle);
{
BFU32 er = pData->pCirc->getCirError();
{
pData->pCirc->showError(er);
er = pData->pCirc->getCirError();
}
*pData->pThreadDone =
TRUE;
return -1;
}
if(cirHandle.BufferNumber == randNum)
{
rv = pData->pCirc->setBufferStatus(cirHandle,
BIHOLD);
{
WaitForSingleObject(*pData->pBufferQueueMutex, INFINITE);
pData->pBufferHandleQueue->push(cirHandle);
ReleaseMutex(*pData->pBufferQueueMutex);
ReleaseSemaphore(*pData->pNewHandleSemaphore, 1,
BFNULL);
}
else
{
}
randNum = (
BFU32)(pData->numBuffers * rand() / (RAND_MAX + 1.0));
}
else
{
}
cout << "Acquired Buffer = " << setw(8) << cirHandle.BufferNumber << "\r";
}
}
{
*pData->pThreadDone =
TRUE;
}
return 0;
}