Scintilla and thread safety - c

I'm using the Scintilla edit control on Windows (Win32, C/C++) . The control is created in WndProc. I have a second thread, created with Boost.Thread, that act as a spell checker and marks with red squiggle incorrectly spelled words. Therefore, I have two threads altering the content of the Scintilla control.
At first, the program was crashing when editing text. So I researched Scintilla for thread safety. I found little information, but I manage to get this quote in the documentation:
direct calling will cause problems if
performed from a different thread to
the native thread of the Scintilla
window in which case
SendMessage(hSciWnd, SCI_*, wParam,
lParam) should be used to synchronize
with the window's thread.
Of course, I'm using direct calls, accordingly I change all calls in the spell check thread to SendMessage and now the program doesn't crash anymore.
Finally, and that's the question, have I solved the problem, or am I going to encounter other quirks with Scintilla and multithreads?

You should generally access windows (HWNDs) in Windows only from the thread they were created in. Any message sent to the window will be performed in the thread that created it, that's why the crashes stopped happening when you replaced all direct calls to the Scintilla functions by sending messages. If you use SendMessage() in your spell check thread this will cause the following to happen:
the spell check thread will block
a context switch to the GUI thread will be performed
the message loop will process the message (but not necessarily immediately, messages in the queue will be handled in the order they were added, so the message will be handled only after all previously added messages have been handled)
a context switch to the spell check thread will be performed
the SendMessage() call returns the result
So you have indeed fixed the problem, but at a very high price. Every misspelt word will cause two thread context switches, and the spell checking will block for each misspelt word. This could actually be quite a long time, if any other messages that take long to handle were still queued up.
You should change the design of your program. Ideally both threads will be able to work independently, and this can be achieved by adding a thread-safe data structure that the spell check thread adds information about misspelt words to, and that the main thread retrieves the information from. Boost has lots of classes to help you out. By doing so you can continue to use the direct calls, since they will be performed in the context of the main thread. Performance should improve, as multiple words could be underlined in one go, causing only a single repaint of the control. If you use PostMessage() instead of SendMessage() the spell check thread will be able to continue its work independently of the main thread being ready to handle the message.
If you remember to never call any Scintilla code from secondary threads you will not encounter other quirks. And this is nothing specific to the Scintilla control, calling Windows API functions that do not use Windows messages internally would be problematic for any other control just as well.

Related

What does it mean to send a message to a thread?

