I typically implement my multi-threaded polling like this:
void logic_thread(sf::Window& window, std::queue<sf::Event>& buffer, std::mutex& buffer_mutex)
{
window.setActive(true);
std::queue<sf::Mutex> events;
while (window.isOpen())
{
while (buffer.size() > 0)
{
buffer_mutex.lock();
events.push(buffer.front());
buffer.pop();
buffer_mutex.unlock();
}
while (events.size() > 0)
{
sf::Event event = events.front();
events.pop();
//Handle event
}
}
}
void main()
{
sf::Window window;
std::queue<sf::Event> buffer;
std::mutex buffer_mutex;
window.setActive(false);
std::thread logic_thread(std::ref(window), std::ref(buffer), std::ref(buffer_mutex));
std::queue<sf::Mutex> tmp;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
tmp.push(event);
while (tmp.size() > 0)
{
buffer_mutex.lock();
buffer.push(tmp.front());
tmp.pop();
buffer_mutex.unlock();
}
}
logic_thread.join();
}
The reason why is because when you have implementations like yours, it's difficult to defer things that require processing on the other thread. On top of that, I've found that certain things can cause
sf::Window::pollEvent to "hang", which mixed with a mutex would cause the same thing to happen on the other thread. And if you're using a time-step, accumulating updates is a very bad thing.
There's a few functions I call that I don't use a mutex for, but I don't have any synchronization problems. There's simply no other way around easily deferring events from one thread to another.