> typedef long pj_thread_desc[(64)
I add an list to maintain the pj_thread_desc and solve the problem. Thank your!
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 ,
- bool ice_register_thread()
- {
- if(!pj_thread_is_registered())
- {
- pj_thread_desc desc;
- pj_thread_t* thed;
- if (pj_thread_register(NULL,desc,&thed) == PJ_SUCCESS)
- {
- return true;
- }
- }
- return false;
- }
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@xxxxxxxxxxxxxxx http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
_______________________________________________
Visit our blog: http://blog.pjsip.org
pjsip mailing list
pjsip@xxxxxxxxxxxxxxx
http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
_______________________________________________ Visit our blog: http://blog.pjsip.org pjsip mailing list pjsip@xxxxxxxxxxxxxxx http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org