I am learning about threads. And I need to understand how threads communicate between each other, so what does it mean when we say something like "let Thread A send a message to Thread B"?
I can think of the following:
Thread B is blocking on some sort of queue, and Thread A places a new
entry in this queue, which causes Thread B to unblock, and retrieve
this entry.
Thread B is blocking on an event (for example, in Windows API there
is the Event object), and Thread A signals this event which will
cause Thread B to wake up (or is this called notifying a thread and
not sending a message to it?)
The "threads" world is subject of many ambiguity due to different nomenclature coming from different environments, sometimes using same words to mean different things.
Your first assertion makes sense in very general terms: the "message" is what makes the thread to wake-up and get some "input".
Depending on the OS and its own API, your second assertion makes sense and is nothing more then a way to implement the first using the Win32 API.
Another possible interpretation can be that the thread is blocked on a message loop (see GetMessage) and the other one calls PostThreadMessage.
In a more general term, you can think of a "message" as an "event" that carries a "state" with it: an event simply happens (and that's all the information it gives). A message "happens", and has some parameter associated with it.
Link to example Windows code that uses two threads to copy a file, the original thread reads, a created thread writes. There's a custom messaging system that uses Windows mutexes and semaphores. Other than the overhead to create and delete the mutexes and semaphores, the actual functions are fairly small. I've worked on embedded multi-threaded devices, using a similar messaging interface scheme.
http://rcgldr.net/misc/mtcopy.zip

Threading problems with GTK

I'm building a fairly simple C application using GTK, but have to perform some blocking IO which will trigger updates to the GUI. In order to do this, I start a new pthread right before gtk_main() as such:
/* global variables */
GMainContext *mainc;
/* local variables */
FILE *fifo;
pthread_t reader;
/* main() */
mainc = g_main_context_default();
pthread_create(&reader, NULL, watch_fifo, argv[argc-1]);
gtk_main();
When the pthread reads some data, it updates the GUI like so:
g_main_context_invoke(mainc, set_icon, param);
Where set_icon is
gboolean set_icon(gpointer data)
{
char *p = (char*)data;
gtk_status_icon_set_from_icon_name(icon, p);
return FALSE;
}
This all works most of the time, but every now and again I get this curious error message:
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
mktrayicon: xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
I thought the whole point of using g_main_context_invoke was to avoid issues with threads? Doing a bit of Googling, I came across gdk_threads_init, gdk_threads_enter and friends, but they all seem to be deprecated? I know the GTK documentation says that all GUI updaes should be performed on the main thread, but this does not combine all that well with blocking IO, and I'd prefer not to have to construct some complex communication mechanism between the threads.
And so, my question is, how should I correctly deal with this?
EDIT: The full code can be seen here
EDIT2: As an update based on #ptomato's answer, I've moved to GThreads and using gdk_threads_add_idle() as seen in this commit, but the problem is still present.
Call XInitThreads(). This should be done before gtk_init, that will stop the messages!
Something like this:
#include <X11/Xlib.h>
...
XInitThreads();
...
gtk_init(&argc, &argv);
I don't remember seeing these messages before GLIB 2.32, when
g_thread_init()/gdk_threads_init() were used.
You might want to check out g_thread_pool_new and g_thread_pool_push.
From thread, use g_main_context_invoke to execute in main loop or
just wrap thread between gdk_threads_enter()/gdk_threads_leave()
I do not use a tray so I can not easily check this. I think you are
correct about gdk_threads_add_idle using locks to protect GTK/GDK API.
There is nothing obvious to me that would cause these messages to
appear. The function description for gtk_status_icon_new_from_icon_name
states that "If the current icon theme is changed, the icon will be
updated appropriately. Which to me, implies your code is not the only
code that will access the X display, which could potentially be the
problem.
There is also some related info regarding XInitThreads() at
What is the downside of XInitThreads()?
Note that while GDK uses locks for the display, GTK/GDK do not ever
call XInitThreads.
On a side note: What's protecting the global variable "onclick", which
is passed to execl after a fork(), The child will not inherit the parent's
memory locks, and GLib mainloop is incompatible with fork().
Maybe you could copy the string to local variable.
I'm not sure if bare pthreads are guaranteed to work with GTK. You should use the GThread wrappers.
I think what the problem may be is that g_main_context_invoke() is adding set_icon() as an idle function. (It seems that that is what goes on behind the scenes, but I'm not sure.) Idle functions added using GLib's API, despite being executed on the main thread, need to hold the GDK lock. If you use the gdk_threads_add_idle() API (which is not deprecated) to invoke set_icon(), then everything should work properly with threading.
(Although this is just a wild guess.)
As a work around, if you just want to avoid blocking the UI while waiting for some IO you could use the asynchronous IO from GIO. That would avoid you having to manage threads yourself.
Edit: Thinking about it you could just mark your file descriptors as non-blocking and add them as a source to the glib main loop and it will poll them for you in the main event loop without having to mess about with threads.
You could avoid using threads by using gio_add_watch() which will invoke your callback function when there is data available on the channel.

Any difference between main thread and other threads?

On GLFW FAQ, item 2.9 it is stated:
[...] It is strongly recommended that all OpenGL and GLFW calls
(except for thread management and synchronization calls) are made from
the main thread, which should not be a big problem since only a single
window is supported. This method is also compatible with the future
direction of GLFW.
The emphasis is mine.
So, what is the difference between the main thread and other threads?
The question refers to an old GLFW API and FAQ, please see the updated GLFW FAQ, and GLFW thread safety documentation.
Some constraints remain, and many GLFW calls must be made from the main thread. The difference between the main thread and other threads depends on platform specific behaviour for window creation, events etc which GLFW handles. For more detail please see this post on the official GLFW forum.
Once an OpenGL window has been created, the context can be made current on another thread and OpenGL calls can be made from that thread.
The statement
"Is … thread safe? No. However, neither is OpenGL."
is wrong. OpenGL is of course thread safe.
Here's the deal: For each thread either one or no OpenGL context can be bound to a drawable (made current). OpenGL calls operate on the context that is active in the thread the calls are made from. It is perfectly possible to transfer a OpenGL context between threads. For this the context to be transfered first must be unbound, then it can be rebound in another thread.
Each OpenGL context manages its own set of state variable and objects (textures, buffers). However context can be "entangled", i.e. share their object space. State is still individual though.
A single drawable (window, PBuffer) can have multiple contexts from different threads being bound to. If contexts from different threads draw to the same drawable a race condition occours and the results are undefined. However in the case of depth tested drawing the outcome should be reasonable. However simultanous drawing to a single drawable will strongly impair performance, so it better is avoided.
The main use for multiple OpenGL contexts in multiple threads is to share their objects so that one thread can load and update data for the other context. It makes sense to bind the helper contexts to off-screen or hidden drawables to prevent race conditions to happen.
There's no technical difference between the threads. From a programming point of view each thread will have a slightly different semantic, which is imposed by the programm running, not by the system architecture. In the case of most OpenGL applications the conventional semantics are, that the main thread will create the window, draw all elements visible to the user (including OpenGL operations) and collect user input. The threads launched from the main thread are worker threads without direct user interaction. However this task distribution is purely by choice and because it turned out to work well. But it's perfectly possible, and sometimes advisable, to use a different scheme. And like already said, there is no technical difference about the threads within a program. All threads are equal rights citizens within a process.
The documentation is maybe worded in a slightly misleading way. A better wording would be:
It is strongly recommended that all OpenGL and GLFW calls (except for thread management and synchronization calls) are made from a single thread, preferrably the same one that called glfwInit and glfwOpenWindow, which should not be a big problem since only a single window is supported. This method is also compatible with the future direction of GLFW.
The reason for that is that OpenGL has the concept of a "current thread" for its contexts, which is the one thread that may legitimate modify or use that context at a given time. A context initially belongs to the thread that created it. You can make it "current" in some other thread by calling wglMakeCurrent or glxMakeCurrent, which unlike GLFW is not portable (but GLFW might have a wrapper for that, I'm not sure).
It is of course very well possible to have several independent contexts, and it is possible to access the same context from several threads by making the same context current in each thread prior to using it. And lastly, it is possible to have several contexts in several threads that share state.
However, none of these options is the regular case, as it either involves non-neglegible synchronization overhead or is not suitable for the common usage of OpenGL. Any other thing than "one thread, one context" usually, with very few exceptions, doesn't offer any advantage, but comes with needless complexity.
The regular case is therefore to have exactly one context that is used by exactly one thread, and optionally some worker threeads that help with shuffling data into mapped buffers.
As for "main thread" versus "any thread", there is no difference. The main thread is just incidentially the one that initializes GLFW (and thus OpenGL), most of the time.

gtk/c manipulate GUI in a thread: strange errors

I wrote a C/S application using udp and it keeps giving me errors, which I believe has something to do with the way I use threads.
When the client program starts, it first initializes a login window and starts a new thread to listen to the response from the server. After it submits user name and password, the new thread will receive a message indicating whether it submitted the right info. If it did, then the thread would initializes the main GUI window. But it would give strange errors:
Fatal IO error 11 (Resource temporarily unavailable) on X server :0.0
or
python: Fatal IO error 0 (Success) on X server :0.0
I found a similar question here, but it's not solved.
Some say GUI should only be manipulated in the main thread, but others say it's not true.
I also tried using gdk_threads_enter() and gdk_threads_enter() around gtk_main() and the code where I initialize window in that listen thread. But it didn't seem to work.
I don't know much about threads so be patient when pointing out where I have done wrong.
Thanks.
These error messages, I have found, pop up from time to time when you are not holding the GTK lock properly.
You should put gdk_threads_enter() and gdk_threads_leave() around the original gtk_main() call, and also around every call to a GTK function that takes place
outside the thread from which you called gtk_main()
but not in a signal, idle, or timeout handler.
This usage is on its way out though as I understand, and in future versions of GTK it will only be possible to manipulate GTK from the main thread.
It is true that GTK windows should only be manipulated from the main thread.
That said, in some architectures (notably GNU/Linux) you can manipulate GTK windows from another thread provided that you properly use the global lock with gdk_threads_enter() / gdk_threads_leave(). The key word is "properly", that's not as easy as it seems.
And that said, in some architectures (notably MS-Windows) doing that may seem to work in some simple programs, but will fail miserably in more complex ones.
About your question, you don't say it, but you seem to be using Python somewhere, but you don't say where... Mixing Python and native threads is probably not such a good idea, either.

What is C's analogy to LabVIEW's Event Structure?

One programming construct I use quite a bit in LabVIEW is the Event Structure. This gives me the benefit of not having to needlessly waste CPU cycles via polling but only perform actions when an event I'm interested in is generated.
As an experienced LabVIEW programmer with a decent understanding of C, I'm curious how one would go about emulating LabVIEW's event structure in C; preferably under Linux. A small code sample (like the one in the link above) illustrating how this might be done would be much appreciated. Also, if there already exists 3rd party libraries (for Linux) to add this event framework to C, that would be nice to know as well. Thanks.
The Event Structure is really just an abstraction that hides the thread of execution from you. There has to be some code running somewhere on the computer that is checking for these events and then calling your event handlers. in C, you'd be expected to provide this code (the "main loop" of the program) yourself. This code would check the various event sources you are interested in and call your event handler functions.
The trick then becomes how to not have this main loop wildly spinning the CPU. One easy trick is to have the main loop sleep for a period of time and then check if any events need to be handled, and then sleep again. This has the downside of introducing latency. A better trick, when applicable, is to have the Operating System do these checks as part of its normal operations, and then wake your application's main loop up when something interesting happened. In Linux, this is done with the 'select' system call, but select has the limitation that it can only specify a resource that can be associated with a file descriptor, so devices, stdin, files, network ports are fine.
Edit: To clarify for my downvoters: I am not denying the existance of hardware interrupts. Yes, in cases where code has direct access to hardware interrupts for all events that it wishes to handle (such as an embedded system or device driver) you can write truly "event driven" code with multiple entry points that does not busy wait or sleep. However, in a normal application level C program running under Linux, this code architecture does not literally exist but is emulated at the application level. Any Linux application is going to have a main loop, and at least one thread of execution. This thread may get paused by the scheduler, but it always exists and always has an instruction pointer at a particular instruction. If the code leaves the main() the program ends. There is no facility for the code to return from main and get a callback later on from the kernel. The code has a single entry point and must call its various event handlers manually. Other than in a device driver (or very specific system code using signals), you can not have the kernel or hardware automatically call a certain function if the user clicked on a certain menu item, instead your code is running, detects this event itself, and calls the correct event handler.
You can tell LabView "Call this function when XX happens". In C, you tell your own event dispatch code "Call this function when XX happens".
What I'm trying to say (poorly?) is that the Event framework architecture is not native to a C / Linux application. It must be emulated by your code by having a main dispatch thread that gives the appearance of an event driven framework. Either you do this manually, or use an event library that does this behind the scenes to give the appearance of an event driven model. LabView takes the second approach, so it appears that no code is running when no events are happening, but in reality there is LabView's own C++ code running managing the event queues. This doesn't mean that it is busy waiting all the time, as I said before there are system calls such as select and sleep that the code can use to yield cpu time when it has no work to do, but the code can not simply stop executing.
Lets say you want to write an "event driven" program with two event handlers. One that gets called every ten seconds called tick() and one that gets called every time a key gets pressed called key(), and one that gets called everytime the word "foobar" gets typed called foobar(). You can define these three event handlers, but in addition you need some dispatch main thread that basically does
while not quitting
If 10 seconds have elapsed, call tick()
If Key has been Pressed
call key()
add save the key to our key buffer
If buffer now contains "foobar" call foobar() and clear buffer
Wait()
If all of the events you care about are system level events or time level events, you can Wait() can simply be telling the kernel 'wake me up when one of these things happens' so I don't need to 'busy wait', But you can't simply tell the Kernel "call foobar() when "foobar is pressed". You have to have application level dispatch code that emulates the Event Structure. You're C program only has a single entry point from the kernel for each thread of execution. If you look at libraries that provide event dispatch models, such as Qt, you will find that they are working like this under the hood.
I like libev for this sort of thing.
Most GUI toolkits (GTK, Qt, etc.) implement their own abstraction of an event loop. I've pastebinned a sample program here, because it was a bit long to include in the answer. It's a port of the LabVIEW example you mentioned to C using the GTK toolkit, because that's the one I'm familiar with. The basics of the event loop are not much different in other toolkits, though.
If all you care about is keyboard input, C standard I/O is what you want. By default input streams are buffered and will stall your program until input is received. Use scanf, getchar, whatever else in <stdio.h>.
If you want mouse input, you'll need to be more specific about your platform as C/C++ has no native support for the mouse or windows.
A good analogy to LabVIEWs event structure is Win32's "event pull" function GetMessage(). GetMessage() waits forever until a GUI event occurs. There are much more events, even for every child window (LabVIEW: control or indicator) in Windows than in LabVIEW. GetMessage() simply returns on every event, fine filtering (as in LabVIEW) has to be done later, typically using DispatchMessage() and the Window's event handler procedure WindowProc() with its more or less large switch() statement.
Most tookits use "event push" style which is not adaequate to the event structure. Interrupt driven programs too.
If a timeout is used, think that MsgWaitForMultipleObjects() with zero file handles is called before PeekMessage(). The timeout case applies when no event arrived in the given time span.
Actually, LabVIEWs event structure should be inside a separate loop. A separate loop is a thread. For typical Win32 programming, GetMessage() is used in the main thread, and additional ("worker") threads are generated by user interaction as needed.
LabVIEW cannot easily create a thread. It is only possible by invoking an asynchronous SubVI. Really! Therefore, most LabVIEW programs use a second while loop as a permanently available worker thread that will run when something has to be done and block (i.e. stop consuming CPU power) otherwise. To instruct what has to be done in background, a queue is used.
As a bad side effect, when the worker thread does something, the user cannot do something else in background as there is only one worker thread.
The LabVIEWs event structure has a big difference to other programming languages: LabVIEW events can have multiple consumers! If multiple event structures are used, everything continues to work well (except for events with boolean return values). In Windows, events are posted to a specific thread, mostly to a Windows' thread. To feed multiple threads, events have to be posted multiple times. Similar to other programming languages. Events there are handled by something similar to LabVIEWs “Queue” related functions: If someone receives the event, it is out off the queue.
Multiple-targetting require that every consumer registers itself somehow to the producer. For GUI events, this is done automatically. For user events, this must be done programmatically. See LabVIEW examples.
Distributing events to multiple listeners is realized in Windows using DDE but that's merely for processes than for threads. Registering to a thread is done using DdeConnect() or similar, and events are pushed to a callback function. (To be more exact how Win32 works, GetMessage() receives DDE messages, and DispathcMessage() actually calls the callback function.)

Resources