David Buchan <pdbuc...@yahoo.com> wrote:

> These darn threads and idle functions still baffle me. I'm sorry to
> be such a pest.
> 
> I want to periodically update a textview as new information comes
> available.
 Sometimes this information can come in quickly (roughly
> every tenth of a second). Each update is a single line of text.
> 
> 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.
> 
> 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.
> 
> 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.

It is awkward, and probably unnecessary.  Unless you have a very good
reason, that is not the way to do it.  Pass the idle function a string
allocated on the heap, and free it in the idle function when finished
with.  Any other way creates thread dependencies which the message
passing approach you have adopted is intended to avoid.

Chris
=========================================

Chris, 

For clarification, if I use strdup() to pass to the idle function a pointer to 
a copy of the string, and then have the idle function free it when finished, is 
that passing it on the heap?

Simplified rough example:

In main():

char *message
message = (char *) malloc (1024);

for loop {

   Calculate good stuff.

  strcpy (message, "Super duper message.");
  g_idle_add ((GSourceFunc) post_message, strdup (message));

  if (we're done) break;
}

free (message);
return (EXIT_SUCCESS);

And the idle function would free that memory before it stops:

int
post_message (char *message)
{
  GtkTextBuffer *textbuffer;
  GtkTextIter end;

  textbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (data->textview));
  gtk_text_buffer_get_end_iter (textbuffer, &end);
  gtk_text_buffer_insert (textbuffer, &end, data->message, -1);
  gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (data->textview), &end, 0.0, 
FALSE, 0, 0);

  // Free memory used for message string.
  free (message);

  return (G_SOURCE_REMOVE);
}

I'm not clear on the exact meaning of "heap". Is that what the above would do?

Dave
_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Reply via email to