[pjsip] Thread safety problem with pj_thread_is_registered

Bill Gardner billg at wavearts.com
Thu Apr 14 09:49:15 EDT 2016


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. returntrue;
> 10.         }
> 11.     }
> 12. returnfalse;
> 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 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/20160414/1cdbbc53/attachment-0002.html>


More information about the pjsip mailing list