diff --git a/media/webrtc/signaling/signaling.gyp b/media/webrtc/signaling/signaling.gyp index 1d6783f023c3..2a91e3d2b7fb 100644 --- a/media/webrtc/signaling/signaling.gyp +++ b/media/webrtc/signaling/signaling.gyp @@ -14,7 +14,7 @@ }, 'targets': [ - + # # ECC # @@ -53,8 +53,8 @@ '../../../netwerk/srtp/src/include', '../../../netwerk/srtp/src/crypto/include', '../../../ipc/chromium/src', - ], - + ], + # # DEPENDENCIES # @@ -63,13 +63,13 @@ 'export_dependent_settings': [ ], - - + + # # SOURCES # 'sources': [ - # Media Conduit + # Media Conduit './src/media-conduit/AudioConduit.h', './src/media-conduit/AudioConduit.cpp', './src/media-conduit/VideoConduit.h', @@ -143,15 +143,15 @@ './src/mediapipeline/SrtpFlow.h', './src/mediapipeline/SrtpFlow.cpp', ], - + # # DEFINES # - + 'defines' : [ - 'LOG4CXX_STATIC', - '_NO_LOG4CXX', - 'USE_SSLEAY', + 'LOG4CXX_STATIC', + '_NO_LOG4CXX', + 'USE_SSLEAY', '_CPR_USE_EXTERNAL_LOGGER', 'WEBRTC_RELATIVE_PATH', 'HAVE_WEBRTC_VIDEO', @@ -177,7 +177,7 @@ 'defines' : [ 'MOZILLA_INTERNAL_API' ], - }], + }], ['build_for_test!=0', { 'include_dirs': [ './test' @@ -186,7 +186,7 @@ 'NO_CHROMIUM_LOGGING', 'USE_FAKE_MEDIA_STREAMS' ], - }], + }], ['(OS=="linux") or (OS=="android")', { 'include_dirs': [ ], @@ -194,26 +194,26 @@ 'defines': [ 'SIP_OS_LINUX', '_GNU_SOURCE', - 'LINUX', - 'GIPS_VER=3510', + 'LINUX', + 'GIPS_VER=3510', 'SECLIB_OPENSSL', ], - + 'cflags_mozilla': [ ], }], ['OS=="win"', { 'include_dirs': [ - ], + ], 'defines': [ 'SIP_OS_WINDOWS', - 'WIN32', + 'WIN32', 'GIPS_VER=3480', 'SIPCC_BUILD', 'HAVE_WINSOCK2_H', 'CPR_STDINT_INCLUDE=\\"mozilla/StandardInteger.h\\"' ], - + 'cflags_mozilla': [ ], }], @@ -222,23 +222,23 @@ ], 'defines': [ 'SIP_OS_OSX', - 'OSX', + 'OSX', '_FORTIFY_SOURCE=2', ], - + 'cflags_mozilla': [ ], }], ], }, - + # # SIPCC # { 'target_name': 'sipcc', 'type': 'static_library', - + # # INCLUDES # @@ -261,18 +261,18 @@ # Danger: this is to include config.h. This could be bad. '../trunk/third_party/libsrtp/config', ], - + # # DEPENDENCIES # 'dependencies': [ ], - - + + 'export_dependent_settings': [ ], - - + + # # SOURCES # @@ -280,7 +280,7 @@ # CCAPP './src/sipcc/core/ccapp/call_logger.c', './src/sipcc/core/ccapp/call_logger.h', - './src/sipcc/core/ccapp/capability_set.c', + './src/sipcc/core/ccapp/capability_set.c', './src/sipcc/core/ccapp/capability_set.h', './src/sipcc/core/ccapp/cc_blf.c', './src/sipcc/core/ccapp/cc_call_feature.c', @@ -332,6 +332,8 @@ './src/sipcc/core/common/subscription_handler.h', './src/sipcc/core/common/text_strings.c', './src/sipcc/core/common/text_strings.h', + './src/sipcc/core/common/thread_monitor.h', + './src/sipcc/core/common/thread_monitor.c', './src/sipcc/core/common/ui.c', # GSM './src/sipcc/core/gsm/ccapi.c', @@ -567,7 +569,7 @@ # PLAT './src/sipcc/plat/csf2g/model.c', './src/sipcc/plat/csf2g/reset_api.c', - # + # # './src/sipcc/plat/common/plat_debug.h', # './src/sipcc/plat/common/tnp_blf.h', @@ -580,7 +582,7 @@ # # DEFINES # - + 'defines' : [ # CPR timers are needed by SIP, but are disabled for now # to avoid the extra timer thread and stale cleanup code @@ -694,18 +696,18 @@ ['OS=="win"', { 'include_dirs': [ ], - + 'sources': [ # SIPSTACK './src/sipcc/core/sipstack/sip_platform_win32_task.c', - + # PLAT './src/sipcc/plat/win32/dns_utils.c', './src/sipcc/plat/win32/mystub.c', './src/sipcc/plat/win32/plat_api_stub.c', './src/sipcc/plat/win32/plat_api_win.c', './src/sipcc/plat/win32/StdAfx.h', - + # CPR './src/sipcc/cpr/win32/cpr_win_assert.h', './src/sipcc/cpr/win32/cpr_win_debug.c', @@ -735,36 +737,36 @@ './src/sipcc/cpr/win32/cpr_win_types.h', ], - + 'defines' : [ 'SIP_OS_WINDOWS', - 'WIN32', + 'WIN32', 'SIPCC_BUILD', 'SDP_WIN32', 'STUBBED_OUT', 'EXTERNAL_TICK_REQUIRED', 'GIPS_VER=3480', ], - + 'cflags_mozilla': [ ], - + }], ['OS=="mac"', { 'include_dirs': [ ], - + 'sources': [ # SIPSTACK './src/sipcc/core/sipstack/sip_platform_task.c', - + # PLAT './src/sipcc/plat/common/dns_utils.c', #'./src/sipcc/plat/darwin/netif.c', './src/sipcc/plat/darwin/plat_api_stub.c', #'./src/sipcc/plat/unix-common/random.c', - + # CPR './src/sipcc/cpr/darwin/cpr_darwin_assert.h', './src/sipcc/cpr/darwin/cpr_darwin_errno.c', @@ -791,7 +793,7 @@ './src/sipcc/cpr/darwin/cpr_darwin_tst.h', './src/sipcc/cpr/darwin/cpr_darwin_types.h', ], - + 'defines' : [ 'SIP_OS_OSX', @@ -805,12 +807,12 @@ '_DARWIN_C_SOURCE', 'NO_NSPR_10_SUPPORT', ], - + 'cflags_mozilla': [ ], }], ], - + }, ], } diff --git a/media/webrtc/signaling/src/sipcc/core/common/init.c b/media/webrtc/signaling/src/sipcc/core/common/init.c index 2ebf10503bb5..7ff2dfca37e5 100755 --- a/media/webrtc/signaling/src/sipcc/core/common/init.c +++ b/media/webrtc/signaling/src/sipcc/core/common/init.c @@ -21,6 +21,8 @@ #include "misc_apps_task.h" #include "plat_api.h" #include "ccapp_task.h" +#include "thread_monitor.h" +#include "mozilla/Assertions.h" #include "phone_platform_constants.h" /** The following defines are used to tune the total memory that pSIPCC @@ -266,7 +268,10 @@ thread_init () ccapp_thread = cprCreateThread("CCAPP Task", (cprThreadStartRoutine) CCApp_task, GSMSTKSZ, CCPROVIDER_THREAD_RELATIVE_PRIORITY /* pri */, ccapp_msgq); - if (ccapp_thread == NULL) { + MOZ_ASSERT(ccapp_thread); + if (ccapp_thread) { + thread_started(THREADMON_CCAPP, ccapp_thread); + } else { err_msg("failed to create CCAPP task \n"); } @@ -286,7 +291,10 @@ thread_init () sip_thread = cprCreateThread("SIPStack task", (cprThreadStartRoutine) sip_platform_task_loop, STKSZ, SIP_THREAD_RELATIVE_PRIORITY /* pri */, sip_msgq); - if (sip_thread == NULL) { + MOZ_ASSERT(sip_thread); + if (sip_thread) { + thread_started(THREADMON_SIP, sip_thread); + } else { err_msg("failed to create sip task \n"); } @@ -296,7 +304,10 @@ thread_init () (cprThreadStartRoutine) sip_platform_task_msgqwait, STKSZ, SIP_THREAD_RELATIVE_PRIORITY /* pri */, sip_msgq); - if (sip_msgqwait_thread == NULL) { + MOZ_ASSERT(sip_msgqwait_thread); + if (sip_msgqwait_thread) { + thread_started(THREADMON_MSGQ, sip_msgqwait_thread); + } else { err_msg("failed to create sip message queue wait task\n"); } #endif @@ -304,7 +315,10 @@ thread_init () gsm_thread = cprCreateThread("GSM Task", (cprThreadStartRoutine) GSMTask, GSMSTKSZ, GSM_THREAD_RELATIVE_PRIORITY /* pri */, gsm_msgq); - if (gsm_thread == NULL) { + MOZ_ASSERT(gsm_thread); + if (gsm_thread) { + thread_started(THREADMON_GSM, gsm_thread); + } else { err_msg("failed to create gsm task \n"); } @@ -569,8 +583,11 @@ ccUnload (void) send_task_unload_msg(CC_SRC_CCAPP); - cprSleep(200); - gStopTickTask = TRUE; + + /* + * Here we are waiting until all threads that were started exit. + */ + join_all_threads(); } diff --git a/media/webrtc/signaling/src/sipcc/core/common/thread_monitor.c b/media/webrtc/signaling/src/sipcc/core/common/thread_monitor.c new file mode 100644 index 000000000000..91a8e6e1bc0d --- /dev/null +++ b/media/webrtc/signaling/src/sipcc/core/common/thread_monitor.c @@ -0,0 +1,51 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "cpr_types.h" +#include "cpr_stdlib.h" +#include "thread_monitor.h" +#include "prtypes.h" +#include "mozilla/Assertions.h" + +/* + * If thread is running, should have a non-zero entry here that is the threadId + */ +static cprThread_t thread_list[THREADMON_MAX]; + +/* + * thread_started + * + * Should be called exactly once for each thread created. + * + * @param[in] monitor_id - enum of which thread created + * @param[in] thread - created thread + */ +void thread_started(thread_monitor_id_t monitor_id, cprThread_t thread) { + MOZ_ASSERT(monitor_id < THREADMON_MAX); + if (monitor_id >= THREADMON_MAX) { + return; + } + + /* Should not already be started */ + MOZ_ASSERT(thread_list[monitor_id] == NULL); + + thread_list[monitor_id] = thread; +} + +/* + * join_all_threads + * + * Join all threads that were started. + */ +void join_all_threads() { + int i; + + for (i = 0; i < THREADMON_MAX; i++) { + if (thread_list[i] != NULL) { + cprJoinThread(thread_list[i]); + cpr_free(thread_list[i]); + thread_list[i] = NULL; + } + } +} diff --git a/media/webrtc/signaling/src/sipcc/core/common/thread_monitor.h b/media/webrtc/signaling/src/sipcc/core/common/thread_monitor.h new file mode 100644 index 000000000000..bd6970667286 --- /dev/null +++ b/media/webrtc/signaling/src/sipcc/core/common/thread_monitor.h @@ -0,0 +1,40 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef THREAD_MONITOR_H_ +#define THREAD_MONITOR_H_ + +#include "cpr_threads.h" + +/* + * This should be a list of threads that could be created by SIPCC + * On Windows, the MSGQ thread is not started. + */ +typedef enum { + THREADMON_CCAPP, + THREADMON_SIP, + THREADMON_MSGQ, + THREADMON_GSM, + THREADMON_MAX +} thread_monitor_id_t; + +/* + * thread_started + * + * Should be called exactly once for each thread created. + * + * @param[in] monitor_id - enum of which thread created + * @param[in] thread - created thread + */ +void thread_started(thread_monitor_id_t monitor_id, cprThread_t thread); + +/* + * join_all_threads + * + * Join all threads that were started. + */ +void join_all_threads(); + +#endif + diff --git a/media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_threads.c b/media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_threads.c index 2be26dc66648..f1f349b5ffb0 100644 --- a/media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_threads.c +++ b/media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_threads.c @@ -9,6 +9,9 @@ #include #include #include +#include "thread_monitor.h" +#include "prtypes.h" +#include "mozilla/Assertions.h" #define ANDROID_MIN_THREAD_PRIORITY (-20) /* tbd: check MV linux: current val from Larry port */ #define ANDROID_MAX_THREAD_PRIORITY (+19) /* tbd: check MV linux. current val from Larry port */ @@ -99,6 +102,19 @@ cprCreateThread (const char *name, return (cprThread_t)NULL; } +/* + * cprJoinThread + * + * wait for thread termination + */ +void cprJoinThread(cprThread_t thread) +{ + cpr_thread_t *cprThreadPtr; + + cprThreadPtr = (cpr_thread_t *) thread; + MOZ_ASSERT(cprThreadPtr); + pthread_join(cprThreadPtr->u.handleInt, NULL); +} /** * cprDestroyThread @@ -118,29 +134,28 @@ cprCreateThread (const char *name, cprRC_t cprDestroyThread (cprThread_t thread) { - static const char fname[] = "cprDestroyThread"; cpr_thread_t *cprThreadPtr; cprThreadPtr = (cpr_thread_t *) thread; - if (cprThreadPtr != NULL) { + if (cprThreadPtr) { /* * Make sure thread is trying to destroy itself. */ if ((pthread_t) cprThreadPtr->u.handleInt == pthread_self()) { - cprThreadPtr->threadId = 0; - cpr_free(cprThreadPtr); + CPR_INFO("%s: Destroying Thread %d", __FUNCTION__, cprThreadPtr->threadId); pthread_exit(NULL); return CPR_SUCCESS; } - CPR_ERROR("%s: Thread attempted to destroy another thread, not itself.\n", - fname); + CPR_ERROR("%s: Thread attempted to destroy another thread, not itself.", + __FUNCTION__); + MOZ_ASSERT(PR_FALSE); errno = EINVAL; return CPR_FAILURE; } - /* Bad application! */ - CPR_ERROR("%s - NULL pointer passed in.\n", fname); + CPR_ERROR("%s - NULL pointer passed in.", __FUNCTION__); + MOZ_ASSERT(PR_FALSE); errno = EINVAL; return CPR_FAILURE; } diff --git a/media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_threads.c b/media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_threads.c index ac7ce8ac122a..d65e3ea0c9fa 100644 --- a/media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_threads.c +++ b/media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_threads.c @@ -9,6 +9,10 @@ #include #include #include +#include "thread_monitor.h" +#include "prtypes.h" +#include "mozilla/Assertions.h" + #define LINUX_MIN_THREAD_PRIORITY (-20) /* tbd: check MV linux: current val from Larry port */ #define LINUX_MAX_THREAD_PRIORITY (+19) /* tbd: check MV linux. current val from Larry port */ @@ -99,6 +103,19 @@ cprCreateThread (const char *name, return (cprThread_t)NULL; } +/* + * cprJoinThread + * + * wait for thread termination + */ +void cprJoinThread(cprThread_t thread) +{ + cpr_thread_t *cprThreadPtr; + + cprThreadPtr = (cpr_thread_t *) thread; + MOZ_ASSERT(cprThreadPtr); + pthread_join(cprThreadPtr->u.handleInt, NULL); +} /** * cprDestroyThread @@ -118,29 +135,28 @@ cprCreateThread (const char *name, cprRC_t cprDestroyThread (cprThread_t thread) { - static const char fname[] = "cprDestroyThread"; cpr_thread_t *cprThreadPtr; cprThreadPtr = (cpr_thread_t *) thread; - if (cprThreadPtr != NULL) { + if (cprThreadPtr) { /* * Make sure thread is trying to destroy itself. */ if (cprThreadPtr->u.handlePtr == (void*) pthread_self()) { - cprThreadPtr->threadId = 0; - cpr_free(cprThreadPtr); + CPR_INFO("%s: Destroying Thread %d", __FUNCTION__, cprThreadPtr->threadId); pthread_exit(NULL); return CPR_SUCCESS; } - CPR_ERROR("%s: Thread attempted to destroy another thread, not itself.\n", - fname); + CPR_ERROR("%s: Thread attempted to destroy another thread, not itself.", + __FUNCTION__); + MOZ_ASSERT(PR_FALSE); errno = EINVAL; return CPR_FAILURE; } - /* Bad application! */ - CPR_ERROR("%s - NULL pointer passed in.\n", fname); + CPR_ERROR("%s - NULL pointer passed in.", __FUNCTION__); + MOZ_ASSERT(PR_FALSE); errno = EINVAL; return CPR_FAILURE; } diff --git a/media/webrtc/signaling/src/sipcc/cpr/include/cpr_threads.h b/media/webrtc/signaling/src/sipcc/cpr/include/cpr_threads.h index 3c74a5b80b44..cab95f883e96 100644 --- a/media/webrtc/signaling/src/sipcc/cpr/include/cpr_threads.h +++ b/media/webrtc/signaling/src/sipcc/cpr/include/cpr_threads.h @@ -70,6 +70,13 @@ cprThread_t cprCreateThread(const char *name, void *data); +/* + * cprJoinThread + * + * wait for thread termination + */ +void cprJoinThread(cprThread_t thread); + /** * cprDestroyThread * diff --git a/media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_threads.c b/media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_threads.c index 36d0844adbc5..cb71f8fd3d60 100644 --- a/media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_threads.c +++ b/media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_threads.c @@ -5,6 +5,9 @@ #include "cpr.h" #include "cpr_stdlib.h" #include "cpr_stdio.h" +#include "thread_monitor.h" +#include "prtypes.h" +#include "mozilla/Assertions.h" #include #include #include @@ -99,6 +102,19 @@ cprCreateThread (const char *name, return (cprThread_t)NULL; } +/* + * cprJoinThread + * + * wait for thread termination + */ +void cprJoinThread(cprThread_t thread) +{ + cpr_thread_t *cprThreadPtr; + + cprThreadPtr = (cpr_thread_t *) thread; + MOZ_ASSERT(cprThreadPtr); + pthread_join(cprThreadPtr->u.handleInt, NULL); +} /** * cprDestroyThread @@ -118,29 +134,28 @@ cprCreateThread (const char *name, cprRC_t cprDestroyThread (cprThread_t thread) { - static const char fname[] = "cprDestroyThread"; cpr_thread_t *cprThreadPtr; cprThreadPtr = (cpr_thread_t *) thread; - if (cprThreadPtr != NULL) { + if (cprThreadPtr) { /* * Make sure thread is trying to destroy itself. */ if ((pthread_t) cprThreadPtr->u.handleInt == pthread_self()) { - cprThreadPtr->threadId = 0; - cpr_free(cprThreadPtr); + CPR_INFO("%s: Destroying Thread %d", __FUNCTION__, cprThreadPtr->threadId); pthread_exit(NULL); return CPR_SUCCESS; } - CPR_ERROR("%s: Thread attempted to destroy another thread, not itself.\n", - fname); + CPR_ERROR("%s: Thread attempted to destroy another thread, not itself.", + __FUNCTION__); + MOZ_ASSERT(PR_FALSE); errno = EINVAL; return CPR_FAILURE; } - /* Bad application! */ - CPR_ERROR("%s - NULL pointer passed in.\n", fname); + CPR_ERROR("%s - NULL pointer passed in.", __FUNCTION__); + MOZ_ASSERT(PR_FALSE); errno = EINVAL; return CPR_FAILURE; } diff --git a/media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_threads.c b/media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_threads.c index ba0613d6484f..31375a4cfca0 100644 --- a/media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_threads.c +++ b/media/webrtc/signaling/src/sipcc/cpr/win32/cpr_win_threads.c @@ -209,6 +209,20 @@ cprCreateThread(const char* name, }; +/* + * cprJoinThread + * + * wait for thread termination + */ +void cprJoinThread(cprThread_t thread) +{ + cpr_thread_t *cprThreadPtr; + + cprThreadPtr = (cpr_thread_t *) thread; + MOZ_ASSERT(cprThreadPtr); + WaitForSingleObject(cprThreadPtr->u.handlePtr, INFINITE); +} + /* * cprDestroyThread * @@ -233,7 +247,6 @@ cprDestroyThread(cprThread_t thread) */ if (cprThreadPtr->threadId == GetCurrentThreadId()) { CPR_INFO("%s: Destroying Thread %d", __FUNCTION__, cprThreadPtr->threadId); - cpr_free(cprThreadPtr); ExitThread(0); return CPR_SUCCESS; } @@ -241,11 +254,13 @@ cprDestroyThread(cprThread_t thread) CPR_ERROR("%s: Thread attempted to destroy another thread, not itself.", __FUNCTION__); MOZ_ASSERT(PR_FALSE); + errno = EINVAL; return CPR_FAILURE; } CPR_ERROR("%s - NULL pointer passed in.", __FUNCTION__); MOZ_ASSERT(PR_FALSE); + errno = EINVAL; return CPR_FAILURE; };