[pjsip] Thread safety problem with pj_thread_is_registered

屈振华 qzhua3 at gmail.com
Wed Apr 20 20:54:38 EDT 2016


​Bill​,

Thank you for timely respone.
It seems that I was confused by the way that pj_thread_desc was defined.

> typedef long pj_thread_desc
<http://www.pjsip.org/pjlib/docs/html/group__PJ__THREAD.htm#ga145dba91437211fe7b768573c14268bb>
[(64)

I add an list to maintain the pj_thread_desc and solve the problem. Thank
your!

2016-04-14 21:49 GMT+08:00 Bill Gardner <billg at wavearts.com>:

> You need to allocate memory for the thread_desc on the heap. Your code was
> allocating it on the stack, where it would be overwritten after your
> function returned.  I posted some example code to the list some time ago. -
> Bill
>
>
> On 4/13/2016 10:33 PM, 屈振华 wrote:
>
> ​​When using pjlib in  threads  other than pj created, I found these
> errors:
>
>     pj_assert(!"Calling pjlib from unknown/external thread. You must "
>            "register external threads with pj_thread_register() "
>            "before calling any pjlib functions.");
>     }
>
> ​I found some solution on the web ,
>
>    1. bool ice_register_thread()
>    2. {
>    3.     if(!pj_thread_is_registered())
>    4.     {
>    5.         pj_thread_desc desc;
>    6.         pj_thread_t* thed;
>    7.         if (pj_thread_register(NULL,desc,&thed) == PJ_SUCCESS)
>    8.         {
>    9.             return true;
>    10.         }
>    11.     }
>    12.     return false;
>    13. }
>
> ​ But this is risky in practice. I found the pj_thread_register in
> os_core_unix.c​ has converted the  input parameter pj_thread_desc desc to
> (pj_thread_t *) and uses it as a pointer to access signature, signature2,
> thread and obj_name.
> ​   So the above code is will cause illegal memory access. ​ I tried to
> solve this problem by defining :
>  > pj_thread_t thread;
>  > pj_thread_desc desc=(pj_thread_desc)&thread;
> However, it has compiling errors: incomplete type 'pj_thread_t', scince
> this data type is only internally defined in os_core_unix.c and and cannot
> be used from outside.
>
> So what is the right way to perform pj_thread_register ?​
>
> PJ_DEF(pj_status_t) pj_thread_register ( const char *cstr_thread_name,
>                      pj_thread_desc desc,
>                      pj_thread_t **ptr_thread)
> {
>
> #if PJ_HAS_THREADS
>     char stack_ptr;
>     pj_status_t rc;
>     pj_thread_t *thread = (pj_thread_t *)desc;
>     pj_str_t thread_name = pj_str((char*)cstr_thread_name);
>
>     /* Size sanity check. */
>     if (sizeof(pj_thread_desc) < sizeof(pj_thread_t)) {
>     pj_assert(!"Not enough pj_thread_desc size!");
>     return PJ_EBUG;
>     }
>
>     /* Warn if this thread has been registered before */
>     if (pj_thread_local_get (thread_tls_id) != 0) {
>     // 2006-02-26 bennylp:
>     //  This wouldn't work in all cases!.
>     //  If thread is created by external module (e.g. sound thread),
>     //  thread may be reused while the pool used for the thread descriptor
>     //  has been deleted by application.
>     //*thread_ptr = (pj_thread_t*)pj_thread_local_get (thread_tls_id);
>         //return PJ_SUCCESS;
>     PJ_LOG(4,(THIS_FILE, "Info: possibly re-registering existing "
>                  "thread"));
>     }
>
>     /* On the other hand, also warn if the thread descriptor buffer seem to
>      * have been used to register other threads.
>      */
>     pj_assert(thread->signature1 != SIGNATURE1 ||
>           thread->signature2 != SIGNATURE2 ||
>           (thread->thread == pthread_self()));
>
>     /* Initialize and set the thread entry. */
>     pj_bzero(desc, sizeof(struct pj_thread_t));
>     thread->thread = pthread_self();
>     thread->signature1 = SIGNATURE1;
>     thread->signature2 = SIGNATURE2;
>
>     if(cstr_thread_name && pj_strlen(&thread_name) <
> sizeof(thread->obj_name)-1)
>     pj_ansi_snprintf(thread->obj_name, sizeof(thread->obj_name),
>              cstr_thread_name, thread->thread);
>     else
>     pj_ansi_snprintf(thread->obj_name, sizeof(thread->obj_name),
>              "thr%p", (void*)thread->thread);
>
>     rc = pj_thread_local_set(thread_tls_id, thread);
>     if (rc != PJ_SUCCESS) {
>     pj_bzero(desc, sizeof(struct pj_thread_t));
>     return rc;
>     }
>
>
>
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing listpjsip at lists.pjsip.orghttp://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
>
>
>
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing list
> pjsip at lists.pjsip.org
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/attachments/20160421/624cced0/attachment-0002.html>


More information about the pjsip mailing list