Thread synchronization problem #2

Hello

     I am facing a problem in sychronizing 2 threads. I do have 2 
classes (CPlayBuffer & CPlay) and 2 threads. CPlayBuffer will start from 
the main application. CPlay(Write into wave out device) thread will 
start from CPlayBuffer(read from the socket) thread. I am reserving 
5buffers. As soon as i get 5 buffers i am signalling an event to notify 
the play thread to start read from the buffer queue. I am maintaining a 
circular buffer. In that i am keeping write position, read position, 
filled buffer nos. I am using CRITICAL_SECTION to avoid overlapping of 
the variable between 2 threads. I tried CMutex also. Problem is that, 
once the play thread is signalled, the write thread is not executing. It 
is executing only after playing 5buffers. Meanwhile read is not 
happening only write into wave device is happening. There are 2 events. 
read event and write event. I am signalling it in GetNextDataBlock & 
PutNextDataBlcok. Can anybody point out me what i am doing wrong.?

CPlay
-----
// here i am reading from the buffer and write this buffer into out 
device. I am using double buffering method.
while (!bDoneLeft)
{
	if (playBuffer->IsReadSignalled())	
	 playBuffer->GetNextDataBlock(cLeftData);
	else
	bDoneLeft = rtpRead->WaitForReadEvent();				}

// waveout proc function
void CALLBACK CPlay::waveOutProc(HWAVEOUT , UINT uMsg, DWORD dwInstance, 
DWORD , DWORD )
{	
CPlay *play = (CPlay *)dwInstance;
if (uMsg == MM_WOM_DONE)
{
	CSingleLock sLock(&(play->mutex));
	sLock.Lock();
	SetEvent(play->hEvent[play->iLastPlayed]);
	sLock.Unlock();
}
return;
}

Play buffer
----------
// Read from the socket
while(!bWait)
{
bWait = IsWriteSignalled();
if (bWait)
   PutNextDataBlock(cBuff);
else
   WaitForWriteEvent();
}

void CPlayBuffer::IncrementReadPos()
{
	// increment the read position
	EnterCriticalSection(&csRead);
	if (iReadPos == (nBUFF - 1))
		iReadPos = 0;
	else
	   ++iReadPos;

	--iAvailBuffToRead;
	LeaveCriticalSection(&csRead);
return;
}

void CPlayBuffer::IncrementWritePos()
{
	// increment the write position
	EnterCriticalSection(&csWrite);
	if (iWritePos == (nBUFF - 1))
		iWritePos = 0;
	else
		++iWritePos;


	++iAvailBuffToRead;
	LeaveCriticalSection(&csWrite);
return;
}

void CPlayBuffer::GetNextDataBlock(LPVOID lpData)
{
	BOOL bReadSignalled = IsReadSignalled();
	if (bReadSignalled)
	{
		memcpy(lpData, &cPlayBuff[iReadPos], nBUFFSIZE);
		IncrementReadPos();
		if (iMinPlayBuff == nMINBUFF)
			iMinPlayBuff = 1;
	}

	int iAvailBuff = GetAvailableBuffer();
	if (iAvailBuff < iMinPlayBuff)
		ResetEvent(hReadEvt);

	// check write event.
	BOOL bWriteSignalled = IsWriteSignalled();
	if (iAvailBuff < nBUFF)
	{
		if (!bWriteSignalled)
			SetEvent(hWriteEvt);
	}
	else
	{
		if (bWriteSignalled)
			ResetEvent(hWriteEvt);
	}
return;
}

void CPlayBuffer::PutNextDataBlock(LPVOID lpData)
{
	BOOL bWriteSignalled = IsWriteSignalled();
	if (bWriteSignalled)
	{
		memcpy(cPlayBuff[iWritePos], lpData, nBUFFSIZE);
		IncrementWritePos();
	}
	int iAvailBuff = GetAvailableBuffer();
	
	if (iAvailBuff == nBUFF)
		ResetEvent(hWriteEvt);
	
	// check read event
	BOOL bReadSignalled = IsReadSignalled();
	
	if (iAvailBuff >= iMinPlayBuff)
	{
		if (!bReadSignalled)
		{
			SetEvent(hReadEvt);
		}
	}
	else
	{
		if (bReadSignalled)
		{
			ResetEvent(hReadEvt);
		}
	}
return;
}

Sreeram

0
10/4/2003 3:22:28 AM
vc.mfc 33608 articles. 0 followers. Follow

2 Replies
436 Views

Similar Articles

[PageSpeed] 10

Don't check for WriteSignalled. Just wait for it.

