Re: Still confused on new thread starting idle functions to update UI.
- From: Bernhard Schuster <schuster bernhard gmail com>
- To: David Buchan <pdbuchan yahoo com>
- Cc: gtk-app-devel-list list <gtk-app-devel-list gnome org>
- Subject: Re: Still confused on new thread starting idle functions to update UI.
- Date: Tue, 03 Dec 2013 19:17:26 +0001
The observed bad behavior is that sometimes messages don't appear at
all, or appear twice in my textview. It's quite unpredictable. Sounds
like a race condition.
I spawn a thread from the main program - and from now on I don't talk
about main - and this new thread prepares messages in a character
string. The thread then passes a pointer to the character string to
an idle function so that the idle function can update a textview in
the UI. When done, the idle function stops itself by returning a
G_SOURCE_REMOVE boolean.
That sounds sane so far.
The thread allocates memory for the character string, and the idle
function does not free it. Instead, the thread free's the memory just
before it stops. It waits a bit to make sure the idle function has
finished using the memory containing the message.
That does not sound sane. This actually could create a race condition,
you never know which thread get scheduled when.
I'd recommend you to use a GAsyncQueue, push a ref counted (not
necessary in your case here) object (i.e. GByteArray or a custom ref
counted version of GString) into it.
Keep the idle function until the queue is empty (+deref/destroy the
char array/GByteArray/GString).
But I lied...
Because there are several messages (roughly 30), the thread actually
allocates memory for an *array* of character strings. An index is
then used to specify which one we're using.
This may seem awkward and unnecessary, but if I just use a single
character string, it is possible for the thread to replace the
contents of the string with the next message while an idle function
is still working with the previous message.
3
This is not deterministic, you are trying to rely on probabilistic
behaviour and that the mainloop is able to process a certain amount x
before your thread shoots again.
What I had before which worked was a single character string and a
sleep (1) after each g_idle_add(), but that made things very sluggish.
Indeed, do not use sleep in order to fix an already broken behaviour
(this is not a rule of thumb, this is a do never ever thing).
<snip>...</snip>
I would've liked to pass the message string to the idle function by
value, because then it would only work with its own ephemeral copy of
the string, but g_idle_add() only allows me to pass a pointer to
data, not the data itself.
Use a refcount char array "container" (like GByteArray and GString is).
Hope I could help you, keep asking if something is not clear or if you
are uncertain how to do implement things properly.
Best
Bernhard
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]