[asterisk-dev] Newbie question about ast_pthread_create_background
Alex Massover
alex at jajah.com
Sat Sep 12 05:35:54 CDT 2009
Hi all!
OMG, I just noticed the difference between ast_strdup() ast_strdupa() ;)
Everything is working for me now! Thanks!
The only concern I still have is about using pbx_builtin_getvar_helper(). Is it always safe to do:
char * my_val= pbx_builtin_getvar_helper(...);
or I need to do:
char * my_val = ast_strdup(pbx_builtin_getvar_helper(...));
I see that my_val still exists inside my detached thread, even after the channel hangup. But is it always safe? When actually the memory that pbx_builtin_getvar_helper() points to freed?
--
Best Regards,
Alex Massover
-----Original Message-----
From: asterisk-dev-bounces at lists.digium.com [mailto:asterisk-dev-bounces at lists.digium.com] On Behalf Of Alex Massover
Sent: Saturday, September 12, 2009 11:49 AM
To: Asterisk Developers Mailing List
Subject: Re: [asterisk-dev] Newbie question about ast_pthread_create_background
Hi Mark!
No, I don't wait for the thread to complete, only to copy the argument structure locally.
I have the structure with semaphore inside:
struct thread_arg {
sem_t mutex;
char * val1;
char * val2;
....
};
In parent thread I do:
struct thread_arg args;
args.val1=my_var1; //populate the structure members
args.val2=my_var2;
.... // same for val3..valx
sem_init(&targs.mutex,0,0); // init the semaphore in blocking state
ast_pthread_create_backgroud(...,...,&thread_function,&args) //create a detached thread
sem_wait(&targs.mutex); //wait for the child thread to save the argument structure locally
sem_destroy(&targs.mutex);
return res;
In the thread_function I have:
void* thread_function (void* targs)
{
struct thread_arg * pargs = (struct thread_arg *) targs;
char *val1=ast_strdupa(pargs->val1);
char *val2=ast_strdupa(pargs->val2);
... // same for val3...valx
sem_post(&(pargs->mutex)); // unlock the semaphore, at this point the parent thread exits
[do the work here]
...
}
Generally it's the same, but this way I don't have to bother with malloc()/free() at all. This is what works for me now.
I even read about something more advanced, instead of having mutex inside my struct, it's written to create another struct with pointer to my original struct and mutex, like this:
struct thread_arg {
char * val1;
char * val2;
...
};
struct wrapper {
struct thread_arg * args;
sem_t mutex;
};
And to pass the pointer to wrapper to the thread. It will allow easier saving the thread_arg locally with memcpy() in the child thread instead of writing
char *val1=ast_strdupa(pargs->val1);
for each structure member.
I'll try to do it with 2 structures next week ;)
--
Best Regards,
Alex Massover
-----Original Message-----
From: asterisk-dev-bounces at lists.digium.com [mailto:asterisk-dev-bounces at lists.digium.com] On Behalf Of Mark Michelson
Sent: Friday, September 11, 2009 5:57 PM
To: Asterisk Developers Mailing List
Subject: Re: [asterisk-dev] Newbie question about ast_pthread_create_background
Alex Massover wrote:
> Hi!
>
> Thank you for spending your time on beginners :)
>
> I'm able to ast_malloc() memory for the thread argument structure, and ast_free() it in the thread. But still have troubles with structure members strings (char *) - it either doesn't pass well or I run into core dumps (memory corruption). But the idea is clear to me now, probably I just don't implement it correctly.
>
> I fixed it differently - with semaphore (no malloc()). I pass a local (stack) structure to the thread and sem_wait() before return. In the thread I copy the data from the stuct to a local variables with ast_strdupa() and sem_post().
> What do you think is it good enough?
>
> On my 1.4 I have only 2 builtins: ast_pthread_create() and ast_pthread_background(). I just pass PTHREAD_CREATE_DETACHED attr to have a detached thread.
>
> --
> Best Regards,
> Alex Massover
If you're going to create a thread and then wait for it to complete before
continuing, why not just call a function instead?
As for the previous problem you had where the individual components of the
malloced structure were garbage, you likely would need to do a deeper copy than
what you had done. In other words, instead of doing something like
my_struct->my_char_ptr = some_auto_char_ptr;
do something like
my_struct->my_char_ptr = ast_strdup(some_auto_char_ptr);
You'd have to make sure to call ast_free on my_struct->my_char_ptr after you are
done with it.
Mark Michelson
_______________________________________________
--Bandwidth and Colocation Provided by http://www.api-digital.com--
AstriCon 2009 - October 13 - 15 Phoenix, Arizona
Register Now: http://www.astricon.net
asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
http://lists.digium.com/mailman/listinfo/asterisk-dev
This mail was received via Mail-SeCure System.
This mail was sent via Mail-SeCure System.
_______________________________________________
--Bandwidth and Colocation Provided by http://www.api-digital.com--
AstriCon 2009 - October 13 - 15 Phoenix, Arizona
Register Now: http://www.astricon.net
asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
http://lists.digium.com/mailman/listinfo/asterisk-dev
This mail was received via Mail-SeCure System.
This mail was sent via Mail-SeCure System.
More information about the asterisk-dev
mailing list