"Sreeram" <sreeram0425@netscape.net> wrote in message
news:OeQdIaiiDHA.1872@TK2MSFTNGP10.phx.gbl...
> Hello
>
>      I am facing a problem in sychronizing 2 threads. I do have 2
> classes (CPlayBuffer & CPlay) and 2 threads. CPlayBuffer will start from
> the main application. CPlay(Write into wave out device) thread will
> start from CPlayBuffer(read from the socket) thread. I am reserving
> 5buffers. As soon as i get 5 buffers i am signalling an event to notify
> the play thread to start read from the buffer queue. I am maintaining a
> circular buffer. In that i am keeping write position, read position,
> filled buffer nos. I am using CRITICAL_SECTION to avoid overlapping of
> the variable between 2 threads. I tried CMutex also. Problem is that,
> once the play thread is signalled, the write thread is not executing. It
> is executing only after playing 5buffers. Meanwhile read is not
> happening only write into wave device is happening. There are 2 events.
> read event and write event. I am signalling it in GetNextDataBlock &
> PutNextDataBlcok. Can anybody point out me what i am doing wrong.?
>
> CPlay
> -----
> // here i am reading from the buffer and write this buffer into out
> device. I am using double buffering method.
> while (!bDoneLeft)
> {
> if (playBuffer->IsReadSignalled())
> playBuffer->GetNextDataBlock(cLeftData);
> else
> bDoneLeft = rtpRead->WaitForReadEvent(); }
>
> // waveout proc function
> void CALLBACK CPlay::waveOutProc(HWAVEOUT , UINT uMsg, DWORD dwInstance,
> DWORD , DWORD )
> {
> CPlay *play = (CPlay *)dwInstance;
> if (uMsg == MM_WOM_DONE)
> {
> CSingleLock sLock(&(play->mutex));
> sLock.Lock();
> SetEvent(play->hEvent[play->iLastPlayed]);
> sLock.Unlock();
> }
> return;
> }
>
> Play buffer
> ----------
> // Read from the socket
> while(!bWait)
> {
> bWait = IsWriteSignalled();
> if (bWait)
>    PutNextDataBlock(cBuff);
> else
>    WaitForWriteEvent();
> }
>
> void CPlayBuffer::IncrementReadPos()
> {
> // increment the read position
> EnterCriticalSection(&csRead);
> if (iReadPos == (nBUFF - 1))
> iReadPos = 0;
> else
>    ++iReadPos;
>
> --iAvailBuffToRead;
> LeaveCriticalSection(&csRead);
> return;
> }
>
> void CPlayBuffer::IncrementWritePos()
> {
> // increment the write position
> EnterCriticalSection(&csWrite);
> if (iWritePos == (nBUFF - 1))
> iWritePos = 0;
> else
> ++iWritePos;
>
>
> ++iAvailBuffToRead;
> LeaveCriticalSection(&csWrite);
> return;
> }
>
> void CPlayBuffer::GetNextDataBlock(LPVOID lpData)
> {
> BOOL bReadSignalled = IsReadSignalled();
> if (bReadSignalled)
> {
> memcpy(lpData, &cPlayBuff[iReadPos], nBUFFSIZE);
> IncrementReadPos();
> if (iMinPlayBuff == nMINBUFF)
> iMinPlayBuff = 1;
> }
>
> int iAvailBuff = GetAvailableBuffer();
> if (iAvailBuff < iMinPlayBuff)
> ResetEvent(hReadEvt);
>
> // check write event.
> BOOL bWriteSignalled = IsWriteSignalled();
> if (iAvailBuff < nBUFF)
> {
> if (!bWriteSignalled)
> SetEvent(hWriteEvt);
> }
> else
> {
> if (bWriteSignalled)
> ResetEvent(hWriteEvt);
> }
> return;
> }
>
> void CPlayBuffer::PutNextDataBlock(LPVOID lpData)
> {
> BOOL bWriteSignalled = IsWriteSignalled();
> if (bWriteSignalled)
> {
> memcpy(cPlayBuff[iWritePos], lpData, nBUFFSIZE);
> IncrementWritePos();
> }
> int iAvailBuff = GetAvailableBuffer();
>
> if (iAvailBuff == nBUFF)
> ResetEvent(hWriteEvt);
>
> // check read event
> BOOL bReadSignalled = IsReadSignalled();
>
> if (iAvailBuff >= iMinPlayBuff)
> {
> if (!bReadSignalled)
> {
> SetEvent(hReadEvt);
> }
> }
> else
> {
> if (bReadSignalled)
> {
> ResetEvent(hReadEvt);
> }
> }
> return;
> }
>
> Sreeram
>


0
alegr (1131)
10/4/2003 4:48:18 AM
Hi Alex,

    Thanks again. But that did not solve my problem. Still the same 
result. I removed the hWriteEvent everywhere. But still the reading 
thread and writing thread is not executing parallely. This is an ActiveX 
OCX control and i am using CreateThread API to create the thread. Will 
that make any difference? I could not able to figure it out what is 
going wrong. Can you please advice me?

    Thanks
    Sreeram

