Re: Still confused on new thread starting idle functions to update UI.





On Tue, 3 Dec 2013 19:59:22 -0800 (PST)
David Buchan <pdbuchan yahoo com> wrote:
ok, I may be getting somewhere. I did some reading on heap memory
versus stack.

Here's a vastly simplified example program which doesn't use GTK+,
but I'm using to demonstrate my plan of attack.

I use a function called packit() which allows me to still use
strdup().

Comments?

Dave


Valgrind is happy with this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

typedef struct _msgdata msgdatas;
struct _msgdata {
  char *message;
  int *textview;
};

msgdatas *packit (msgdatas *, char *);
int myfunc (msgdatas *);

int
main (int argc, char ** argv)
{
  int i;
  char *message;
  msgdatas *msgdata;

  // Allocate memory on the heap, not stack.
  msgdata = (msgdatas *) malloc (1 * sizeof (msgdatas));
  msgdata->textview = (int *) malloc (1 * sizeof (int));
  message = (char *) malloc (1024);

  // Main loop.
  for (i=0; i<100; i++) {
    sprintf (message, "%i Dave is here.", i);  // In reality, this is
a more complicated sprintf().

    *(msgdata->textview) = 7;  // This is a stand-in for a pointer to
a textview. myfunc (packit (msgdata, strdup (message)));  // strdup()
allocates memory for message on the heap.

    sprintf (message, "%i Dave is no longer here.", i);  // In
reality, this is a more complicated sprintf().

    *(msgdata->textview) = 3;  // This is a stand-in for a pointer to
a textview; only changed for fun. myfunc (packit (msgdata, strdup
(message)));  // strdup() allocates memory for message on the heap. }

  // Don't free msgdata->message; it gets free'd by myfunc().
  free (msgdata->textview);
  free (msgdata);
  free (message);

  return (EXIT_SUCCESS);
}

msgdatas *
packit (msgdatas *msgdata, char *message)
{
  msgdata->message = message;

  return (msgdata);
}

// This is a stand-in for an idle function which would update the
textview in the UI. int  // Would really be gboolean
myfunc (msgdatas *data)
{
  printf ("Pointer to textview: %i\n", *(data->textview));
  printf ("message: %s\n", data->message);

  // Only free the element "message" of msgdatas struct.
  free (data->message);

  return (EXIT_SUCCESS);  // Would really be return (G_SOURCE_REMOVE)
}

I don't really understand what you are trying to do.  It seems bizarre
to allocate a pointer to a textview on the heap (it seems completely
unnecessary), and even more bizarre then to free it again in the same
thread.  In fact I have no idea why you are passing a pointer to a text
view at all: that sounds like shared data (you shouldn't create a
GtkTextView except in the main loop thread), which may defeat part of
the purpose of the exercise.  If the worker thread can see the textview
then presumably so can the main thread.  If myfunc() is a stand-in for
g_idle_add(), then there is also a clear error in freeing msgdata and
its textview member in main(), and using these in myfunc(). You should
free the struct and any of its members which need freeing in myfunc()
(the g_idle_add() stand-in). Furthermore your call to strdup() is
completely unnecessary as 'message' has already been allocated on the

heap.

I may be wrong but I get the impression you do not know much about C.
You need to take some basic tuition on the use of C pointers and on
memory allocation as a minimum.  Learning C is a good thing to do if
you are serious about programming but you cannot run until you can
walk.  I would caution you against trying to program with threads,
which bring in a host of new issues concerning synchronization, at your
level of understanding.  Having said that, if you want to plough on
regardless, then good on you, as you need to start somewhere and learn
from there.  Possibly you already know about how to use threads safely
from another language, in which case fine.

Otherwise, have you considered perhaps using something like the python
bindings for GTK+?  These have a binding for g_idle_add() and handle
all the memory allocation for you.  I recommend using the
gobject-introspection binding for GTK+-3 rather than the old pygtk for
GTK+-2.  Python is another language which is worth learning.  There are
also introspection bindings for javascript if you prefer that (although
you won't be able to use threads in javascript - but that may be an
advantage for you).

Chris

====================
The example above has main() calling the idle function, but in reality, it's a thread. That thread receives a 
pointer to the textview from main(). The idle function needs to access the textview, but it needs 
g_idle_add() to send a pointer to the textview to it, otherwise it won't be able to access it. But it also 
needs access to the message, thus I pack the two items in a struct.

For the purposes of demonstration, the int is standing-in for a textview. I don't really allocate it as you 
see in this example. I'm just trying to show I can pass the two items in a struct using packit().

I didn't think my C was that bad. :o(
Dave


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]