From 56f42d7be8dac65f70ebfa0cc5107d5b8a88ffef Mon Sep 17 00:00:00 2001 From: "B. Bogart" Date: Tue, 10 Aug 2010 22:54:06 +0000 Subject: Fixed a typo in helpfile. Actually (tested) solved stall after code cleanup and memleak solution thanks to Martin Peach and the gphoto devs. This code should be installation ready! svn path=/trunk/externals/bbogart/; revision=13783 --- gphoto/gphoto-help.pd | 4 ++-- gphoto/gphoto.c | 40 ++++++++++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/gphoto/gphoto-help.pd b/gphoto/gphoto-help.pd index 8c99df8..1a8c9be 100644 --- a/gphoto/gphoto-help.pd +++ b/gphoto/gphoto-help.pd @@ -4,7 +4,7 @@ #X msg 29 95 listconfig; #X obj 23 308 gphoto; #X msg 23 70 open; -#X obj 56 331 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 +#X obj 56 331 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X msg 52 274 close; #X msg 47 186 capture test.jpg; @@ -24,7 +24,7 @@ you are using compatible values with: "gphoto2 --get-config zoom") #X text 97 274 Close connection to camera (does not retract lens!) ; #X msg 40 153 setconfig capture 1; -#X msg 52 229 setconfig zoom 60; +#X msg 52 229 setconfig zoom 11; #X connect 0 0 3 0; #X connect 2 0 3 0; #X connect 3 0 1 0; diff --git a/gphoto/gphoto.c b/gphoto/gphoto.c index b17140c..bd01338 100644 --- a/gphoto/gphoto.c +++ b/gphoto/gphoto.c @@ -33,6 +33,7 @@ t_class *gphoto_class; typedef struct gphoto_struct { t_object x_obj; t_outlet *connectedOutlet; + pthread_attr_t threadAttr; //thread attributes, added from DM2 version. Camera *camera; int connected; @@ -68,7 +69,7 @@ void *openCam(void *gphoto) { // Set to connected state. ((gphoto_struct *)gphoto)->connected = 1; - + return(NULL); } @@ -78,7 +79,7 @@ static void wrapOpen(gphoto_struct *gphoto) { pthread_t thread1; // Create thread and pass reference to object struct - ret = pthread_create( &thread1, NULL, openCam, gphoto); + ret = pthread_create( &thread1, &gphoto->threadAttr, openCam, gphoto); return; } @@ -106,7 +107,7 @@ static void wrapClose(gphoto_struct *gphoto) { pthread_t thread1; // Create thread and pass reference to object struct - ret = pthread_create( &thread1, NULL, closeCam, gphoto); + ret = pthread_create( &thread1, &gphoto->threadAttr, closeCam, gphoto); return; } @@ -153,7 +154,9 @@ void *listConfig(void *threadArgs) { // Send bang out 1st outlet when operation is done. sys_lock(); outlet_bang(((gphoto_gimme_struct *)threadArgs)->gphoto->x_obj.ob_outlet); - sys_unlock(); + sys_unlock(); + + free(((gphoto_gimme_struct *)threadArgs)->argv); // suggested by Martin Peach, safe to free() from here when we alloc() from parent? return(NULL); } @@ -172,7 +175,7 @@ static void wrapListConfig(gphoto_struct *gphoto) { threadArgs->gphoto = gphoto; // Create thread - ret = pthread_create( &thread1, NULL, listConfig, threadArgs); + ret = pthread_create( &thread1, &gphoto->threadAttr, listConfig, threadArgs); } else { error("gphoto: ERROR: Not connected."); } @@ -244,6 +247,8 @@ void *getConfig(void *threadArgs) { outlet_bang(((gphoto_gimme_struct *)threadArgs)->gphoto->x_obj.ob_outlet); sys_unlock(); + free(((gphoto_gimme_struct *)threadArgs)->argv); // suggested by Martin Peach, safe to free() from here when we alloc() from parent? + return(NULL); } @@ -265,7 +270,7 @@ static void wrapGetConfig(gphoto_struct *gphoto, t_symbol *s, int argc, t_atom * memcpy(threadArgs->argv, argv, sizeof(*argv)*argc); // copy the arguments into new space. // Create thread - ret = pthread_create( &thread1, NULL, getConfig, threadArgs); + ret = pthread_create( &thread1, &gphoto->threadAttr, getConfig, threadArgs); } else { error("gphoto: ERROR: Not connected."); } @@ -331,6 +336,8 @@ void *setConfig(void *threadArgs) { outlet_bang(((gphoto_gimme_struct *)threadArgs)->gphoto->x_obj.ob_outlet); sys_unlock(); + free(((gphoto_gimme_struct *)threadArgs)->argv); // suggested by Martin Peach, safe to free() from here when we alloc() from parent? + return(NULL); } @@ -353,7 +360,7 @@ static void wrapSetConfig(gphoto_struct *gphoto, t_symbol *s, int argc, t_atom memcpy(threadArgs->argv, argv, sizeof(*argv)*argc); // copy the arguments into new space. // Create thread - ret = pthread_create( &thread1, NULL, setConfig, threadArgs); + ret = pthread_create( &thread1, &gphoto->threadAttr, setConfig, threadArgs); } else { error("gphoto: ERROR: Not connected."); } @@ -382,19 +389,22 @@ void *captureImage(void *threadArgs) { gp_ret = gp_camera_file_get(((gphoto_gimme_struct *)threadArgs)->gphoto->camera, camera_file_path.folder, camera_file_path.name, GP_FILE_TYPE_NORMAL, camerafile, NULL); // get file from camera if (gp_ret != 0) {sys_lock(); error("gphoto: ERROR: %s\n", gp_result_as_string(gp_ret)); sys_unlock(); gp_camera_unref(((gphoto_gimme_struct *)threadArgs)->gphoto->camera); return(NULL);} + + gp_file_unref(camerafile); // clear camerafile gp_ret = gp_camera_file_delete(((gphoto_gimme_struct *)threadArgs)->gphoto->camera, camera_file_path.folder, camera_file_path.name, NULL); if (gp_ret != 0) {sys_lock(); error("gphoto: ERROR: %s\n", gp_result_as_string(gp_ret)); sys_unlock(); gp_camera_unref(((gphoto_gimme_struct *)threadArgs)->gphoto->camera); return(NULL);} - close(fd); // close file descriptor - gp_file_free(camerafile); // free camerafile (needed to avoid fd leaks!) - + //close(fd); // close file descriptor # gphoto devs say this is uneeded. + // Send bang out 2nd outlet when operation is done. sys_lock(); outlet_bang(((gphoto_gimme_struct *)threadArgs)->gphoto->x_obj.ob_outlet); sys_unlock(); - return(NULL); + free(((gphoto_gimme_struct *)threadArgs)->argv); // suggested by Martin Peach, safe to free() from here when we alloc() from parent? + + return(NULL); } // Wrap captureImage @@ -416,7 +426,7 @@ static void wrapCaptureImage(gphoto_struct *gphoto, t_symbol *s, int argc, t_at memcpy(threadArgs->argv, argv, sizeof(*argv)*argc); // copy the arguments into new space. // Create thread - ret = pthread_create( &thread1, NULL, captureImage, threadArgs); + ret = pthread_create( &thread1, &gphoto->threadAttr, captureImage, threadArgs); } else { error("gphoto: ERROR: Not connected."); } @@ -429,6 +439,10 @@ static void *gphoto_new(void) { outlet_new(&gphoto->x_obj, NULL); gphoto->connectedOutlet = outlet_new(&gphoto->x_obj, &s_float); + // When we create a thread, make sure it is deatched, from DM2 version. + pthread_attr_init(&gphoto->threadAttr); + pthread_attr_setdetachstate(&gphoto->threadAttr, PTHREAD_CREATE_DETACHED); + // Initially the external is not "connected" gphoto->connected = 0; @@ -451,5 +465,7 @@ void gphoto_setup(void) { class_addmethod(gphoto_class, (t_method) wrapSetConfig, gensym("setconfig"), A_GIMME, 0); class_addmethod(gphoto_class, (t_method) wrapCaptureImage, gensym("capture"), A_GIMME, 0); class_addmethod(gphoto_class, (t_method) wrapListConfig, gensym("listconfig"), 0); + + post("Gphoto: SVN version w/ gp_file_free()"); } -- cgit v1.2.1