Hey all,
I've got some simple threading code working, and it looks like that will fix my HUP issues with PD and my gphoto external.
Problem I'm having is that I need to pass thread arguments as a pointer to a structure.
Are there some PD types I can use to make this work? (A_GIMME?)
Or do I need to make struct that holds the *argv argc stuff, pass that structure to the thread, and have it unpack the content?
Also my code function that executes the thread does not wait for the threads to complete.
What is the best way to make my object output a bang when the thread is complete?
Any advice appreciated.
Thanks, B.
I figured that doing this with a PD type was unlikely, so I started messing with creating a structure for my args and passing a pointer to that.
So I have defined my structure for a single float arg:
struct floatArgStruct { gphoto2_struct *gphoto2; t_symbol *s; };
just under the typedef for the external structure. (Is the external struct a better place for its def?)
Then the function that is executed from the PD selector:
static void wrapGetConfig(gphoto2_struct *gphoto2, t_symbol *s) { int ret; pthread_t thread1;
// instance of structure struct floatArgStruct threadArgs;
// packaging arguments into structure threadArgs.gphoto2 = gphoto2; threadArgs.s = s;
post("I'm about to start the thread.");
// Create thread ret = pthread_create( &thread1, NULL, mythread, (void *)threadArgs); }
which populates the structure, and starts the thread. The struct stuff appears to work here)
Above this is the def of the function that is to execute in the thread:
void *mythread(struct floatArgStruct *threadArgs) { int i; post("thread start.");
post("My symbol: %s", threadArgs.s->s_name); // line 92 outlet_float(threadArgs.gphoto2->x_obj.ob_outlet, 0.00001);
post("thread end."); }
The errors I'm confused about are:
gphoto2.c:92: error: request for member 's' in something not a structure or union gphoto2.c:93: error: request for member 'gphoto2' in something not a structure or union
Which means that the structure is not being passed to the thread code correctly, as its not recognized as a structure.
Next gcc complains about the way I'm initiating the thread:
gphoto2.c:112: error: cannot convert to a pointer type gphoto2.c:112: warning: passing argument 3 of 'pthread_create' from incompatible pointer type
In the tutorial the function args were cast as (void *) which does not seem to be working in this case.
Does anyone have any code that does this kind of job I could look at?
Or is it obvious I'm doing something really wrong?
This is my first exploration into threads and custom structs (not counting the external struct) so I may have it totally wrong.
Thanks, B.
B. Bogart wrote:
Hey all,
I've got some simple threading code working, and it looks like that will fix my HUP issues with PD and my gphoto external.
Problem I'm having is that I need to pass thread arguments as a pointer to a structure.
Are there some PD types I can use to make this work? (A_GIMME?)
Or do I need to make struct that holds the *argv argc stuff, pass that structure to the thread, and have it unpack the content?
Also my code function that executes the thread does not wait for the threads to complete.
What is the best way to make my object output a bang when the thread is complete?
Any advice appreciated.
Thanks, B.
B. Bogart wrote:
I figured that doing this with a PD type was unlikely, so I started messing with creating a structure for my args and passing a pointer to that.
So I have defined my structure for a single float arg:
struct floatArgStruct { gphoto2_struct *gphoto2; t_symbol *s; };
just under the typedef for the external structure. (Is the external struct a better place for its def?)
Then the function that is executed from the PD selector:
static void wrapGetConfig(gphoto2_struct *gphoto2, t_symbol *s) { int ret; pthread_t thread1;
// instance of structure struct floatArgStruct threadArgs;
// packaging arguments into structure threadArgs.gphoto2 = gphoto2; threadArgs.s = s;
post("I'm about to start the thread.");
// Create thread ret = pthread_create( &thread1, NULL, mythread, (void *)threadArgs); }
which populates the structure, and starts the thread. The struct stuff appears to work here)
Above this is the def of the function that is to execute in the thread:
void *mythread(struct floatArgStruct *threadArgs) { int i; post("thread start.");
post("My symbol: %s", threadArgs.s->s_name); // line 92
threadArgs is a pointer, '.' is only for structs/unions
try '->' instead of '.' to both dereference pointer and access member
outlet_float(threadArgs.gphoto2->x_obj.ob_outlet, 0.00001);
post("thread end."); }
The errors I'm confused about are:
gphoto2.c:92: error: request for member 's' in something not a structure or union gphoto2.c:93: error: request for member 'gphoto2' in something not a structure or union
Which means that the structure is not being passed to the thread code correctly, as its not recognized as a structure.
Next gcc complains about the way I'm initiating the thread:
gphoto2.c:112: error: cannot convert to a pointer type gphoto2.c:112: warning: passing argument 3 of 'pthread_create' from incompatible pointer type
In the tutorial the function args were cast as (void *) which does not seem to be working in this case.
Does anyone have any code that does this kind of job I could look at?
Or is it obvious I'm doing something really wrong?
This is my first exploration into threads and custom structs (not counting the external struct) so I may have it totally wrong.
Thanks, B.
B. Bogart wrote:
Hey all,
I've got some simple threading code working, and it looks like that will fix my HUP issues with PD and my gphoto external.
Problem I'm having is that I need to pass thread arguments as a pointer to a structure.
Are there some PD types I can use to make this work? (A_GIMME?)
Or do I need to make struct that holds the *argv argc stuff, pass that structure to the thread, and have it unpack the content?
Also my code function that executes the thread does not wait for the threads to complete.
What is the best way to make my object output a bang when the thread is complete?
Any advice appreciated.
Thanks, B.
Pd-dev mailing list Pd-dev@iem.at http://lists.puredata.info/listinfo/pd-dev
Thanks Claude!
I got lots of help from Matju on IRC so things are compiling.
I'm now getting a segfault when trying to access a member of the structure in the thread function:
#0 0xf7d531cb in strlen () from /lib/i686/cmov/libc.so.6 #1 0xf7d1f648 in vfprintf () from /lib/i686/cmov/libc.so.6 #2 0xf7d43e04 in vsnprintf () from /lib/i686/cmov/libc.so.6 #3 0x080c68d6 in post (fmt=0xf7f7db5a "My symbol: %s") at s_print.c:51 #4 0xf7f7d829 in mythread () from /home/bbogart/src/gphoto/src/pd-external/gphoto2.pd_linux
The way I'm trying to access the member is as follows:
post("My symbol: %s", ((struct floatArgStruct *)threadArgs)->s->s_name);
I've attached the full source.
All this typdef stuff is new to me, so I may have messed up something obvious.
Thanks, .b.
Claude Heiland-Allen wrote:
post("My symbol: %s", threadArgs.s->s_name); // line 92
threadArgs is a pointer, '.' is only for structs/unions
try '->' instead of '.' to both dereference pointer and access member
B. Bogart wrote:
I'm now getting a segfault when trying to access a member of the structure in the thread function:
#0 0xf7d531cb in strlen () from /lib/i686/cmov/libc.so.6 #1 0xf7d1f648 in vfprintf () from /lib/i686/cmov/libc.so.6 #2 0xf7d43e04 in vsnprintf () from /lib/i686/cmov/libc.so.6 #3 0x080c68d6 in post (fmt=0xf7f7db5a "My symbol: %s") at s_print.c:51 #4 0xf7f7d829 in mythread () from /home/bbogart/src/gphoto/src/pd-external/gphoto2.pd_linux
The way I'm trying to access the member is as follows:
post("My symbol: %s", ((struct floatArgStruct *)threadArgs)->s->s_name);
You called pthread_create() with &threadargs: ret = pthread_create( &thread1, NULL, mythread, &threadArgs); when you probably should just use threadargs, since it's already a pointer. Or else you need to dereference the handle: post("My symbol: %s", ((*(struct floatArgStruct**))threadArgs)->s->s_name);
Martin
On Fri, 27 Feb 2009, Martin Peach wrote:
You called pthread_create() with &threadargs: ret = pthread_create( &thread1, NULL, mythread, &threadArgs); when you probably should just use threadargs, since it's already a pointer. Or else you need to dereference the handle: post("My symbol: %s", ((*(struct floatArgStruct**))threadArgs)->s->s_name);
No, it was supposed to be just threadArgs, but the type of threadArgs changed while writing the code, as I made him change it from a global variable to a malloc. In the end, it turns out it wasn't quite useful, because there's only going to be one extra thread, after all.
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801, Montréal, Québec
Mathieu Bouchard wrote:
On Fri, 27 Feb 2009, Martin Peach wrote:
You called pthread_create() with &threadargs: ret = pthread_create( &thread1, NULL, mythread, &threadArgs); when you probably should just use threadargs, since it's already a pointer. Or else you need to dereference the handle: post("My symbol: %s", ((*(struct floatArgStruct**))threadArgs)->s->s_name);
No, it was supposed to be just threadArgs, but the type of threadArgs changed while writing the code, as I made him change it from a global variable to a malloc. In the end, it turns out it wasn't quite useful, because there's only going to be one extra thread, after all.
Too bad, you could have tested if the compiler could handle types changing while the code was being written.
Martin
On Fri, 27 Feb 2009, Martin Peach wrote:
Too bad, you could have tested if the compiler could handle types changing while the code was being written.
rofl :)
I'm sure that there's a compsci department somewhere in the world where someone is writing a thesis about a type theory that would handle that case. Actually, I'd almost bet that this has already happened.
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801, Montréal, Québec