SFML community forums

Help => Window => Topic started by: Groogy on July 08, 2011, 09:32:03 am

Title: Polling events and setting cursor position thread safety
Post by: Groogy on July 08, 2011, 09:32:03 am
Oi!

I'm just wondering if it is thread safe to pull events in one thread and set the cursor position in another thread? This is in SFML2 of course.

Because of the recent changes it feels like they are being detached more and more from each other so I suspect they got nothing to do with each other but just want to make sure before I change anything in my engine.
Title: Polling events and setting cursor position thread safety
Post by: Laurent on July 08, 2011, 09:42:57 am
In today's revision, they really are disconnected from each other so it's safe to use them concurrently.
Title: Polling events and setting cursor position thread safety
Post by: Groogy on July 08, 2011, 09:47:58 am
One problem though... Whenever I move my mouse... The entire application locks until the mouse stops... At least that's how it is for my example application on the engine... Is there something in SFML that creates this behaviour or is it me doing something funky?
Title: Polling events and setting cursor position thread safety
Post by: Laurent on July 08, 2011, 09:55:42 am
Hmm I don't know. Try to reproduce it in a minimal SFML-only application.
Title: Polling events and setting cursor position thread safety
Post by: Groogy on July 08, 2011, 09:57:20 am
Apparently the lock don't happen if I comment out:
Code: [Select]
sf::Mouse::SetPosition( sf::Vector2i( myWindow.GetWidth() / 2, myWindow.GetHeight() / 2 ), myWindow );

If you are not doing any locking then Windows probably are... I'll try and find a work around. But seriously, dude we need a better way to create a FPS camera or something.

Update: Or wait.. might be something else.. though funny thing is when the mouse is OUTSIDE the window it don't lock =/
Title: Polling events and setting cursor position thread safety
Post by: Laurent on July 08, 2011, 10:12:13 am
If you SetPosition and PollEvent in parallel, then the latter can be spammed by the former and your event loop might never end.
It doesn't freeze when the mouse is outside the window because in this case no MouseMove event is generated and your event loop can finish.

Quote
But seriously, dude we need a better way to create a FPS camera or something.

I know. But right now there are other priorities.
Title: Polling events and setting cursor position thread safety
Post by: Groogy on July 08, 2011, 10:16:04 am
Quote from: "Laurent"
If you SetPosition and PollEvent in parallel, then the latter can be spammed by the former and your event loop might never end.

It happened while I had SetPosition commented out too.

Alright some more information. Tried a little with a breakpoint. I got a very weird behaviour.... While I was moving the mouse it seems that I never got out of the poll event loop. Because the breakpoint was only triggered when I stopped moving the mouse.
Code: [Select]
void GGE::Application::UpdateInput()
{
sf::Event event;
Threading::MessageList &list = mySynchro.GetOutput().GetList();
unsigned int numMoves = 0;
unsigned int numEvents = 0;
while( myWindow.PollEvent( event ) == true )
{
numEvents++;
if( event.Type == sf::Event::MouseMoved )
{
numMoves++;
continue;
}
InputMessage *message = new InputMessage( event, &myWindow );
list.AddElement( message );
}
if( numMoves > 10 )
{
numMoves = numMoves;   // <-- Breakpoint here
}
}

The result of numMoves was 90 and the result of numEvents was also 90. So the window got locked until the mouse stopped moving.

I want to point out the behaviour was not like this before the changes.

I am going to try and create a simple example to show.
Title: Polling events and setting cursor position thread safety
Post by: Groogy on July 08, 2011, 10:27:31 am
Actually I don't need to create a minimal example. The OpenGL example that come with SFML2 shows the same behaviour, both in debug and release.

NOTE: Actually it's the same for all SFML examples.

Filling out with some more information:
I'm on Windows 7 64 bit with the latest SFML2 compiled with VS10 32 bit.
My mouse input is a touch-pad or whatever it's called in English, the common thing that every laptop have to replace an actual mouse.

Also again, this worked perfectly before the new changes.
Title: Polling events and setting cursor position thread safety
Post by: Laurent on July 08, 2011, 10:37:42 am
Hmm... I'll so some tests :?
Title: Re: Polling events and setting cursor position thread safety
Post by: Hiura on July 08, 2011, 11:06:59 am
Quote from: "Groogy"
pull events in one thread
I just wanted to point out that this thread _must_ be the main thread, at least on Mac OS X because of some (stupid) system limitations. I think this is not the case on Windows nor Linux so be aware of that while developing your engine stuff.
Title: Re: Polling events and setting cursor position thread safety
Post by: Groogy on July 08, 2011, 11:11:39 am
Quote from: "Hiura"
I just wanted to point out that this thread _must_ be the main thread, at least on Mac OS X because of some (stupid) system limitations. I think this is not the case on Windows nor Linux so be aware of that while developing your engine stuff.


