In GGI: it seems that the IS_CRITICAL, ENTER_CRITICAL and LEAVE_CRITICAL macros implement the "the_mutex_for_everything_shared" abstraction.
So, if you do something that has to be thread-safe, you may surround all your code with ENTER_CRITICAL and LEAVE_CRITICAL pairs. This may be inefficient, but well, probably not, and you are safe at least. It means that nothing else will be done by any GGI code before you LEAVE_CRITICAL. (To others: Is it the actual meaning of these macros ?)
NB: A code section surrounded by a MutexGet/Release pair is generally called a critical section (hence the macros names). But I don't really like this naming, because in fact a section is always critical with respect to something (the data accessed, and nothing else). You can encapsulate _several_ critical sections inside each other without any harm if you are careful. You may even interleave several critical sections without any harm, but, you have to be _very_ careful with this (and I wouldn't recomment this to anyone).
You should not protect the library calls, you should protect _your_ data ! (Well, if you program a library, your data is library data, but...:-) Of course, if you use thread-UNsafe libraries, your program will not be thread-safe either and you are doing extra work. But well, libggi is supposed to be thread-safe one day (and then, it must rely on a thread-safe libc for example...). However, if you pass a "pointer" to a library function, the associated data is _your_ data (even though the library will modify it, you simply delegate the work to it). So you should protect it: but only if your main program is multi-threaded.
The problem with GGI accelerated commands is that, implicitly, a new "thread" (in fact a control-flow) can always appear: the "program" that executes on the card's chipset (bitBLT engine, 3D engine). The data to protect (your data) is the framebuffer... We could use a real mutex to protect this things, but well, it is simpler to have a "wait_until_finished" approach. You can (and you will be obliged) to wait for the on-video-board "thread" to finish. Hence, each time you want to draw on the framebuffer ((either yourself or thanks to the library), you must do a ggiFlush (or maybe ggiFinish as Andreas wanted to change the name), to let the engine leave the framebuffer to you. If you don't do that: you may face a data corruption problem (as with first_data or second_data). (NB: It is not so "critical" for graphical data, it's "only" ugly...) You may ask me: but, well, we don't have a true mutex, so, if I think truly "parallel", what about the case where the 2D engine starts drawing something on the framebuffer and I start also ? Should I use ggiFinish _before_ drawing. The answer is no: the underlying assumption is that the accelerated engine will never start something by itself (at least I hope so). So, you should ggiFinish only after a drawing command (and before the next one of course). By the way, we also do a synchronization with ggiFinish as the _whole_ framebuffer will be "ready" after that call.
Why not implement a "complete" locking system on the framebuffer (ie: Get/Release, or Enter/Leave) ? Simply because it is a very big data, and it would be inefficient. Furthermore, unless you use the card's memory to store program code, corruption of this big data is only garbage on screen, so... Let it be simpler, and the programmer will check that things are correct, and be synchronous if he doesn't want to worry about this. In this case, the programmer forgets about the bitBLT or 3D engine running asynchronously, and simply says to the libggi: be SYNC and worry about these stupid things yourself. This is a "convenience" mode, that effectively makes use of a complete locking semantic on the framebuffer (maybe a clever one, but well only because we are good persons) and manages it itself. If the programmer wants to go ASYNC, then, _he_ will have to manage the ggiFinish problems himself. The advantage ? He _can_ do a finer grain control of the data and make his application draw in the framebuffer at the same time as the card engines, (hopefully in different areas, or the result will be... funny :-). In this case, GGI (kgi+libggi) only does controls wrt hw safety (prevent hardware locks if needed, etc.). We may rename these macros: GARBAGE_FORBIDDEN, GARBAGE_ALLOWED... :-)
NB: However, even if you are synchronous wrt graphics (ie: a single drawing thread), this does not mean that your program shouldn't protect any data. If the AI thread sends data to the drawing thread, these data should be protected in the application program.