I found this when I was porting my data loader thread from SDL to SFML.
Here's more complete example:
#include <SFML/System.hpp>
#include <iostream>
#include <queue>
sf::Mutex WorkMutex;
enum JobEnum
{
LoadJob,
ExitJob
};
sf::Mutex JobMutex;
std::queue<enum JobEnum> LoadQue;
/*--------------------------------------------------------------------------*/
void Worker(void *)
{
bool Done=false;
while (!Done)
{
// Wait for job
WorkMutex.Lock();
// Get a job from queue
enum JobEnum Job;
{
sf::Lock Lock(JobMutex);
std::cout << "Get job from queue" << std::endl;
Job=LoadQue.front();
LoadQue.pop();
}
// Check the type of job
switch (Job)
{
case LoadJob:
std::cout << "Load job" << std::endl;
break;
case ExitJob:
std::cout << "Exit job" << std::endl;
Done=true;
break;
default:
std::cout << "FATAL: Unknown job" << std::endl;
Done=true;
break;
}
}
std::cout << "Thread exit" << std::endl;
}
/*--------------------------------------------------------------------------*/
// Main
//
int main()
{
// Lock mutex to prevent worker doing anything
WorkMutex.Lock();
// Create and launch worker thread
sf::Thread Thread(Worker);
Thread.Launch();
// Add few load jobs
for (int i=0; i<3; i++)
{
// Add job to queue
{
sf::Lock Lock(JobMutex);
std::cout << "Add job to queue" << std::endl;
LoadQue.push(LoadJob);
}
// Tell thread that there is something to do
WorkMutex.Unlock();
// Simulate data processing
sf::Sleep(0.5);
}
// Tell worker thread to exit
std::cout << "Add exit job" << std::endl;
LoadQue.push(ExitJob);
WorkMutex.Unlock();
return EXIT_SUCCESS;
}
(fyi: this code is not complete, this version here has logical errors)
This prints following:
Add job to queue
Get job from queue
Load job
Get job from queue <---- Bug here, there was only one job in que
FATAL: Unknown job
Thread exit
Add job to queue
Add job to queue
Add exit job
Since SFML is using critical section my worker thread does not work and it gets two jobs from queue, even if only one was created.
My point here is that when someone writes similar code on Linux, it will not work when it is compiled on Windows.
This is not a problem for me, since now I know that SFML doesn't do mutexes as I expect, but it might be problem for someone else at some point.
Also, since my code above should be using Semaphore instead of WorkMutex, this might be much smaller issue than it sounds.