1

I'm creating application model with three threads based on while(true) and a blocking function.

  1. Event thread - waits for user input, blocked by SDL_WaitEvent
  2. Socked thread - waits for data from server, blocked by blocking socket.
  3. Render thread - renders data from buffer, not blocked.

I have a problem with rendering thread - i need a blocking function that will, for example, block until some paint event (defined by me and dispatched in one of other two threads) happens.
But I don't know how blocking functions work. I can, of course, create an sleep() loop, but such loop has fixed FPS takes resources even if nothing happens (I've already elaborated on that topic here). On the oher side, it does not display data immediatelly. This is not good for GUI application.

Community
  • 1
  • 1
Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
  • 1
    Whats about WaitForMultipleObject? It it not what you are looking for? – Leo Chapiro Feb 04 '13 at 16:32
  • Looks good. Is there multiplatform version? Or at least, linux equivalent, so I can write one myself? – Tomáš Zato Feb 04 '13 at 16:38
  • `WaitForMultipleObject` is a hack, because Windows didn't have conditional variables. It's very nice when you're waiting for external events, like incoming data, but it's not really well designed for internal synchronization; it's too easy to get race conditions. – James Kanze Feb 04 '13 at 17:44

2 Answers2

3

If you're using C++11, you can use std::condition_variable and std::mutex:

void
waitForEvent()
{
    std::unique_lock<std::mutex> lock( myMutex );
    while ( ! externalCondition ) {
        myConditionVariable.wait( lock );
    }
}

To trigger the event:

void
setEvent()
{
    std::unique_lock<std::mutex> lock( myMutex );
    setExternalCondition();
}

On the other hand, you mention a GUI and a renderer. You cannot wait on an external condition in the GUI thread. If you need to be in the GUI thread for rendering, you'll have to find out how to create a GUI event in your GUI manager, and post the GUI event.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • Well, this looks even better, but I have a few questions. First, what is `myMutex` variable? Then what are theese `` after variable definition. This is not the first time I see them. Quite similar, I see no definition of `myConditionVariable`. I'm sorry, but I'm beginner and I only understand very basic syntax. – Tomáš Zato Feb 04 '13 at 17:49
  • `myMutex` and `myConditionVariable` are variables of type `std::mutex` and `std::condition_variable`, respectively. And the `<...>` are template specifications: you must have seen them a lot, any time you've used `std::vector`, for example. – James Kanze Feb 04 '13 at 17:57
  • Yeah, I've seen them with vector, and while I didn't understand them, I did my best to avoid vectors at all. Even if `myConditionVariable` and `myMutex` are of `std::mutex`, they don't just pop from the air, do they? I'm sorry for being so annoying, but to make working code, I need to know where to define theese, or, at least, understand whole problem. – Tomáš Zato Feb 04 '13 at 18:01
  • @TomášZato Why do you avoid vectors? The alternatives are usually more complicated. As for the definitions, everything in `std::` is defined in a standard header. You just have to include it. `` and ``, in this case. – James Kanze Feb 04 '13 at 18:08
0

Looks good. Is there multiplatform version? Or at least, linux equivalent, so I can write one myself?

Take a look at this thread: WaitForSingleObject and WaitForMultipleObjects equivalent in linux

Stick to pthread_cond_timedwait and use clock_gettime. For example:

struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 10; // ten seconds
while (!some_condition && ret == 0)
    ret = pthread_cond_timedwait(&cond, &mutex, &ts);
Community
  • 1
  • 1
Leo Chapiro
  • 13,678
  • 8
  • 61
  • 92