Already taken into account. Actually I think it is the same for them too but in Windows you can move it to another thread but it requires you to take some steps before you can do that. Don't remember exactly how, I stumbled upon it when tried to figure out why my Windows Message Loop didn't work for my school groups project, but it was such a mess so we just moved the message loop instead. Much easier!
Title: Polling events and setting cursor position thread safety
Post by: Laurent on July 08, 2011, 11:14:50 am
On Windows, event polling must happen in the thread that created the window.
Title: Polling events and setting cursor position thread safety
Post by: Groogy on July 08, 2011, 11:22:20 am
Quote from: "Laurent"
On Windows, event polling must happen in the thread that created the window.

Actually, if I remember correctly, you can give permission to other threads to pull events from the window. Something like that. But like I said, it was easier to just move the loop instead.

Anyway getting a bit off-topic.
Title: Polling events and setting cursor position thread safety
Post by: Laurent on July 08, 2011, 11:24:51 am
Quote
Actually, if I remember correctly, you can give permission to other threads to pull events from the window

Never heard about that. If you can find a source, let me know I'm interested ;)
Title: Polling events and setting cursor position thread safety
Post by: Groogy on July 08, 2011, 11:29:06 am
Quote from: "Laurent"
Quote
Actually, if I remember correctly, you can give permission to other threads to pull events from the window

Never heard about that. If you can find a source, let me know I'm interested ;)


It's like 3 months since I looked it up. I found it somewhere in the jungles of MSDN... I'll see if I can find it.
Title: Polling events and setting cursor position thread safety
Post by: Groogy on July 08, 2011, 11:43:17 am
Couldn't find it, must have misread/misremembered something... Though I'm pretty sure me and another group member came up with something but we decided that moving the loop was easier :?

Though just from looking at it for 15 min I could find it would be possible to forward all window messages to another threads message queue. (That was not what we came up with though)

NOTE: Not sure but it might have been something like this: http://msdn.microsoft.com/en-us/library/ms681956%28v=vs.85%29.aspx
Title: Polling events and setting cursor position thread safety
Post by: Laurent on July 08, 2011, 06:22:06 pm
I can't reproduce the freezing thing. Have you tried to fully recompile everything?
Title: Polling events and setting cursor position thread safety
Post by: Groogy on July 08, 2011, 09:15:33 pm
Quote from: "Laurent"
I can't reproduce the freezing thing. Have you tried to fully recompile everything?


Yepp I always do that and just did it again before posting just to be sure. Same result. I also tried putting in a mouse. Same result. The OpenGL is the most obvious one because of the rotating cube. While moving the mouse the cube stops moving and rotating until the mouse stops.

So just a theory. But feels like as the PollEvent function waits for the mouse to generate a mouse moved event before it returns while the mouse is moving.
Title: Polling events and setting cursor position thread safety
Post by: Laurent on July 08, 2011, 09:34:13 pm
The logic inside Window::PollEvent is the same as before, even if the code slightly changed (mostly for WaitEvent).

It's weird that I can't reproduce it because I have the same environment as you (just using VC2008 instead of 2010).

Quote
Also again, this worked perfectly before the new changes.

Which revision exactly?
Title: Polling events and setting cursor position thread safety
Post by: Groogy on July 10, 2011, 06:01:21 pm
Anyway regarding the problem we had with the locking while mouse being in motion... magically disappeared.... From examples.. from my engine...

So must have been my drivers or something.... Really freaky. Didn't recompile SFML2 or anything like that.

Just wanted you to know so that you can stop worrying about it Laurent ^^
Title: Polling events and setting cursor position thread safety
Post by: Fray on July 26, 2011, 10:17:36 pm
Hi,

I am experiencing the exact same problem here and it looks like it comes from the Joystick event processing.
Commenting ProcessJoystickEvents(); from WindowImpl.cpp seems to "fix" the problem and also drastically improves the framerate.

Unfortunately I'm not knowledgeable enough to investigate the issue further.


SFML2 from github
VS 2010
SFML_STATIC
Win7 x86
Title: Polling events and setting cursor position thread safety
Post by: OopsIDied on August 11, 2011, 06:28:08 am
Quote from: "Laurent"
Quote
Actually, if I remember correctly, you can give permission to other threads to pull events from the window

Never heard about that. If you can find a source, let me know I'm interested ;)


I'm not sure what you guys are trying to do but it seems like this can be easily done with DLL Injection + subclassing the parent window's WndProc. Instead of passing the windows events to another thread, you move external code INTO the thread. You guys probably already knew about that but just making sure lol  :)