Alexander Grigoriev wrote:
> Don't check for WriteSignalled. Just wait for it.
> 
> "Sreeram" <sreeram0425@netscape.net> wrote in message
> news:OeQdIaiiDHA.1872@TK2MSFTNGP10.phx.gbl...
> 
>>Hello
>>
>>     I am facing a problem in sychronizing 2 threads. I do have 2
>>classes (CPlayBuffer & CPlay) and 2 threads. CPlayBuffer will start from
>>the main application. CPlay(Write into wave out device) thread will
>>start from CPlayBuffer(read from the socket) thread. I am reserving
>>5buffers. As soon as i get 5 buffers i am signalling an event to notify
>>the play thread to start read from the buffer queue. I am maintaining a
>>circular buffer. In that i am keeping write position, read position,
>>filled buffer nos. I am using CRITICAL_SECTION to avoid overlapping of
>>the variable between 2 threads. I tried CMutex also. Problem is that,
>>once the play thread is signalled, the write thread is not executing. It
>>is executing only after playing 5buffers. Meanwhile read is not
>>happening only write into wave device is happening. There are 2 events.
>>read event and write event. I am signalling it in GetNextDataBlock &
>>PutNextDataBlcok. Can anybody point out me what i am doing wrong.?
>>
>>CPlay
>>-----
>>// here i am reading from the buffer and write this buffer into out
>>device. I am using double buffering method.
>>while (!bDoneLeft)
>>{
>>if (playBuffer->IsReadSignalled())
>>playBuffer->GetNextDataBlock(cLeftData);
>>else
>>bDoneLeft = rtpRead->WaitForReadEvent(); }
>>
>>// waveout proc function
>>void CALLBACK CPlay::waveOutProc(HWAVEOUT , UINT uMsg, DWORD dwInstance,
>>DWORD , DWORD )
>>{
>>CPlay *play = (CPlay *)dwInstance;
>>if (uMsg == MM_WOM_DONE)
>>{
>>CSingleLock sLock(&(play->mutex));
>>sLock.Lock();
>>SetEvent(play->hEvent[play->iLastPlayed]);
>>sLock.Unlock();
>>}
>>return;
>>}
>>
>>Play buffer
>>----------
>>// Read from the socket
>>while(!bWait)
>>{
>>bWait = IsWriteSignalled();
>>if (bWait)
>>   PutNextDataBlock(cBuff);
>>else
>>   WaitForWriteEvent();
>>}
>>
>>void CPlayBuffer::IncrementReadPos()
>>{
>>// increment the read position
>>EnterCriticalSection(&csRead);
>>if (iReadPos == (nBUFF - 1))
>>iReadPos = 0;
>>else
>>   ++iReadPos;
>>
>>--iAvailBuffToRead;
>>LeaveCriticalSection(&csRead);
>>return;
>>}
>>
>>void CPlayBuffer::IncrementWritePos()
>>{
>>// increment the write position
>>EnterCriticalSection(&csWrite);
>>if (iWritePos == (nBUFF - 1))
>>iWritePos = 0;
>>else
>>++iWritePos;
>>
>>
>>++iAvailBuffToRead;
>>LeaveCriticalSection(&csWrite);
>>return;
>>}
>>
>>void CPlayBuffer::GetNextDataBlock(LPVOID lpData)
>>{
>>BOOL bReadSignalled = IsReadSignalled();
>>if (bReadSignalled)
>>{
>>memcpy(lpData, &cPlayBuff[iReadPos], nBUFFSIZE);
>>IncrementReadPos();
>>if (iMinPlayBuff == nMINBUFF)
>>iMinPlayBuff = 1;
>>}
>>
>>int iAvailBuff = GetAvailableBuffer();
>>if (iAvailBuff < iMinPlayBuff)
>>ResetEvent(hReadEvt);
>>
>>// check write event.
>>BOOL bWriteSignalled = IsWriteSignalled();
>>if (iAvailBuff < nBUFF)
>>{
>>if (!bWriteSignalled)
>>SetEvent(hWriteEvt);
>>}
>>else
>>{
>>if (bWriteSignalled)
>>ResetEvent(hWriteEvt);
>>}
>>return;
>>}
>>
>>void CPlayBuffer::PutNextDataBlock(LPVOID lpData)
>>{
>>BOOL bWriteSignalled = IsWriteSignalled();
>>if (bWriteSignalled)
>>{
>>memcpy(cPlayBuff[iWritePos], lpData, nBUFFSIZE);
>>IncrementWritePos();
>>}
>>int iAvailBuff = GetAvailableBuffer();
>>
>>if (iAvailBuff == nBUFF)
>>ResetEvent(hWriteEvt);
>>
>>// check read event
>>BOOL bReadSignalled = IsReadSignalled();
>>
>>if (iAvailBuff >= iMinPlayBuff)
>>{
>>if (!bReadSignalled)
>>{
>>SetEvent(hReadEvt);
>>}
>>}
>>else
>>{
>>if (bReadSignalled)
>>{
>>ResetEvent(hReadEvt);
>>}
>>}
>>return;
>>}
>>
>>Sreeram
>>
> 
> 
> 

0
10/4/2003 5:50:21 AM
Reply:

Similar Artilces: