summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2014-08-13 09:14:53 +0000
committerNanang Izzuddin <nanang@teluu.com>2014-08-13 09:14:53 +0000
commit6b29b9ed22824ecb99eafa500b22db20cc9f3d75 (patch)
tree02cd3df1c06d03743c9f60b98c527a0298f769ae
parent23260129fc5c82f99ee7d7c35c787052b9eff261 (diff)
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
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h17
-rw-r--r--pjsip/include/pjsua2/endpoint.hpp20
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c23
-rw-r--r--pjsip/src/pjsua2/endpoint.cpp57
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
@@ -1883,25 +1883,12 @@ 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 <pjsua2/media.hpp>
#include <pjsua2/siptypes.hpp>
#include <list>
+#include <map>
/** 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<pj_thread_t*, pj_thread_desc*> 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 <pjsua2/account.hpp>
-#include <pjsua2/call.hpp>
+#include <pjsua-lib/pjsua_internal.h> /* 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<pj_thread_t*, pj_thread_desc*>::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);
}