From 6b29b9ed22824ecb99eafa500b22db20cc9f3d75 Mon Sep 17 00:00:00 2001 From: Nanang Izzuddin Date: Wed, 13 Aug 2014 09:14:53 +0000 Subject: Close #1779: Add APIs for external/native thread registration to pjsua2: Endpoint::libRegisterThread() & Endpoint::libIsThreadRegistered(). git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4887 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/include/pjsua-lib/pjsua.h | 17 ++---------- pjsip/include/pjsua2/endpoint.hpp | 20 +++++++++++--- pjsip/src/pjsua-lib/pjsua_core.c | 23 ---------------- pjsip/src/pjsua2/endpoint.cpp | 57 ++++++++++++++++++++++++++++++++++++--- 4 files changed, 71 insertions(+), 46 deletions(-) diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index 8e0e3156..a86644c5 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -1882,26 +1882,13 @@ PJ_DECL(pj_status_t) pjsua_destroy2(unsigned flags); PJ_DECL(int) pjsua_handle_events(unsigned msec_timeout); -/** - * Register a thread to poll for events. This function should be - * called by an external worker thread, and it will block polling - * for events until the library is destroyed. - * - * @return PJ_SUCCESS if things are working correctly - * or an error polling cannot be done for some - * reason. - */ -PJ_DECL(pj_status_t) pjsua_register_worker_thread(const char *name); - - /** * Signal all worker threads to quit. This will only wait until internal - * threads are done. For external threads, application must perform - * its own waiting for the external threads to quit from - * pjsua_register_worker_thread() function. + * threads are done. */ PJ_DECL(void) pjsua_stop_worker_threads(void); + /** * Create memory pool to be used by the application. Once application * finished using the pool, it must be released with pj_pool_release(). diff --git a/pjsip/include/pjsua2/endpoint.hpp b/pjsip/include/pjsua2/endpoint.hpp index 5ccd533b..09b27243 100644 --- a/pjsip/include/pjsua2/endpoint.hpp +++ b/pjsip/include/pjsua2/endpoint.hpp @@ -27,6 +27,7 @@ #include #include #include +#include /** PJSUA2 API is inside pj namespace */ namespace pj @@ -721,11 +722,21 @@ public: void libStart() throw(Error); /** - * Register a thread to poll for events. This function should be - * called by an external worker thread, and it will block polling - * for events until the library is destroyed. + * Register a thread that was created by external or native API to the + * library. Note that each time this function is called, it will allocate + * some memory to store the thread description, which will only be freed + * when the library is destroyed. + * + * @param name The optional name to be assigned to the thread. + */ + void libRegisterThread(const string &name) throw(Error); + + /** + * Check if this thread has been registered to the library. Note that + * this function is only applicable for library main & worker threads and + * external/native threads registered using libRegisterThread(). */ - void libRegisterWorkerThread(const string &name) throw(Error); + bool libIsThreadRegistered(); /** * Stop all worker threads. @@ -1172,6 +1183,7 @@ private: AudioMediaVector mediaList; AudDevManager audioDevMgr; CodecInfoVector codecInfoList; + std::map threadDescMap; /* Pending logging */ bool mainThreadOnly; diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index 1d5eae7c..d4fefe3c 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -699,29 +699,6 @@ static int worker_thread(void *arg) return 0; } -PJ_DEF(pj_status_t) pjsua_register_worker_thread(const char *name) -{ - pj_thread_desc desc; - pj_thread_t *thread; - pj_status_t status; - - if (pjsua_var.thread_quit_flag) - return PJ_EGONE; - - status = pj_thread_register(NULL, desc, &thread); - if (status != PJ_SUCCESS) - return status; - - if (name) - PJ_LOG(4,(THIS_FILE, "Worker thread %s started", name)); - - worker_thread(NULL); - - if (name) - PJ_LOG(4,(THIS_FILE, "Worker thread %s stopped", name)); - - return PJ_SUCCESS; -} PJ_DEF(void) pjsua_stop_worker_threads(void) { diff --git a/pjsip/src/pjsua2/endpoint.cpp b/pjsip/src/pjsua2/endpoint.cpp index 77b60b01..e7fcded3 100644 --- a/pjsip/src/pjsua2/endpoint.cpp +++ b/pjsip/src/pjsua2/endpoint.cpp @@ -26,8 +26,7 @@ using namespace pj; using namespace std; -#include -#include +#include /* For retrieving pjsua threads */ #define THIS_FILE "endpoint.cpp" #define MAX_STUN_SERVERS 32 @@ -1217,6 +1216,9 @@ void Endpoint::libCreate() throw(Error) { PJSUA2_CHECK_EXPR( pjsua_create() ); mainThread = pj_thread_this(); + + /* Register library main thread */ + threadDescMap[pj_thread_this()] = NULL; } pjsua_state Endpoint::libGetState() const @@ -1277,6 +1279,23 @@ void Endpoint::libInit(const EpConfig &prmEpConfig) throw(Error) /* Init! */ PJSUA2_CHECK_EXPR( pjsua_init(&ua_cfg, &log_cfg, &med_cfg) ); + + /* Register worker threads */ + int i = pjsua_var.ua_cfg.thread_cnt; + while (i) { + pj_thread_t *t = pjsua_var.thread[--i]; + if (t) + threadDescMap[t] = NULL; + } + + /* Register media endpoint worker thread */ + pjmedia_endpt *medept = pjsua_get_pjmedia_endpt(); + i = pjmedia_endpt_get_thread_count(medept); + while (i) { + pj_thread_t *t = pjmedia_endpt_get_thread(medept, --i); + if (t) + threadDescMap[t] = NULL; + } } void Endpoint::libStart() throw(Error) @@ -1284,9 +1303,30 @@ void Endpoint::libStart() throw(Error) PJSUA2_CHECK_EXPR(pjsua_start()); } -void Endpoint::libRegisterWorkerThread(const string &name) throw(Error) +void Endpoint::libRegisterThread(const string &name) throw(Error) +{ + pj_thread_t *thread; + pj_thread_desc *desc; + pj_status_t status; + + desc = (pj_thread_desc*)malloc(sizeof(pj_thread_desc)); + status = pj_thread_register(name.c_str(), *desc, &thread); + if (status == PJ_SUCCESS) { + threadDescMap[thread] = desc; + } else { + free(desc); + PJSUA2_RAISE_ERROR(status); + } +} + +bool Endpoint::libIsThreadRegistered() { - PJSUA2_CHECK_EXPR(pjsua_register_worker_thread(name.c_str())); + if (pj_thread_is_registered()) { + /* Recheck again if it exists in the thread description map */ + return (threadDescMap.find(pj_thread_this()) != threadDescMap.end()); + } + + return false; } void Endpoint::libStopWorkerThreads() @@ -1315,6 +1355,15 @@ void Endpoint::libDestroy(unsigned flags) throw(Error) } #endif + /* Clean up thread descriptors */ + std::map::iterator i; + for (i = threadDescMap.begin(); i != threadDescMap.end(); ++i) { + pj_thread_desc* d = (*i).second; + if (d != NULL) + free(d); + } + threadDescMap.clear(); + PJSUA2_CHECK_RAISE_ERROR(status); } -- cgit v1.2.3