Yet another multithreading problem

calvin1602 wrote on Sunday, July 22, 2007:

Hello

I’m using glfw multithreading functions in a program and I’m experiencing some trouble.
First, some precisions, I don’t know if it’ll help, but anyway:
I do call glfwInit, but not glfwWindow ( I am in console mode since it’s a test & learning program )
I’m running XP SP2
I link glfw statically

so, here it is. I tried to follow the user’s guide as much as possible.

In the main thread
[code]
// all the init
for (int a=0;a!=10;a++){
glfwLockMutex( Mutex );
there_are_data_to_send();
glfwUnlockMutex( Mutex );
// THERE WHEN I ADD A Sleep(0), yes, ZERO, IT WORKS. if I don’t, the glfwWaitCond is only triggered ONCE :blush:
glfwSignalCond( WaitingForPackets);// Allô le thread ? ya du boulot pour toi …
}[/code]

in the thread :
[code]
glfwLockMutex( Mutex );
while (1){ // loop forever, wait for packets
glfwWaitCond( WaitingForPackets, Mutex, GLFW_INFINITY );
send_data();
}
glfwUnlockMutex( Mutex );
[/code]

So, here it is … I try to send 10 UDP packets. If I add a Sleep(0) ( nonsense, huh ? ), it works. If I don’t, the glfwUnlockMutex( Mutex ); function in the thread loops forever ( I tested with some printf() tests … )

Any idea ? thanks.
Arnaud

peterpp wrote on Sunday, July 22, 2007:

The problem is, that signal sent in main thread is lost if there is no other thread waiting for it. So if you send 10 signals at once, first signal will be used and other nine will be lost while thread is sending data.

From GLFW user guide:
"An important property of condition variables, which separates them from other signaling objects such
as events, is that only currently waiting threads are affected by a condition. A condition is “forgotten”
as soon as it has been signaled or broadcasted."

You have two choices:
- second thread will sent all data that are ready to send, or
- you will use semaphore - signaling object that does not forget signals

PS: My implementation of semaphore that use GLFW library:
http://dark-oberon.svn.sourceforge.net/viewvc/dark-oberon/trunk/game/sources/glfwmodule/glfwsemaphore.h?revision=160&view=markup

calvin1602 wrote on Tuesday, July 24, 2007:

Ohhhhh

All right, thanks :slight_smile: I think your explanation is far better than the manual’s . Could it be added ? I have read the user’s guide several times, but I hadn’t understand this part.

BUT

I see that you count the times where you send a signal to be sure glfw won’t forget any. this way:
this->singnals++;
but I do :
this->WaitingPackets.push_back( blah ); ( I dont have the code there :stuck_out_tongue: )

so I can’t really see the difference, since you write :
111 if (!this->singnals)
112 glfwWaitCond(this->cond, this->mutex, timeout);
113
114 if (this->singnals)
115 this->singnals–;

and I write:
while(! WaitingPackets.empty()){ blah }

I’m sorry if I misunderstood something, it’s the first time I deal with that theads stuff.
Thanks again, anyway :slight_smile:

peterpp wrote on Tuesday, July 24, 2007:

You’r welcome. :slight_smile:

There is no difference. If function send_data() from your first message sends ALL packets that are in buffer:

while(! WaitingPackets.empty()){
send_packet( this->WaitingPackets.front() );
this->WaitingPackets.pop_front();
}

all should works fine… I hope. :slight_smile:

nobody wrote on Wednesday, July 25, 2007:

Well, this really is what I’ve done. And once more, it works only ONCE if I don’t write that stupid Sleep(0);
I think I’m gonna test under Ubunutu today and see what he tells me.

peterpp wrote on Wednesday, July 25, 2007:

I understand that it works only once. But I can’t see any problem, all packets should by sent.

calvin1602 wrote on Wednesday, July 25, 2007:

Okay. Thanks for answering, though :slight_smile: