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. So instead I rotate through 30 character strings with the assumption that by the time the 30th idle function is finished, the character string at index 0 is no longer being used by the first idle function and that string can now be re-used. 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. In the header file, I have: ****** code snip ****** // Define a struct to contain pointers to textview and message for post_message(). typedef struct _msgdata msgdata; struct _msgdata { char *message; GtkWidget *textview; }; #define MAXBUF 30 ****** end code snip ****** In my thread (not main), I have: ****** code snip ****** int i, indx; msgdata *msgdata; msgdata = (msgdata *) malloc (MAXBUF * sizeof (msgdata)); memset (msgdata, 0, MAXBUF * sizeof (msgdata)); for (i=0; i<MAXBUF; i++) { msgdata[i].message = (char *) malloc (1024 * sizeof (char)); memset (msgdata[i].message, 0, 1024 * sizeof (char)); } indx = 0; for loop { Do interesting things. // Report latest results. sprintf (msgdata[indx].message, "Some interesting messages %s %i %f etc\n", various arguments); msgdata[indx].textview = data->textview1; g_idle_add ((GSourceFunc) post_message, &msgdata[indx]); next_msg(&indx); if (we're done) break; } sleep (1); // Wait for idle functions to finish using character string memory. for (i=0; i<MAXBUF; i++) { free (msgdata[i].message); } free (msgdata); return (EXIT_SUCCESS); ****** end code snip ****** The ugly helper function which increments the index is: ****** code ****** // Increment message buffer index. int next_msg (int *index) { index++; if ((*index) > (MAXBUF - 1)) { (*index) = 0; } return (EXIT_SUCCESS); } ****** end code ****** And the idle function: ****** code ****** // Idle function to add a message to a textview. // This idle function returns 0 in order to stop. gboolean post_message (msgdata *data) { 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); return (G_SOURCE_REMOVE); // This idle function stops when it returns G_SOURCE_REMOVE. } ****** end code ****** 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. As always, any advice is appreciated, Dave _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list