The nice thing about a single lock is once the local variable for that lock goes out of scope -- be it the function ends or (what's more important!) the function somehow crashes and you never unlock the critical section -- the class unlocks for you in its deconstructor.
So, instead of passing a handle around and what not, I would use a CCriticalSection as your base object and wrap it in a CSingleLock, which would take away the use of your wait for.
HTH
mohamed123
September 5th, 2005, 01:35 PM
hi thans for the reply
but the main problem i face is lack of understanding of
why we waitforsingleobject
i found out that when i
OnCapture();
MessageBox
OnCapture2();
the program works fine
but without messaage box or
OnCapture();
Sleep
OnCapture2();
the program crashes at dwResvoid CPreviewTestDlg::waitPreviewThread(HANDLE * m_hSemaphore)
{
DWORD dwRes;
// wait for the preview thread to stop
dwRes = WaitForSingleObject(*m_hSemaphore, 45000);
if (dwRes == WAIT_TIMEOUT)
{
AfxMessageBox(_T("Camera timed out."), MB_OK);
return;
}
}
My question isnt it allowed to access or waitforsingleobject twice ?
And why does it work when i use a messagebox , does messagebox clear something or does it give a delay ? Then why doesnt Sleep work
Regards
Mohamed
mohamed123
September 5th, 2005, 06:11 PM
hi
thanx for the reply
but i did not have problem when i call waitforsingleobject first time
it did not even give a compiler error
and
one more point
the code works when i use a message box between first and second call for waitforsingleobject the code works perfectly
one question does waitforsingleobject , makes the m_sem wait ??
and is i use releasesemaphore does this thread start again ??
regards
mohamed
Siddhartha
September 5th, 2005, 06:40 PM
but i did not have problem when i call waitforsingleobject first time
it did not even give a compiler errorPlease post your declaration of m_hSemaphore.
Compilation Success does not imply correct API usage.one question does waitforsingleobject , makes the m_sem wait ??Do you mean m_hSem??
WaitForSingleObject does not return till the state of the object is signaled. In that sense, WaitForSingleObject makes the current thread wait (and not any semaphore wait... Semaphore is an Event Object that can get signalled -- releasing the wait.)
is i use releasesemaphore does this thread start again ??ReleaseSemaphore will increment the Semaphore Usage count.
The semaphore will get signalled only when - The state of a semaphore is signaled when its count is greater than zero and nonsignaled when it is zero. The count is decreased by one whenever a wait function releases a thread that was waiting for the semaphore. The count is increased by a specified amount by calling the ReleaseSemaphore function. Also post your CreateSemaphore code...
mohamed123
September 5th, 2005, 06:57 PM
hi
heres where semaphore is created
void CPreviewTestDlg::SetPreview1()
{
// TODO: Add your control notification handler code here
RECT rc;
// initialize the VARIANT array to hold the preview data
// do it once with a large enough buffer so we don't waste
// time each preview
m_arPreview.CreateOneDim(VT_UI1, 65536);
// save the DC information for the preview window
// only need to do this once since it won't change
m_dcPreview = m_Preview.GetDC()->m_hDC;
m_Preview.GetClientRect(&rc);
m_nPreviewHeight = rc.bottom - rc.top;
m_nPreviewWidth = rc.right - rc.left;
// create a semaphore object to syncronize the preview thread
// with the main thread so we don't try to access the camera
// from two threads at the same time
m_hSem = CreateSemaphore(NULL, 1, 1, NULL);
// start the preview thread
m_pThread = AfxBeginThread(PreviewFunc, this);
}
Siddhartha
September 5th, 2005, 07:00 PM
I shall look into your code tomorrow... Its late night here, and actually I just realized that m_hSemaphore above is a pointer to a handle, and hence the WaitForSingleObject Statement is seemingly ok.
I'll reply tomorrow... If I do so now I might make mistakes. :)
In the meanwhile, please post as much code as you can... especially that pertaining to OnCapture and OnCapture2...
void CPreviewTestDlg::OnCapture2()
{
if(cam2Connected)
{
if(strName!="NOSELECTION") // unless a product id is selected picture cannot be taken
{
waitPreviewThread(&m_hSem2);
cam2Capture = TRUE;
cam2PicCounter++;
getFileName(cam2PicCounter);
GetDlgItem(IDC_BTNCAPTURE2)->EnableWindow(FALSE);
CaptureCam(1);
cam2Capture = FALSE;
// release the semaphore so the preview thread can start up again
ReleaseSemaphore(m_hSem2, 1, NULL);
}
else
{
MessageBox("No Product Id Selected","Product Id",MB_ICONEXCLAMATION);
GetDlgItem(IDC_BTNCAPTURE2)->EnableWindow(TRUE);
}
this is the code for oncapture
and the thing about
void CPreviewTestDlg::waitPreviewThread(HANDLE * m_hSemaphore);
i declare m_hSemaphore as pointer variable and pass the address of the m_hSem
regards
mohamed
Siddhartha
September 6th, 2005, 05:19 AM
[ code tags added ]
Regards,
Siddhartha
PS: Please post your code using Code Tags. Thank you.
Siddhartha
September 6th, 2005, 05:39 AM
Okay, answering the smaller questions before I get to the big-picture...
My question isnt it allowed to access or waitforsingleobject twice ?It is... You can call WaitForSingleObject as often as you like - so long as you have a valid HANDLE to wait on.
And why does it work when i use a messagebox , does messagebox clear something or does it give a delay ? Then why doesnt Sleep workThread behaviour is transient... Without seeing all the code, one cant say for sure.
What I can tell is that there is no direct connection between MessageBox and the Wait Functions or Semaphore.
Coming to the Semaphore creation code...
// create a semaphore object to syncronize the preview thread
// with the main thread so we don't try to access the camera
// from two threads at the same time
m_hSem = CreateSemaphore(NULL, 1, 1, NULL); You are creating a Semaphore with a count of 1.
This means that you only need a system that allows one thread to access a section of code at a time, am I right in my understanding?
If so, Semaphores are not the right objects for you... One would typically use Semaphore to ensure that a section of code is entered by N threads at a time. (N = 1) is sub-optimal.
CRITICAL SECTIONS (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/critical_section_objects.asp) are made for this. They are simple to use, and ensure that a piece of code is accessed one thread at a time.
When you answer the question above, I'll detail on using CRITICAL SECTIONS if need be.
mohamed123
September 6th, 2005, 06:39 AM
hi
your replies helped me understanding the semaphore better thanx
time line goes like this
OnCapture
- waitforsingleobject this would stop the preview thread
- capture - contacts camera and takes pic , when preview is paused
- releasesemaphore , starts the preview thread again
i do the same again
OnCapture
- waitforsingleobject this would stop the preview thread
- capture - contacts camera and takes pic , when preview is paused
- releasesemaphore , starts the preview thread again
but what happens is the second time during wait for single object the , wait is not returning
i have attached code as file for your reference
regards
mohamed
Siddhartha
September 6th, 2005, 07:45 AM
your replies helped me understanding the semaphore better thanxYou are welcome... :)
but what happens is the second time during wait for single object the , wait is not returningThis can happen only when you have taken a Semaphore (i.e. Waited on it...) but not released it later. So, the Semaphore remains non-Signaled, and all further waits on it are blocked.
Hence, please check all your code flows for this situation.
Now, I need a clarification - Initially you said that the WaitForSingleObject crashed on the second call.
Does it crash no more?
Remember that for WaitForSingleObject to work fine, the HANDLE to the semaphore m_hSem should be valid.
But, if you do a CloseHandle as in here -
void CPreviewTestDlg::OnPreview ()
{
// [...]
CloseHandle(m_hSem2);
} ...before calling WaitForSingleObject the second time, remember that you have sent an invalid HANDLE, and strange behaviour is to be expected.
You are also Closing the Handle in OnPreview2().
Use breakpoints to make sure that the HANDLE is not being closed before you use it again. i have attached code as file for your reference Yes, I looked into it... I see that you need to stop one thread, start another, etc - and whilst CRITICAL SECTIONS are not applicable - Events, IMO would be better suited.
There is only so much one can say / do without being able to debug... ;)
mohamed123
September 6th, 2005, 07:57 AM
hi
This can happen only when you have taken a Semaphore (i.e. Waited on it...) but not released it later. So, the Semaphore remains non-Signaled, and all further waits on it are blocked.
Hence, please check all your code flows for this situation.
Now, I need a clarification - Initially you said that the WaitForSingleObject crashed on the second call.
Does it crash no more?
Remember that for WaitForSingleObject to work fine, the HANDLE to the semaphore m_hSem should be valid.
the handle seems to be ok since i checked while debug and found the same address value as in first call . ( 0x00000b14 )
the it does return !!!
regards
mohamed
Siddhartha
September 6th, 2005, 08:00 AM
Please use Code-Tags, and please use Quote-Tags.
I don't relish the idea of doing this for you - for every post of yours... ;)
the handle seems to be ok since i checked while debug and found the same address value as in first call . ( 0x00000b14 ) You see, CloseHandle does not change the value of the handle... You can invalidate the HANDLE by calling CloseHandle (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/closehandle.asp) on it, and continue to use the same...
mohamed123
September 6th, 2005, 08:06 AM
hi
i dont closehandle any where during the process i check that and
when reduced the timeout time for waitforsingleobject
, it retunrs and says " Camera timed out"
does that mean the camera is not responding to second capture call ???
regards
mohamed
mohamed123
September 6th, 2005, 08:10 AM
but if use a messagebox inbetween
if (m_pThread)
{
MessageBox("test",NULL,MB_OK);
dwRes = WaitForSingleObject(m_hSem,10000);
}
works fine !!!!
Siddhartha
September 6th, 2005, 08:14 AM
i dont closehandle any where during the process i check that and
when reduced the timeout time for waitforsingleobject
, it retunrs and says " Camera timed out"
does that mean the camera is not responding to second capture call ???As neither your exe, nor your camera and your environment are in my posession - I am not in a position to hazard a guess.
What I can tell you is that you need a ReleaseSemaphore for every WaitForSingleObject, and if you timeout - I think, you still need to do a ReleaseSemaphore - something you are not doing.
Else, your Semaphore remains non-signaled forever... And subsequent waits will not return.
mohamed123
September 6th, 2005, 09:14 AM
hi
i just addedone more releasesemaphhore
between oncapture and oncapture2
and it worked
i think what u said about releasesemaphore was right
although i use releasesemaphore immly in oncapture
next time when i call oncapture the waitforsingleobject doesnt return strange!!!
BTW, a correct place for the ReleaseSemaphore might be here inside OnCapture -
if (dwRes == WAIT_TIMEOUT)
{
AfxMessageBox(_T("Camera timed out."), MB_OK);
ReleaseSemaphore (m_hSem);
return;
} Before the return.
Test it out...
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.