>> if(ReleaseSemaphore(egg_sem, 1, 0) == NULL)
ReleaseSemaphore() returns BOOL, so compare with TRUE or FALSE.
>> ReleaseSemaphore(egg_sem, 1, 0);
Now you've called it twice, incrementing the semaphore's count again.
You create a Win32 semaphore with an initial count. This count basicly represents the number of times WaitForSingleObject() can be called before it blocks. Each time WaitForSingleObject() is called, the count on the semaphore is decremented. If this count is zero then WaitForSingleObject() will block until the count is incremented (releasing a single thread waiting on the semaphore). You call ReleaseSemaphore() to increment the count.
Here's another simple example:
Code:
#include <windows.h>
#include <iostream>
using namespace std;
HANDLE g_sema;
DWORD WINAPI thread_function(LPVOID param)
{
cout << "Releasing g_sema in " << flush;
for (int n = 5; n > 0; n--)
{
cout << n << " " << flush;
Sleep(1000);
}//for
cout << endl;
ReleaseSemaphore(g_sema, 1, NULL);
return 0;
}//thread1
int main()
{
g_sema = CreateSemaphore(NULL, 2, 2, NULL);
if (g_sema == NULL)
{
cout << "CreateSemaphore() failed, last error = " << GetLastError() << endl;
}//if
DWORD thread_id;
HANDLE hthread = CreateThread(NULL, 0, thread_function, NULL, 0, &thread_id);
if (hthread == NULL)
{
cout << "CreateThread() failed, last error = " << GetLastError() << endl;
return 1;
}//if
// count for g_sema will be 1 after call
WaitForSingleObject(g_sema, INFINITE);
// count for g_sema will be 0 after call
WaitForSingleObject(g_sema, INFINITE);
// this call will block until other thread makes count non-zero
WaitForSingleObject(g_sema, INFINITE);
cout << "here!" << endl;
// wait for thread to complete (we all know how to spell "ass-u-me")
WaitForSingleObject(hthread, INFINITE);
// forgot to do this in my last past
CloseHandle(hthread);
CloseHandle(g_sema);
return 0;
}//main
gg