Bug 991037 - Part 4: Get rid of the sipcc threads/queues, and run all sipcc logic on main. r=mt

This commit is contained in:
Byron Campen [:bwc] 2014-07-30 11:09:51 -07:00
parent 49cb1647c8
commit 62ec63bb40
34 changed files with 318 additions and 2985 deletions

View File

@ -405,8 +405,6 @@
'./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',

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,6 @@
#include "PeerConnectionImpl.h"
#include "PeerConnectionCtx.h"
#include "runnable_utils.h"
#include "cpr_socket.h"
#include "debug-psipcc-types.h"
#include "prcvar.h"
@ -36,18 +35,9 @@
#include "nsIObserver.h"
#include "mozilla/Services.h"
#include "StaticPtr.h"
extern "C" {
#include "../sipcc/core/common/thread_monitor.h"
}
static const char* logTag = "PeerConnectionCtx";
extern "C" {
extern PRCondVar *ccAppReadyToStartCond;
extern PRLock *ccAppReadyToStartLock;
extern char ccAppReadyToStart;
}
namespace mozilla {
using namespace dom;
@ -169,29 +159,11 @@ PeerConnectionCtx* PeerConnectionCtx::gInstance;
nsIThread* PeerConnectionCtx::gMainThread;
StaticRefPtr<PeerConnectionCtxShutdown> PeerConnectionCtx::gPeerConnectionCtxShutdown;
// Since we have a pointer to main-thread, help make it safe for lower-level
// SIPCC threads to use SyncRunnable without deadlocking, by exposing main's
// dispatcher and waiter functions. See sipcc/core/common/thread_monitor.c.
static void thread_ended_dispatcher(thread_ended_funct func, thread_monitor_id_t id)
{
nsresult rv = PeerConnectionCtx::gMainThread->Dispatch(WrapRunnableNM(func, id),
NS_DISPATCH_NORMAL);
if (NS_FAILED(rv)) {
CSFLogError( logTag, "%s(): Could not dispatch to main thread", __FUNCTION__);
}
}
static void join_waiter() {
NS_ProcessPendingEvents(PeerConnectionCtx::gMainThread);
}
nsresult PeerConnectionCtx::InitializeGlobal(nsIThread *mainThread,
nsIEventTarget* stsThread) {
if (!gMainThread) {
gMainThread = mainThread;
CSF::VcmSIPCCBinding::setMainThread(gMainThread);
init_thread_monitor(&thread_ended_dispatcher, &join_waiter);
} else {
MOZ_ASSERT(gMainThread == mainThread);
}
@ -425,31 +397,14 @@ nsresult PeerConnectionCtx::Initialize() {
codecMask |= VCM_CODEC_RESOURCE_VP8;
//codecMask |= VCM_CODEC_RESOURCE_I420;
mCCM->setVideoCodecs(codecMask);
ccAppReadyToStartLock = PR_NewLock();
if (!ccAppReadyToStartLock) {
return NS_ERROR_FAILURE;
}
ccAppReadyToStartCond = PR_NewCondVar(ccAppReadyToStartLock);
if (!ccAppReadyToStartCond) {
return NS_ERROR_FAILURE;
}
mCCM->addCCObserver(this);
ChangeSipccState(dom::PCImplSipccState::Starting);
if (!mCCM->startSDPMode())
return NS_ERROR_FAILURE;
mDevice = mCCM->getActiveDevice();
mCCM->addCCObserver(this);
NS_ENSURE_TRUE(mDevice.get(), NS_ERROR_FAILURE);
ChangeSipccState(dom::PCImplSipccState::Starting);
// Now that everything is set up, we let the CCApp thread
// know that it's okay to start processing messages.
PR_Lock(ccAppReadyToStartLock);
ccAppReadyToStart = 1;
PR_NotifyAllCondVar(ccAppReadyToStartCond);
PR_Unlock(ccAppReadyToStartLock);
#ifdef MOZILLA_INTERNAL_API
mConnectionCounter = 0;
@ -570,36 +525,11 @@ void PeerConnectionCtx::onDeviceEvent(ccapi_device_event_e aDeviceEvent,
}
}
static void onCallEvent_m(nsAutoPtr<std::string> peerconnection,
ccapi_call_event_e aCallEvent,
CSF::CC_CallInfoPtr aInfo);
void PeerConnectionCtx::onCallEvent(ccapi_call_event_e aCallEvent,
CSF::CC_CallPtr aCall,
CSF::CC_CallInfoPtr aInfo) {
// This is called on a SIPCC thread.
//
// We cannot use SyncRunnable to main thread, as that would deadlock on
// shutdown. Instead, we dispatch asynchronously. We copy getPeerConnection(),
// a "weak ref" to the PC, which is safe in shutdown, and CC_CallInfoPtr (an
// nsRefPtr) is thread-safe and keeps aInfo alive.
nsAutoPtr<std::string> pcDuped(new std::string(aCall->getPeerConnection()));
// DISPATCH_NORMAL with duped string
nsresult rv = gMainThread->Dispatch(WrapRunnableNM(&onCallEvent_m, pcDuped,
aCallEvent, aInfo),
NS_DISPATCH_NORMAL);
if (NS_FAILED(rv)) {
CSFLogError( logTag, "%s(): Could not dispatch to main thread", __FUNCTION__);
}
}
// Demux the call event to the right PeerConnection
static void onCallEvent_m(nsAutoPtr<std::string> peerconnection,
ccapi_call_event_e aCallEvent,
CSF::CC_CallInfoPtr aInfo) {
CSFLogDebug(logTag, "onCallEvent()");
PeerConnectionWrapper pc(peerconnection->c_str());
PeerConnectionWrapper pc(aCall->getPeerConnection());
if (!pc.impl()) // This must be an event on a dead PC. Ignore
return;
CSFLogDebug(logTag, "Calling PC");

View File

@ -1785,8 +1785,6 @@ PeerConnectionImpl::Close()
nsresult res = CloseInt();
SetSignalingState_m(PCImplSignalingState::SignalingClosed);
return res;
}
@ -1868,18 +1866,23 @@ PeerConnectionImpl::CloseInt()
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
if (IsClosed()) {
return NS_OK;
}
SetSignalingState_m(PCImplSignalingState::SignalingClosed);
// We do this at the end of the call because we want to make sure we've waited
// for all trickle ICE candidates to come in; this can happen well after we've
// transitioned to connected. As a bonus, this allows us to detect race
// conditions where a stats dispatch happens right as the PC closes.
if (!IsClosed()) {
RecordLongtermICEStatistics();
}
RecordLongtermICEStatistics();
if (mInternal->mCall) {
CSFLogInfo(logTag, "%s: Closing PeerConnectionImpl %s; "
"ending call", __FUNCTION__, mHandle.c_str());
mInternal->mCall->endCall();
mInternal->mCall = nullptr;
}
#ifdef MOZILLA_INTERNAL_API
if (mDataConnection) {
@ -2179,7 +2182,7 @@ SendEndOfCandidatesImpl(nsWeakPtr weakPCObserver) {
void
PeerConnectionImpl::SendEndOfCandidates() {
// We dispatch this because real candidates do a dispatch in
// PeerConnection::onCallEvent, and we don't want this to jump ahead.
// PeerConnectionImpl::onCallEvent, and we don't want this to jump ahead.
NS_DispatchToMainThread(
WrapRunnableNM(&SendEndOfCandidatesImpl, mPCObserver),
NS_DISPATCH_NORMAL);

View File

@ -141,7 +141,8 @@ typedef enum {
extern cpr_status_e ccappTaskPostMsg(unsigned int msgId, void * data, uint16_t len, int appId);
extern void ccappSyncSessionMgmt(session_mgmt_t *sessMgmt);
extern void CCApp_task(void * arg);
extern void CCApp_prepare_task();
extern void GSM_prepare_task();
extern void *findhash(unsigned int key);
extern session_id_t createSessionId(line_t line, callid_t call);
extern void getLineIdAndCallId (line_t *line_id, callid_t *call_id);

View File

@ -122,75 +122,28 @@ cpr_status_e ccappTaskPostMsg(unsigned int msgId, void * data, uint16_t len, int
cpr_status_e
ccappTaskSendMsg (uint32_t cmd, void *msg, uint16_t len, uint32_t UsrInfo)
{
phn_syshdr_t *syshdr;
appListener *listener = NULL;
syshdr = (phn_syshdr_t *) cprGetSysHeader(msg);
if (!syshdr) {
return CPR_FAILURE;
}
syshdr->Cmd = cmd;
syshdr->Len = len;
syshdr->Usr.UsrInfo = UsrInfo;
CCAPP_DEBUG(DEB_F_PREFIX"Received Cmd[%d] for app[%d]", DEB_F_PREFIX_ARGS(SIP_CC_PROV, __FUNCTION__),
cmd, UsrInfo);
if (cprSendMessage(ccapp_msgq , (cprBuffer_t*)msg, (void **)&syshdr) == CPR_FAILURE) {
cprReleaseSysHeader(syshdr);
return CPR_FAILURE;
listener = getCcappListener(UsrInfo);
if (listener != NULL) {
(* ((appListener)(listener)))(msg, cmd);
} else {
CCAPP_DEBUG(DEB_F_PREFIX"Event[%d] doesn't have a dedicated listener.", DEB_F_PREFIX_ARGS(SIP_CC_PROV, __FUNCTION__),
UsrInfo);
}
cpr_free(msg);
return CPR_SUCCESS;
}
/**
*
* CCApp Provider main routine.
*
* @param arg - CCApp msg queue
*
* @return void
*
* @pre None
*/
void CCApp_task(void * arg)
void CCApp_prepare_task()
{
static const char fname[] = "CCApp_task";
phn_syshdr_t *syshdr = NULL;
appListener *listener = NULL;
void * msg;
//initialize the listener list
sll_lite_init(&sll_list);
CCAppInit();
// If the "ready to start" condition variable has been created
// (is non-null), we're going to wait for it to be signaled
// before we start processing messages.
if (ccAppReadyToStartCond) {
PR_Lock(ccAppReadyToStartLock);
while (!ccAppReadyToStart) {
PR_WaitCondVar(ccAppReadyToStartCond, PR_INTERVAL_NO_TIMEOUT);
}
PR_Unlock(ccAppReadyToStartLock);
}
while (1) {
msg = cprGetMessage(ccapp_msgq, TRUE, (void **) &syshdr);
if ( msg) {
CCAPP_DEBUG(DEB_F_PREFIX"Received Cmd[%d] for app[%d]", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname),
syshdr->Cmd, syshdr->Usr.UsrInfo);
listener = getCcappListener(syshdr->Usr.UsrInfo);
if (listener != NULL) {
(* ((appListener)(listener)))(msg, syshdr->Cmd);
} else {
CCAPP_DEBUG(DEB_F_PREFIX"Event[%d] doesn't have a dedicated listener.", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname),
syshdr->Usr.UsrInfo);
}
cprReleaseSysHeader(syshdr);
cpr_free(msg);
}
}
}

View File

@ -53,7 +53,6 @@
#include "prlog.h"
#include "prlock.h"
#include "prcvar.h"
#include "thread_monitor.h"
/*---------------------------------------------------------
*
@ -176,7 +175,7 @@ extern void cc_media_update_video_txcap(boolean val);
session_data_t * getDeepCopyOfSessionData(session_data_t *data);
static void ccappUpdateSessionData(session_update_t *sessUpd);
static void ccappFeatureUpdated (feature_update_t *featUpd);
void destroy_ccapp_thread();
void ccapp_shutdown();
void ccpro_handleserviceControlNotify();
/* Sets up mutex needed for protecting state variables. */
static cc_int32_t InitInternal();
@ -2147,8 +2146,7 @@ void ccp_handler(void* msg, int type) {
break;
case CCAPP_THREAD_UNLOAD:
thread_ended(THREADMON_CCAPP);
destroy_ccapp_thread();
ccapp_shutdown();
break;
default:
APP_ERR_MSG("CCApp_Task: Error: Unknown message %d msg =%p",
@ -2158,19 +2156,18 @@ void ccp_handler(void* msg, int type) {
}
/*
* Function: destroy_ccapp_thread
* Description: shutdown and kill ccapp thread
* Function: ccapp_shutdown
* Description: shutdown ccapp
* Parameters: none
* Returns: none
*/
void destroy_ccapp_thread()
void ccapp_shutdown()
{
static const char fname[] = "destroy_ccapp_thread";
TNP_DEBUG(DEB_F_PREFIX"Unloading ccapp and destroying ccapp thread",
static const char fname[] = "ccapp_shutdown";
TNP_DEBUG(DEB_F_PREFIX"Unloading ccapp",
DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname));
platform_initialized = FALSE;
CCAppShutdown();
(void)cprDestroyThread(ccapp_thread);
}
/**

View File

@ -21,7 +21,7 @@
#include "misc_apps_task.h"
#include "plat_api.h"
#include "ccapp_task.h"
#include "thread_monitor.h"
#include "uiapi.h"
#include "mozilla/Assertions.h"
#include "phone_platform_constants.h"
@ -94,29 +94,29 @@ boolean gStopTickTask = FALSE;
*--------------------------------------------------------------------------
*/
cprMsgQueue_t ccapp_msgq;
cprThread_t ccapp_thread;
cprMsgQueue_t ccapp_msgq = NULL;
cprThread_t ccapp_thread = NULL;
cprMsgQueue_t sip_msgq;
cprThread_t sip_thread;
cprMsgQueue_t sip_msgq = NULL;
cprThread_t sip_thread = NULL;
#ifdef NO_SOCKET_POLLING
cprThread_t sip_msgqwait_thread;
cprThread_t sip_msgqwait_thread = NULL;
#endif
cprMsgQueue_t gsm_msgq;
cprThread_t gsm_thread;
cprMsgQueue_t gsm_msgq = NULL;
cprThread_t gsm_thread = NULL;
cprMsgQueue_t misc_app_msgq;
cprThread_t misc_app_thread;
cprMsgQueue_t misc_app_msgq = NULL;
cprThread_t misc_app_thread = NULL;
#ifdef JINDO_DEBUG_SUPPORTED
cprMsgQueue_t debug_msgq;
cprThread_t debug_thread;
cprMsgQueue_t debug_msgq = NULL;
cprThread_t debug_thread = NULL;
#endif
#ifdef EXTERNAL_TICK_REQUIRED
cprMsgQueue_t ticker_msgq;
cprThread_t ticker_thread;
cprMsgQueue_t ticker_msgq = NULL;
cprThread_t ticker_thread = NULL;
#endif
/* Platform initialized flag */
@ -215,13 +215,6 @@ ccInit ()
strlib_init();
/*
* below should move to cprPreInit. keep it here until then
*/
#if defined(_WIN32) && defined(CPR_TIMERS_ENABLED)
cprTimerSystemInit();
#endif
/* Initialize threads, queues etc. */
(void) thread_init();
@ -243,136 +236,16 @@ thread_init ()
PHNChangeState(STATE_FILE_CFG);
/* initialize message queues */
sip_msgq = cprCreateMessageQueue("SIPQ", SIPQSZ);
gsm_msgq = cprCreateMessageQueue("GSMQ", GSMQSZ);
if (FALSE == gHardCodeSDPMode) {
misc_app_msgq = cprCreateMessageQueue("MISCAPPQ", DEFQSZ);
}
ccapp_msgq = cprCreateMessageQueue("CCAPPQ", DEFQSZ);
#ifdef JINDO_DEBUG_SUPPORTED
debug_msgq = cprCreateMessageQueue("DEBUGAPPQ", DEFQSZ);
#endif
#ifdef EXTERNAL_TICK_REQUIRED
ticker_msgq = cprCreateMessageQueue("Ticker", DEFQSZ);
#endif
/*
* Initialize the command parser and debug infrastructure
*/
debugInit();
/* create threads */
ccapp_thread = cprCreateThread("CCAPP Task",
(cprThreadStartRoutine) CCApp_task,
GSMSTKSZ, CCPROVIDER_THREAD_RELATIVE_PRIORITY /* pri */, ccapp_msgq);
MOZ_ASSERT(ccapp_thread);
if (ccapp_thread) {
thread_started(THREADMON_CCAPP, ccapp_thread);
} else {
CSFLogError("common", "failed to create CCAPP task");
}
CCApp_prepare_task();
GSM_prepare_task();
#ifdef JINDO_DEBUG_SUPPORTED
#ifndef VENDOR_BUILD
debug_thread = cprCreateThread("Debug Task",
(cprThreadStartRoutine) debug_task, STKSZ,
0 /*pri */ , debug_msgq);
if (debug_thread == NULL) {
CSFLogError("common", "failed to create debug task");
}
#endif
#endif
/* SIP main thread */
sip_thread = cprCreateThread("SIPStack task",
(cprThreadStartRoutine) sip_platform_task_loop,
STKSZ, SIP_THREAD_RELATIVE_PRIORITY /* pri */, sip_msgq);
MOZ_ASSERT(sip_thread);
if (sip_thread) {
thread_started(THREADMON_SIP, sip_thread);
} else {
CSFLogError("common", "failed to create sip task");
}
#ifdef NO_SOCKET_POLLING
/* SIP message wait queue task */
sip_msgqwait_thread = cprCreateThread("SIP MsgQueueWait task",
(cprThreadStartRoutine)
sip_platform_task_msgqwait,
STKSZ, SIP_THREAD_RELATIVE_PRIORITY /* pri */, sip_msgq);
MOZ_ASSERT(sip_msgqwait_thread);
if (sip_msgqwait_thread) {
thread_started(THREADMON_MSGQ, sip_msgqwait_thread);
} else {
CSFLogError("common", "failed to create sip message queue wait task");
}
#endif
gsm_thread = cprCreateThread("GSM Task",
(cprThreadStartRoutine) GSMTask,
GSMSTKSZ, GSM_THREAD_RELATIVE_PRIORITY /* pri */, gsm_msgq);
MOZ_ASSERT(gsm_thread);
if (gsm_thread) {
thread_started(THREADMON_GSM, gsm_thread);
} else {
CSFLogError("common", "failed to create gsm task");
}
if (FALSE == gHardCodeSDPMode) {
misc_app_thread = cprCreateThread("MiscApp Task",
(cprThreadStartRoutine) MiscAppTask,
STKSZ, 0 /* pri */, misc_app_msgq);
if (misc_app_thread == NULL) {
CSFLogError("common", "failed to create MiscApp task");
}
}
#ifdef EXTERNAL_TICK_REQUIRED
ticker_thread = cprCreateThread("Ticker task",
(cprThreadStartRoutine) TickerTask,
STKSZ, 0, ticker_msgq);
if (ticker_thread == NULL) {
CSFLogError("common", "failed to create ticker task");
}
#endif
/* Associate the threads with the message queues */
(void) cprSetMessageQueueThread(sip_msgq, sip_thread);
(void) cprSetMessageQueueThread(gsm_msgq, gsm_thread);
if (FALSE == gHardCodeSDPMode) {
(void) cprSetMessageQueueThread(misc_app_msgq, misc_app_thread);
}
(void) cprSetMessageQueueThread(ccapp_msgq, ccapp_thread);
#ifdef JINDO_DEBUG_SUPPORTED
(void) cprSetMessageQueueThread(debug_msgq, debug_thread);
#endif
#ifdef EXTERNAL_TICK_REQUIRED
(void) cprSetMessageQueueThread(ticker_msgq, ticker_thread);
#endif
/*
* initialize debugs of other modules.
*
* dp_init needs the gsm_msgq id. This
* is set in a global variable by the
* GSM task running. However due to timing
* issues dp_init is sometimes run before
* the GSM task has set this variable resulting
* in a NULL msgqueue ptr being passed to CPR
* which returns an error and does not create
* the dialplan timer. Thus pass is the same
* data to dp_init that is passed into the
* cprCreateThread call for GSM above.
*/
config_init();
vcmInit();
dp_init(gsm_msgq);
if (sip_minimum_config_check() != 0) {
PHNChangeState(STATE_UNPROVISIONED);
@ -423,22 +296,9 @@ void
send_protocol_config_msg (void)
{
const char *fname = "send_protocol_config_msg";
char *msg;
TNP_DEBUG(DEB_F_PREFIX"send TCP_DONE message to sip thread..", DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname));
msg = (char *) SIPTaskGetBuffer(4);
if (msg == NULL) {
TNP_DEBUG(DEB_F_PREFIX"failed to allocate message..", DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname));
return;
}
/* send a config done message to the SIP Task */
if (SIPTaskSendMsg(TCP_PHN_CFG_TCP_DONE, msg, 0, NULL) == CPR_FAILURE) {
CSFLogError("common", "%s: notify SIP stack ready failed", fname);
cpr_free(msg);
}
gsm_set_initialized();
PHNChangeState(STATE_CONNECTED);
ui_set_sip_registration_state(CC_ALL_LINES, TRUE);
}
@ -461,17 +321,11 @@ send_task_unload_msg(cc_srcs_t dest_id)
{
const char *fname = "send_task_unload_msg";
uint16_t len = 4;
cprBuffer_t msg = gsm_get_buffer(len);
cprBuffer_t msg;
int sdpmode = 0;
config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode));
if (msg == NULL) {
CSFLogError("common", "%s: failed to allocate msg cprBuffer_t",
fname);
return;
}
DEF_DEBUG(DEB_F_PREFIX"send Unload message to %s task ..",
DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname),
dest_id == CC_SRC_SIP ? "SIP" :
@ -599,10 +453,5 @@ ccUnload (void)
send_task_unload_msg(CC_SRC_CCAPP);
gStopTickTask = TRUE;
/*
* Here we are waiting until all threads that were started notify and exit.
*/
join_all_threads();
}

View File

@ -1,116 +0,0 @@
/* 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 "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];
static boolean wait_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;
wait_list[monitor_id] = TRUE;
}
/*
* thread_ended
*
* Must be called by thread itself on THREAD_UNLOAD to unblock join_all_threads()
*
* Alerts if init_thread_monitor() has not been called.
*
* @param[in] monitor_id - enum of which thread created
*/
/*
* init_thread_monitor
*
* Thread-monitor supports a way to let threads notify the joiner when it is
* safe to join, IF it is initialized with a dispatcher and a waiter function.
*
* Example: To use SyncRunnable or otherwise block on the main thread without
* deadlocking on shutdown, pass in the following:
*
* static void dispatcher(thread_ended_funct fun, thread_monitor_id_t id)
* {
* nsresult rv = gMain->Dispatch(WrapRunnableNM(fun, id), NS_DISPATCH_NORMAL);
* MOZ_ASSERT(NS_SUCCEEDED(rv));
* }
*
* static void waiter() { NS_ProcessPendingEvents(gMain); }
*
* The created thread must then call thread_ended() on receiving THREAD_UNLOAD.
*/
static thread_ended_dispatcher_funct dispatcher = NULL;
static join_wait_funct waiter = NULL;
void init_thread_monitor(thread_ended_dispatcher_funct dispatch,
join_wait_funct wait) {
dispatcher = dispatch;
waiter = wait;
}
static void thread_ended_m(thread_monitor_id_t monitor_id) {
MOZ_ASSERT(dispatcher);
MOZ_ASSERT(waiter);
MOZ_ASSERT(monitor_id < THREADMON_MAX);
if (monitor_id >= THREADMON_MAX) {
return;
}
/* Should already be started */
MOZ_ASSERT(thread_list[monitor_id]);
MOZ_ASSERT(wait_list[monitor_id]);
wait_list[monitor_id] = FALSE;
}
void thread_ended(thread_monitor_id_t monitor_id) {
MOZ_ASSERT(dispatcher);
dispatcher (&thread_ended_m, monitor_id);
}
/*
* join_all_threads
*
* Join all threads that were started.
*/
void join_all_threads() {
int i;
MOZ_ASSERT(dispatcher);
MOZ_ASSERT(waiter);
for (i = 0; i < THREADMON_MAX; i++) {
if (thread_list[i] != NULL) {
while (wait_list[i]) {
waiter();
}
cprJoinThread(thread_list[i]);
cpr_free(thread_list[i]);
thread_list[i] = NULL;
}
}
}

View File

@ -1,60 +0,0 @@
/* 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);
/*
* thread_ended
*
* Must be called by thread itself on THREAD_UNLOAD to unblock join_all_threads()
*
* Alerts if init_thread_monitor() has not been called.
*
* @param[in] monitor_id - enum of which thread created
*/
void thread_ended(thread_monitor_id_t monitor_id);
typedef void (*thread_ended_funct)(thread_monitor_id_t);
typedef void (*thread_ended_dispatcher_funct)(thread_ended_funct func, thread_monitor_id_t);
typedef void (*join_wait_funct)();
/*
* init_thread_monitor - see thread_monitor.c
*/
void init_thread_monitor(thread_ended_dispatcher_funct dispatch, join_wait_funct wait);
/*
* join_all_threads
*
* Join all threads that were started.
*/
void join_all_threads();
#endif

View File

@ -1264,16 +1264,6 @@ fsmdef_init_dcb (fsmdef_dcb_t *dcb, callid_t call_id,
dcb->active_feature = CC_FEATURE_NONE;
/* Release transient timers if any have been allocated */
if (dcb->err_onhook_tmr) {
(void) cprDestroyTimer(dcb->err_onhook_tmr);
dcb->err_onhook_tmr = NULL;
}
if (dcb->req_pending_tmr) {
(void) cprDestroyTimer(dcb->req_pending_tmr);
dcb->req_pending_tmr = NULL;
}
FSM_SET_SECURITY_STATUS(dcb, CC_SECURITY_UNKNOWN);
FSM_SET_POLICY(dcb, CC_POLICY_UNKNOWN);
dcb->session = PRIMARY;
@ -1341,25 +1331,6 @@ fsmdef_free_dcb (fsmdef_dcb_t *dcb)
strlib_free(dcb->caller_id.orig_called_number);
strlib_free(dcb->caller_id.orig_rpid_number);
/* Cancel any existing error onhook timer */
if (dcb->err_onhook_tmr) {
(void) cprCancelTimer(dcb->err_onhook_tmr);
(void) cprDestroyTimer(dcb->err_onhook_tmr);
dcb->err_onhook_tmr = NULL;
}
/* Cancel any existing request pending timer */
if (dcb->req_pending_tmr) {
(void) cprCancelTimer(dcb->req_pending_tmr);
(void) cprDestroyTimer(dcb->req_pending_tmr);
dcb->req_pending_tmr = NULL;
}
/* Cancel any existing ringback delay timer */
if (dcb->ringback_delay_tmr) {
(void) cprCancelTimer(dcb->ringback_delay_tmr);
}
// Free the call instance id
if (dcb->caller_id.call_instance_id != 0) {
fsmutil_free_ci_id(dcb->caller_id.call_instance_id, dcb->line);
@ -1985,9 +1956,6 @@ fsmdef_release (fsm_fcb_t *fcb, cc_causes_t cause, boolean send_release)
ui_update_media_interface_change(dcb->line, dcb->call_id, MEDIA_INTERFACE_UPDATE_FAIL);
}
memset(&kfactor, 0, sizeof(cc_kfact_t));
/* Cancel any existing autoanswer timer */
(void) cprCancelTimer(dcb->autoAnswerTimer);
/*
* Let Dialog Manager know that there is ONHOOK event
@ -2340,73 +2308,16 @@ fsmdef_set_feature_timer (fsmdef_dcb_t *dcb, cprTimer_t *timer,
{
static const char fname[] = "fsmdef_set_feature_timer";
if (cprCancelTimer(*timer) != CPR_SUCCESS) {
FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CANCEL_FAILED),
dcb->call_id, dcb->line, fname, "Feature", cpr_errno);
return;
}
if (cprStartTimer(*timer, duration, (void *)(long)dcb->call_id) == CPR_FAILURE) {
FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_START_FAILED),
dcb->call_id, dcb->line, fname, "Feature", cpr_errno);
}
}
static void
fsmdef_set_req_pending_timer (fsmdef_dcb_t *dcb)
{
static const char fname[] = "fsmdef_set_req_pending_timer";
uint32_t msec;
if (dcb == NULL) {
FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_INVALID_DCB), fname);
return;
}
if (!dcb->req_pending_tmr) {
dcb->req_pending_tmr = cprCreateTimer("Request Pending",
GSM_REQ_PENDING_TIMER,
TIMER_EXPIRATION,
gsm_msgq);
if (dcb->req_pending_tmr == NULL) {
FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CREATE_FAILED),
dcb->call_id, dcb->line, fname, "Request Pending");
return;
}
}
if (dcb->inbound) {
// We did not initiate this call, so set timer between 0 and 2000ms
msec = abs(cpr_rand()) % 2000;
} else {
// We initiated this call, so set the timer between 2100 and 4000ms
msec = abs(cpr_rand()) % 1900 + 2100;
}
FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Starting req pending timer for %d ms.",
DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, dcb->call_id, fname), msec);
fsmdef_set_feature_timer(dcb, &dcb->req_pending_tmr, msec);
}
static void
fsmdef_set_ringback_delay_timer (fsmdef_dcb_t *dcb)
{
static const char fname[] = "fsmdef_set_ringback_delay_timer";
if (dcb == NULL) {
FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_INVALID_DCB), fname);
return;
}
FSM_DEBUG_SM(DEB_L_C_F_PREFIX"Starting Ringback Delay timer"
" for %d ms.\n",
DEB_L_C_F_PREFIX_ARGS(FSM, dcb->line, dcb->call_id, fname), RINGBACK_DELAY);
fsmdef_set_feature_timer(dcb, &dcb->ringback_delay_tmr, RINGBACK_DELAY);
}
/*******************************************************************
@ -4724,30 +4635,6 @@ fsmdef_ev_collectinginfo_release (sm_event_t *event)
fsmdef_set_call_info_cc_call_state(dcb, CC_STATE_CALL_FAILED, CC_CAUSE_INVALID_NUMBER);
// Start onhook timer
if ( dcb->err_onhook_tmr) {
(void) cprDestroyTimer(dcb->err_onhook_tmr);
}
dcb->err_onhook_tmr = cprCreateTimer("Error Onhook",
GSM_ERROR_ONHOOK_TIMER,
TIMER_EXPIRATION,
gsm_msgq);
if (dcb->err_onhook_tmr == NULL) {
FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CREATE_FAILED),
dcb->call_id, dcb->line, "", "Error Onhook");
return (SM_RC_CLEANUP);
}
if (cprStartTimer(dcb->err_onhook_tmr,
FSMDEF_ERR_ONHOOK_TMR_SECS * 1000,
(void *)(long)dcb->call_id) == CPR_FAILURE) {
FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_START_FAILED),
dcb->call_id, dcb->line, "",
"Error Onhook", cpr_errno);
return (SM_RC_CLEANUP);
}
return (SM_RC_END);
}
@ -4942,28 +4829,6 @@ fsmdef_ev_out_alerting (sm_event_t *event)
* used for inband ringback.
*/
dcb->inband_received = TRUE;
FSM_DEBUG_SM(DEB_F_PREFIX"inband_received, cancel timer.", DEB_F_PREFIX_ARGS(FSM, fname));
/*
* If ringback delay timer has been started, cancel it now.
*/
if (cprCancelTimer(dcb->ringback_delay_tmr) != CPR_SUCCESS) {
FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CANCEL_FAILED),
dcb->call_id, dcb->line, fname, "Ringback Delay",
cpr_errno);
}
} else {
/*
* Not inband alerting case. Set ringback delay timer so that local
* ringback will eventually be played. We delay the ringback for
* a short time to handle the case where the messages key was pressed.
* This is because VM server can respond very quickly with RTP, 183,
* and 200 and we do not want local ringback tone to interfere with
* the playing of the VM prompt.
*/
if (!cprIsTimerRunning(dcb->ringback_delay_tmr)) {
fsmdef_set_ringback_delay_timer(dcb);
}
}
cc_call_state(dcb->call_id, dcb->line, CC_STATE_FAR_END_ALERTING,
@ -5062,31 +4927,6 @@ fsmdef_ev_callsent_release (sm_event_t *event)
if (src_id == CC_SRC_SIP) {
dcb->early_error_release = TRUE;
}
if ( dcb->err_onhook_tmr) {
(void) cprDestroyTimer(dcb->err_onhook_tmr);
}
dcb->err_onhook_tmr = cprCreateTimer("Error Onhook",
GSM_ERROR_ONHOOK_TIMER,
TIMER_EXPIRATION,
gsm_msgq);
if (dcb->err_onhook_tmr == NULL) {
FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CREATE_FAILED),
dcb->call_id, dcb->line, "", "Error Onhook");
return (SM_RC_CLEANUP);
}
if (cprStartTimer(dcb->err_onhook_tmr,
FSMDEF_ERR_ONHOOK_TMR_SECS * 1000,
(void *)(long)dcb->call_id) == CPR_FAILURE) {
FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_START_FAILED),
dcb->call_id, dcb->line, "",
"Error Onhook", cpr_errno);
return (SM_RC_CLEANUP);
}
break;
default:
@ -5448,9 +5288,6 @@ fsmdef_handle_inalerting_offhook_answer (sm_event_t *event)
}
}
/* Cancel any existing autoanswer timer */
(void)cprCancelTimer(dcb->autoAnswerTimer);
cc_int_connected(CC_SRC_GSM, CC_SRC_SIP, dcb->call_id, dcb->line,
&(dcb->caller_id), NULL, &msg_body);
@ -5576,11 +5413,6 @@ fsmdef_transition_to_connected (fsm_fcb_t *fcb)
FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__));
if (dcb->req_pending_tmr) {
/* cancel any request pending timer, just in case */
(void) cprCancelTimer(dcb->req_pending_tmr);
}
/*
* Update the media capability without effecting the existing media line.
*/
@ -5653,15 +5485,6 @@ fsmdef_ev_connected (sm_event_t *event)
dcb->spoof_ringout_applied = FALSE;
/*
* Cancel ringback delay timer
*/
if (cprCancelTimer(dcb->ringback_delay_tmr) != CPR_SUCCESS) {
FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CANCEL_FAILED),
dcb->call_id, dcb->line, fname, "Ringback Delay",
cpr_errno);
}
cc_call_state(dcb->call_id, dcb->line, CC_STATE_CONNECTED,
FSMDEF_CC_CALLER_ID);
@ -5939,28 +5762,6 @@ fsm_connected_media_pend_local_hold (fsm_fcb_t *fcb, cc_feature_data_t *data_p)
return (SM_RC_END);
}
if (dcb->req_pending_tmr &&
cprIsTimerRunning(dcb->req_pending_tmr)) {
/*
* Request timer is running, that means we are waiting
* to re-send media update again due to previously glare.
* Since the previous offer has not been accepted, we can
* simply just send hold instead when glare resolution timer
* expires.
*/
/* store the reason to resend when glare timer expires */
dcb->hold_reason = data_p->hold.call_info.data.hold_resume_reason;
/*
* reset feature hold pending flag in case that there are
* multiple hold feature received while waiting for
* glare resolution to resolve.
*/
FSM_RESET_FLAGS(dcb->flags, FSMDEF_F_HOLD_REQ_PENDING);
fsm_change_state(fcb, __LINE__, FSMDEF_S_HOLD_PENDING);
return (SM_RC_END);
}
/*
* We have sent media capability update out but have not received
* any response yet. The glare condition may occur but we can only
@ -7084,17 +6885,7 @@ void fsmdef_reversion_timeout(callid_t call_id)
return;
}
if (dcb->reversionInterval > 0) {
ret = cprStartTimer(dcb->revertTimer, dcb->reversionInterval * 1000, (void*)(long)call_id);
}
if ( ret == CPR_FAILURE ) {
FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_START_FAILED),
dcb->call_id, dcb->line, "", "Reversion", cpr_errno);
return;
}
cc_call_state(dcb->call_id, dcb->line, CC_STATE_HOLD_REVERT, NULL);
cc_call_state(dcb->call_id, dcb->line, CC_STATE_HOLD_REVERT, NULL);
}
@ -7144,8 +6935,6 @@ fsmdef_resume (sm_event_t *event)
return;
}
(void) cprCancelTimer(dcb->revertTimer);
dcb->reversionInterval = -1;
/*
* Make sure the connected call (if there is one) goes on hold,
* but do not hold the connected call if it is involved in a
@ -7167,10 +6956,6 @@ fsmdef_resume (sm_event_t *event)
/* Clear all media holding status */
fsmdef_update_media_hold_status(dcb, NULL, FALSE);
if (dcb->req_pending_tmr && cprIsTimerRunning(dcb->req_pending_tmr)) {
req_pending_tmr_running = TRUE;
}
if (!req_pending_tmr_running) {
/*
* Reinitialize the local sdp to include all available codecs.
@ -7260,12 +7045,7 @@ fsmdef_ev_holding_offhook (sm_event_t *event)
FSM_DEBUG_SM(DEB_F_PREFIX"Entered.", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__));
if (cprIsTimerRunning(dcb->revertTimer)) {
// Off hook resume calls only if HR is active else ignore this event
fsmdef_resume(event);
}
return SM_RC_END;
return SM_RC_END;
}
@ -7310,9 +7090,6 @@ fsmdef_ev_holding_feature (sm_event_t *event)
return (sm_rc);
case CC_FEATURE_HOLD_REVERSION:
// Stop the timer for alert interval
(void) cprCancelTimer(dcb->revertTimer);
dcb->reversionInterval = -1;
// Do not revert if alertInterval is negative
if ( data->hold_reversion.alertInterval < 0 )
@ -7326,8 +7103,6 @@ fsmdef_ev_holding_feature (sm_event_t *event)
if ( data->hold_reversion.alertInterval > MAX_HOLD_REVERSION_INTERVAL_TIMER )
data->hold_reversion.alertInterval = MAX_HOLD_REVERSION_INTERVAL_TIMER;
dcb->reversionInterval = data->hold_reversion.alertInterval ;
fsmdef_reversion_timeout(fcb->dcb->call_id);
fsmdef_handle_join_pending(dcb);
@ -7339,8 +7114,6 @@ fsmdef_ev_holding_feature (sm_event_t *event)
case CC_FEATURE_END_CALL:
sm_rc = fsmdef_release_call(fcb, msg);
(void) cprCancelTimer(dcb->revertTimer);
dcb->reversionInterval = -1;
fsmdef_handle_join_pending(dcb);
return (sm_rc);
@ -7388,8 +7161,6 @@ fsmdef_ev_holding_feature (sm_event_t *event)
break;
case CC_FEATURE_CALL_PRESERVATION:
(void) cprCancelTimer(dcb->revertTimer);
dcb->reversionInterval = -1;
return (fsmdef_release(fcb, CC_CAUSE_NORMAL, dcb->send_release));
case CC_FEATURE_NOTIFY:
@ -7527,42 +7298,24 @@ fsmdef_ev_resume_pending_feature (sm_event_t *event)
* about to hold again.
*/
fim_unlock_ui(dcb->call_id);
if (dcb->req_pending_tmr &&
cprIsTimerRunning(dcb->req_pending_tmr)) {
/*
* Request timer is running, that means we are waiting
* to send resume or we already have sent one out
* but it resulted in glare condition and that we are waiting
* to resent it again. In this, just go back to hold state.
*/
(void) cprCancelTimer(dcb->req_pending_tmr);
FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG1),
dcb->call_id, dcb->line, fname,
"Received Hold while waiting to send resume\n");
/* Go back to holding without sending any thing out */
(void)fsm_hold_local_only(fcb);
/*
* We have sent resume to the network and wait for
* for the feature ack. The glare condition can
* occur but we can only assume that resume was sent out
* at this point. We can not send out any more request
* until the result is known.
*/
if (msg->data_valid) {
dcb->hold_reason =
data->hold.call_info.data.hold_resume_reason;
} else {
/*
* We have sent resume to the network and wait for
* for the feature ack. The glare condition can
* occur but we can only assume that resume was sent out
* at this point. We can not send out any more request
* until the result is known.
*/
if (msg->data_valid) {
dcb->hold_reason =
data->hold.call_info.data.hold_resume_reason;
} else {
dcb->hold_reason = CC_REASON_NONE;
}
// since we are going to hold stop the media now
// else the next new call or resume will result in 2 sets of media ports open
(void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_STOP_MEDIA,
NULL);
fsm_change_state(fcb, __LINE__, FSMDEF_S_HOLD_PENDING);
dcb->hold_reason = CC_REASON_NONE;
}
// since we are going to hold stop the media now
// else the next new call or resume will result in 2 sets of media ports open
(void)cc_call_action(dcb->call_id, dcb->line, CC_ACTION_STOP_MEDIA,
NULL);
fsm_change_state(fcb, __LINE__, FSMDEF_S_HOLD_PENDING);
break;
default:
@ -9232,48 +8985,6 @@ fsmdef_init (void)
FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) {
fsmdef_init_dcb(dcb, CC_NO_CALL_ID, FSMDEF_CALL_TYPE_NONE,
FSMDEF_NO_NUMBER, LSM_NO_LINE, NULL);
/*
* Allocate ringback delay timer for each dcb
*/
dcb->ringback_delay_tmr = cprCreateTimer("Ringback Delay",
GSM_RINGBACK_DELAY_TIMER,
TIMER_EXPIRATION,
gsm_msgq);
if (dcb->ringback_delay_tmr == NULL) {
FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CREATE_FAILED),
dcb->call_id, dcb->line, fname, "Ringback Delay");
return;
}
/*
* Allocate auto answer timer for each dcb
*/
dcb->autoAnswerTimer = cprCreateTimer("Auto Answer",
GSM_AUTOANSWER_TIMER,
TIMER_EXPIRATION,
gsm_msgq);
if (dcb->autoAnswerTimer == NULL) {
FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CREATE_FAILED),
dcb->call_id, dcb->line, fname, "Auto Answer");
(void)cprDestroyTimer(dcb->ringback_delay_tmr);
dcb->ringback_delay_tmr = NULL;
return;
}
dcb->revertTimer = cprCreateTimer("Call Reversion",
GSM_REVERSION_TIMER,
TIMER_EXPIRATION,
gsm_msgq);
dcb->reversionInterval = -1;
if (dcb->revertTimer == NULL) {
FSM_DEBUG_SM(get_debug_string(FSMDEF_DBG_TMR_CREATE_FAILED),
dcb->call_id, dcb->line, fname, "Hold Revertion");
(void)cprDestroyTimer(dcb->ringback_delay_tmr);
dcb->ringback_delay_tmr = NULL;
(void)cprDestroyTimer(dcb->autoAnswerTimer);
dcb->autoAnswerTimer = NULL;
return;
}
if (dcb == fsmdef_dcbs) {
g_disable_mass_reg_debug_print = TRUE;
}
@ -9296,22 +9007,6 @@ fsmdef_shutdown (void)
fsmdef_dcb_t *dcb;
FSM_FOR_ALL_CBS(dcb, fsmdef_dcbs, FSMDEF_MAX_DCBS) {
if (dcb->req_pending_tmr) {
(void)cprDestroyTimer(dcb->req_pending_tmr);
}
if (dcb->err_onhook_tmr) {
(void)cprDestroyTimer(dcb->err_onhook_tmr);
}
if (dcb->ringback_delay_tmr) {
(void)cprDestroyTimer(dcb->ringback_delay_tmr);
}
if (dcb->autoAnswerTimer) {
(void)cprDestroyTimer(dcb->autoAnswerTimer);
}
if (dcb->revertTimer) {
(void)cprDestroyTimer(dcb->revertTimer);
}
/* clean media list */
gsmsdp_clean_media_list(dcb);
}

View File

@ -27,7 +27,6 @@
#include "kpmlmap.h"
#include "subapi.h"
#include "platform_api.h"
#include "thread_monitor.h"
static void sub_process_feature_msg(uint32_t cmd, void *msg);
static void sub_process_feature_notify(ccsip_sub_not_data_t *msg, callid_t call_id,
@ -45,7 +44,6 @@ extern void dcsm_shutdown(void);
/* Flag to see whether we can start processing events */
static boolean gsm_initialized = FALSE;
extern cprThread_t gsm_thread;
static media_timer_callback_fp* media_timer_callback = NULL;
/**
@ -75,26 +73,6 @@ gsm_get_buffer (uint16_t size)
}
cpr_status_e
gsm_send_msg (uint32_t cmd, cprBuffer_t buf, uint16_t len)
{
phn_syshdr_t *syshdr;
syshdr = (phn_syshdr_t *) cprGetSysHeader(buf);
if (!syshdr) {
return CPR_FAILURE;
}
syshdr->Cmd = cmd;
syshdr->Len = len;
if (cprSendMessage(gsm_msgq, buf, (void **) &syshdr) == CPR_FAILURE) {
cprReleaseSysHeader(syshdr);
return CPR_FAILURE;
}
return CPR_SUCCESS;
}
boolean
gsm_process_msg (uint32_t cmd, void *msg)
{
@ -258,28 +236,8 @@ gsm_reset (void)
}
void
GSMTask (void *arg)
GSM_prepare_task()
{
static const char fname[] = "GSMTask";
void *msg;
phn_syshdr_t *syshdr;
boolean release_msg = TRUE;
MOZ_ASSERT (gsm_msgq == (cprMsgQueue_t) arg);
if (!gsm_msgq) {
GSM_ERR_MSG(GSM_F_PREFIX"invalid input, exiting", fname);
return;
}
if (platThreadInit("GSMTask") != 0) {
return;
}
/*
* Adjust relative priority of GSM thread.
*/
(void) cprAdjustRelativeThreadPriority(GSM_THREAD_RELATIVE_PRIORITY);
/*
* Initialize all the GSM modules
*/
@ -304,75 +262,73 @@ GSMTask (void *arg)
* Cache random numbers for SRTP keys
*/
gsmsdp_cache_crypto_keys();
while (1) {
release_msg = TRUE;
msg = cprGetMessage(gsm_msgq, TRUE, (void **) &syshdr);
if (msg) {
switch (syshdr->Cmd) {
case TIMER_EXPIRATION:
gsm_process_timer_expiration(msg);
break;
case GSM_SIP:
case GSM_GSM:
release_msg = gsm_process_msg(syshdr->Cmd, msg);
break;
case DP_MSG_INIT_DIALING:
case DP_MSG_DIGIT_STR:
case DP_MSG_STORE_DIGIT:
case DP_MSG_DIGIT:
case DP_MSG_DIAL_IMMEDIATE:
case DP_MSG_REDIAL:
case DP_MSG_ONHOOK:
case DP_MSG_OFFHOOK:
case DP_MSG_UPDATE:
case DP_MSG_DIGIT_TIMER:
case DP_MSG_CANCEL_OFFHOOK_TIMER:
dp_process_msg(syshdr->Cmd, msg);
break;
case SUB_MSG_B2BCNF_SUBSCRIBE_RESP:
case SUB_MSG_B2BCNF_NOTIFY:
case SUB_MSG_B2BCNF_TERMINATE:
sub_process_b2bcnf_msg(syshdr->Cmd, msg);
break;
case SUB_MSG_FEATURE_SUBSCRIBE_RESP:
case SUB_MSG_FEATURE_NOTIFY:
case SUB_MSG_FEATURE_TERMINATE:
sub_process_feature_msg(syshdr->Cmd, msg);
break;
case REG_MGR_STATE_CHANGE:
gsm_reset();
break;
case THREAD_UNLOAD:
thread_ended(THREADMON_GSM);
destroy_gsm_thread();
break;
default:
GSM_ERR_MSG(GSM_F_PREFIX"Unknown message", fname);
break;
}
cprReleaseSysHeader(syshdr);
if (release_msg == TRUE) {
cpr_free(msg);
}
/* Check if there are pending messages for dcsm
* if it in the right state perform its operation
*/
dcsm_process_jobs();
}
}
}
cpr_status_e
gsm_send_msg (uint32_t cmd, cprBuffer_t msg, uint16_t len)
{
boolean release_msg = TRUE;
switch (cmd) {
case TIMER_EXPIRATION:
gsm_process_timer_expiration(msg);
break;
case GSM_SIP:
case GSM_GSM:
release_msg = gsm_process_msg(cmd, msg);
break;
case DP_MSG_INIT_DIALING:
case DP_MSG_DIGIT_STR:
case DP_MSG_STORE_DIGIT:
case DP_MSG_DIGIT:
case DP_MSG_DIAL_IMMEDIATE:
case DP_MSG_REDIAL:
case DP_MSG_ONHOOK:
case DP_MSG_OFFHOOK:
case DP_MSG_UPDATE:
case DP_MSG_DIGIT_TIMER:
case DP_MSG_CANCEL_OFFHOOK_TIMER:
dp_process_msg(cmd, msg);
break;
case SUB_MSG_B2BCNF_SUBSCRIBE_RESP:
case SUB_MSG_B2BCNF_NOTIFY:
case SUB_MSG_B2BCNF_TERMINATE:
sub_process_b2bcnf_msg(cmd, msg);
break;
case SUB_MSG_FEATURE_SUBSCRIBE_RESP:
case SUB_MSG_FEATURE_NOTIFY:
case SUB_MSG_FEATURE_TERMINATE:
sub_process_feature_msg(cmd, msg);
break;
case REG_MGR_STATE_CHANGE:
gsm_reset();
break;
case THREAD_UNLOAD:
destroy_gsm_thread();
break;
default:
GSM_ERR_MSG(GSM_F_PREFIX"Unknown message", __FUNCTION__);
break;
}
if (release_msg == TRUE) {
cpr_free(msg);
}
/* Check if there are pending messages for dcsm
* if it in the right state perform its operation
*/
dcsm_process_jobs();
return CPR_SUCCESS;
}
/**
* This function will process SUBSCRIBED feature NOTIFY messages.
*
@ -593,5 +549,4 @@ void destroy_gsm_thread()
DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname));
gsm_shutdown();
dp_shutdown();
(void) cprDestroyThread(gsm_thread);
}

View File

@ -356,15 +356,6 @@ typedef struct {
/* TRUE if GSM has applied ringout due to CCMs request to show ringout UI */
boolean spoof_ringout_applied;
/* Timer to go on hook after any call error */
cprTimer_t err_onhook_tmr;
/* Request pending timer */
cprTimer_t req_pending_tmr;
/* Ringback delay timer */
cprTimer_t ringback_delay_tmr;
/*
* save of orientation from callInfo to update UI at any time
* other than during call info. update such as after Tx start in
@ -385,11 +376,6 @@ typedef struct {
cc_security_e security;
cc_policy_e policy;
/* auto answer timer */
cprTimer_t autoAnswerTimer;
int32_t reversionInterval;
cprTimer_t revertTimer;
boolean dsp_out_of_resources;
boolean selected;

View File

@ -43,7 +43,6 @@
#include "sip_interface_regmgr.h"
#include "ccsip_publish.h"
#include "platform_api.h"
#include "thread_monitor.h"
#ifdef SAPP_SAPP_GSM
#define SAPP_APP_GSM 3
@ -61,12 +60,10 @@ extern sipSCB_t *find_scb_by_callid(const char *callID, int *scb_index);
extern int platThreadInit(char *);
void sip_platform_handle_service_control_notify(sipServiceControl_t *scp);
short SIPTaskProcessTimerExpiration(void *msg, uint32_t *cmd);
extern cprMsgQueue_t sip_msgq;
extern cprMsgQueue_t gsm_msgq;
extern void ccsip_dump_recv_msg_info(sipMessage_t *pSIPMessage,
cpr_ip_addr_t *cc_remote_ipaddr,
uint16_t cc_remote_port);
void destroy_sip_thread(void);
// Global variables
@ -118,9 +115,6 @@ typedef struct ccsip_shutdown_req_t_ {
} ccsip_shutdown_req_t;
extern cprThread_t sip_thread;
/*---------------------------------------------------------
*
* Local Variables
@ -317,28 +311,11 @@ SIPTaskInit (void)
cpr_status_e
SIPTaskSendMsg (uint32_t cmd, void *msg, uint16_t len, void *usr)
{
phn_syshdr_t *syshdr;
syshdr = (phn_syshdr_t *) cprGetSysHeader(msg);
if (!syshdr) {
return CPR_FAILURE;
}
syshdr->Cmd = cmd;
syshdr->Len = len;
syshdr->Usr.UsrPtr = usr;
/*
* If we send a message to the task too soon the sip variable is not set yet.
* so just use the global for now. This happens if we create sip thread
* and immediately send a CFG_DONE message to sip thread from the main thread.
* This can be solved by waiting for an echo roundtrip from Thread before sending
* any other message. Will do someday.
*/
if (cprSendMessage(sip_msgq /*sip.msgQueue */ , (cprBuffer_t)msg, (void **)&syshdr)
== CPR_FAILURE) {
cprReleaseSysHeader(syshdr);
return CPR_FAILURE;
}
/* Mozilla hack: just ignore everything that is posted here */
(void)cmd;
cpr_free(msg);
(void)len;
(void)usr;
return CPR_SUCCESS;
}
@ -877,10 +854,6 @@ SIPTaskProcessListEvent (uint32_t cmd, void *msg, void *pUsr, uint16_t len)
break;
case THREAD_UNLOAD:
{
thread_ended(THREADMON_SIP);
destroy_sip_thread();
}
break;
case SIP_TMR_GLARE_AVOIDANCE:
@ -3018,18 +2991,4 @@ SIPTaskProcessShutdown (int action, int reason)
/* Shutdown SIP components */
sip_shutdown_phase1(action, reason);
}
/*
* Function: destroy_sip_thread
* Description: kill sip msgQ and sip thread
* Parameters: none
* Returns: none
*/
void destroy_sip_thread()
{
static const char fname[] = "destroy_sip_thread";
DEF_DEBUG(DEB_F_PREFIX"Unloading SIP and destroying sip thread",
DEB_F_PREFIX_ARGS(SIP_CC_INIT, fname));
/* kill msgQ thread first, then itself */
(void) cprDestroyThread(sip_thread);
}

View File

@ -26,7 +26,6 @@
#include <stdio.h>
#include <unistd.h>
#include "prprf.h"
#include "thread_monitor.h"
/*---------------------------------------------------------
*
@ -123,136 +122,6 @@ sip_platform_task_init (void)
}
/**
* The function is a thread loop that waits on SIP message queue
* visible for the external components (sip_msgq). The thread is used
* to avoid having the main task loop from having to set a small time
* waiting on select() to poll inter-thread messages. The small waiting
* time on select() to poll internal messages queue increases the
* unnecessary of waking up when system is idle. On the platform that
* power conservative is critical such as handheld phone, waking up
* periodically is not good for battery life.
*
* This thread splits the message queue waiting function from the
* main thread waiting on select(). This thread simply listens on the
* internal message queue and signal to the main thread via IPC socket
* or local socket trigger. Therefore the main thread can uniformly
* process internal message event and the network event via select().
* The small internal poll time on select() can be
* avoided.
*
* @param[in] arg - pointer to SIP main thread's message queue.
*
* @return None.
*
* @pre (arg != NULL)
*/
void sip_platform_task_msgqwait (void *arg)
{
const char *fname = "sip_platform_task_msgqwait";
cprMsgQueue_t *msgq = (cprMsgQueue_t *)arg;
unsigned int wait_main_thread = 0;
phn_syshdr_t *syshdr;
void *msg;
uint8_t num_messages = 0;
uint8_t response = 0;
boolean quit_thread = FALSE;
if (msgq == NULL) {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"task msgq is null, exiting", fname);
return;
}
if (platThreadInit("SIP IPCQ task") != 0) {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to attach thread to JVM", fname);
return;
}
/*
* Wait for SIP main thread ready for IPC connection.
*/
while (!main_thread_ready) {
/* Pause for other threads to run while waiting */
cprSleep(SIP_PAUSE_WAIT_IPC_LISTEN_READY_TIME);
wait_main_thread++;
if (wait_main_thread > SIP_MAX_WAIT_FOR_IPC_LISTEN_READY) {
/* Exceed the number of wait time */
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"timeout waiting for listening IPC"
" socket ready, exiting\n", fname);
return;
}
}
/*
* Adjust relative priority of SIP thread.
*/
(void) cprAdjustRelativeThreadPriority(SIP_THREAD_RELATIVE_PRIORITY);
while (quit_thread == FALSE) {
msg = cprGetMessage(msgq, TRUE, (void **) &syshdr);
while (msg != NULL) {
/*
* There is a message to be forwarded to the main SIP
* thread for processing.
*/
sip_int_msgq_buf[num_messages].msg = msg;
sip_int_msgq_buf[num_messages].syshdr = syshdr;
num_messages++;
switch (syshdr->Cmd) {
case THREAD_UNLOAD:
thread_ended(THREADMON_MSGQ);
quit_thread = TRUE;
break;
default:
break;
}
if (num_messages == MAX_SIP_MESSAGES) {
/*
* Limit the number of messages passed to the main SIP
* thread to MAX_SIP_MESSAGES since SIP main thread only
* process messages up to MAX_SIP_MESSAGES at a time.
*/
break;
}
/*
* Check to see if there is more message on the queue
* before sending IPC message trigger to the main SIP
* thread. This is to minimize the overhead of the
* the main SIP thread in processing select().
*/
msg = cprGetMessage(msgq, 0, (void **) &syshdr);
}
if (num_messages) {
CCSIP_DEBUG_TASK(DEB_F_PREFIX"%d msg available on msgq", DEB_F_PREFIX_ARGS(SIP_MSG_QUE, fname), num_messages);
/*
* There are some number of messages sent to the main thread,
* trigger the main SIP thread via IPC to process the message.
*/
if (cprSend(sip_ipc_clnt_socket, (void *)&num_messages,
sizeof(num_messages), 0) < 0) {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"send IPC failed errno=%d", fname, cpr_errno);
}
if (FALSE == quit_thread) {
/*
* Wait for main thread to signal us to get more message.
*/
if (cprRecv(sip_ipc_clnt_socket, &response,
sizeof(response), 0) < 0) {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"read IPC failed:"
" errno=%d\n", fname, cpr_errno);
}
num_messages = 0;
}
}
}
cprCloseSocket(sip_ipc_clnt_socket);
}
/**
* sip_process_int_msg - process internal IPC message from the
* the message queue waiting thread.
@ -326,189 +195,6 @@ static void sip_process_int_msg (void)
}
}
/**
*
* sip_platform_task_loop
*
* Run the SIP task
*
* Parameters: arg - SIP message queue
*
* Return Value: None
*
*/
void
sip_platform_task_loop (void *arg)
{
static const char *fname = "sip_platform_task_loop";
int pending_operations;
uint16_t i;
fd_set sip_read_fds;
fd_set sip_write_fds;
sip_tcp_conn_t *entry;
sip_msgq = (cprMsgQueue_t) arg;
if (!sip_msgq) {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_msgq is null, exiting", fname);
return;
}
sip.msgQueue = sip_msgq;
sip_platform_task_init();
/*
* Initialize the SIP task
*/
SIPTaskInit();
if (platThreadInit("SIPStack Task") != 0) {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to attach thread to JVM", fname);
return;
}
/*
* Adjust relative priority of SIP thread.
*/
(void) cprAdjustRelativeThreadPriority(SIP_THREAD_RELATIVE_PRIORITY);
/*
* Setup IPC socket addresses for main thread (server)
*/
{
cpr_socket_t sockets[2];
if (cprSocketPair(AF_LOCAL, SOCK_DGRAM, 0, sockets) == CPR_SUCCESS) {
sip_ipc_serv_socket = sockets[0];
sip_ipc_clnt_socket = sockets[1];
} else {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"socketpair failed:"
" errno=%d\n", fname, cpr_errno);
return;
}
}
/*
* On Win32 platform, the random seed is stored per thread; therefore,
* each thread needs to seed the random number. It is recommended by
* MS to do the following to ensure randomness across application
* restarts.
*/
cpr_srand((unsigned int)time(NULL));
/*
* Set read IPC socket
*/
sip_platform_task_set_read_socket(sip_ipc_serv_socket);
/*
* Let the message queue waiting thread know that the main
* thread is ready.
*/
main_thread_ready = TRUE;
/*
* Main Event Loop
* - Forever-loop exits in sip_process_int_msg()::THREAD_UNLOAD
*/
while (TRUE) {
sip_process_int_msg();
#if 0
/* We don't actually want to select anything else. See bug 1049291 */
/*
* Wait on events or timeout
*/
sip_read_fds = read_fds;
// start off by init to zero
FD_ZERO(&sip_write_fds);
// now look for sockets where data has been queued up
for (i = 0; i < MAX_CONNECTIONS; i++) {
entry = sip_tcp_conn_tab + i;
if (-1 != entry->fd && entry->sendQueue && sll_count(entry->sendQueue)) {
FD_SET(entry->fd, &sip_write_fds);
}
}
pending_operations = cprSelect((nfds + 1),
&sip_read_fds,
&sip_write_fds,
NULL, NULL);
if (pending_operations == SOCKET_ERROR) {
CCSIP_DEBUG_ERROR(SIP_F_PREFIX"cprSelect() failed: errno=%d."
" Recover by initiating sip restart\n",
fname, cpr_errno);
/*
* If we have come here, then either read socket related to
* sip_ipc_serv_socket has got corrupted, or one of the write
* socket related to cucm tcp/tls connection.
* We will recover, by first clearing all fds, then re-establishing
* the connection with sip-msgq by listening on
* sip_ipc_serv_socket.
*/
sip_platform_task_init(); /* this clear FDs */
sip_platform_task_set_read_socket(sip_ipc_serv_socket);
/*
* Since all sockets fds have been cleared above, we can not anyway
* send or receive msg from cucm. So, there is no point
* trying to send registration cancel msg to cucm. Also, a
* call may be active, and in that case we do not want to
* un-register. So, by setting sip_reg_all_failed to true, we
* make sure that no registration cancelation attempt is made.
*/
sip_reg_all_failed = TRUE;
platform_reset_req(DEVICE_RESTART);
continue;
} else if (pending_operations) {
/*
* Listen socket is set only if UDP transport has been
* configured. So see if the select return was for read
* on the listen socket.
*/
if ((listen_socket != INVALID_SOCKET) &&
(sip.taskInited == TRUE) &&
FD_ISSET(listen_socket, &sip_read_fds)) {
sip_platform_udp_read_socket(listen_socket);
pending_operations--;
}
/*
* Check IPC for internal message queue
*/
if (FD_ISSET(sip_ipc_serv_socket, &sip_read_fds)) {
/* read the message to flush the buffer */
sip_process_int_msg();
pending_operations--;
}
/*
* Check all sockets for stuff to do
*/
for (i = 0; ((i < MAX_SIP_CONNECTIONS) &&
(pending_operations > 0)); i++) {
if ((sip_conn.read[i] != INVALID_SOCKET) &&
FD_ISSET(sip_conn.read[i], &sip_read_fds)) {
/*
* Assume tcp
*/
sip_tcp_read_socket(sip_conn.read[i]);
pending_operations--;
}
if ((sip_conn.write[i] != INVALID_SOCKET) &&
FD_ISSET(sip_conn.write[i], &sip_write_fds)) {
int connid;
connid = sip_tcp_fd_to_connid(sip_conn.write[i]);
if (connid >= 0) {
sip_tcp_resend(connid);
}
pending_operations--;
}
}
}
#endif
}
}
/**
*
* sip_platform_task_set_listen_socket

View File

@ -27,94 +27,13 @@ extern cprThread_t misc_app_thread;
cpr_status_e
MiscAppTaskSendMsg (uint32_t cmd, cprBuffer_t buf, uint16_t len)
{
phn_syshdr_t *syshdr_p;
syshdr_p = (phn_syshdr_t *) cprGetSysHeader(buf);
if (!syshdr_p)
{
return CPR_FAILURE;
}
syshdr_p->Cmd = cmd;
syshdr_p->Len = len;
if (cprSendMessage(s_misc_msg_queue, buf, (void **)&syshdr_p) == CPR_FAILURE)
{
cprReleaseSysHeader(syshdr_p);
return CPR_FAILURE;
}
/* Mozilla hack: just ignore everything that is posted here */
(void)cmd;
cpr_free(buf);
(void)len;
return CPR_SUCCESS;
}
void MiscAppTask (void *arg)
{
static const char fname[] = "MiscAppTask";
void *msg_p;
phn_syshdr_t *syshdr_p;
/*
* Get the misc apps message queue handle
*/
s_misc_msg_queue = (cprMsgQueue_t)arg;
if (!s_misc_msg_queue) {
MISC_ERROR(MISC_F_PREFIX"invalid input, exiting", fname);
return;
}
if (platThreadInit("MiscAppTask") != 0) {
MISC_ERROR(MISC_F_PREFIX"Failed to Initialize the thread, exiting",
fname);
return;
}
/*
* Create retry-after timers.
*/
if (pres_create_retry_after_timers() == CPR_FAILURE) {
MISC_ERROR(MISC_F_PREFIX"failed to create retry-after Timers, exiting",
fname);
return;
}
while (1)
{
msg_p = cprGetMessage(s_misc_msg_queue, TRUE, (void **)&syshdr_p);
if (msg_p)
{
switch(syshdr_p->Cmd) {
case SUB_MSG_PRESENCE_SUBSCRIBE_RESP:
case SUB_MSG_PRESENCE_NOTIFY:
case SUB_MSG_PRESENCE_UNSOLICITED_NOTIFY:
case SUB_MSG_PRESENCE_TERMINATE:
case SUB_MSG_PRESENCE_GET_STATE:
case SUB_MSG_PRESENCE_TERM_REQ:
case SUB_MSG_PRESENCE_TERM_REQ_ALL:
case TIMER_EXPIRATION:
case SUB_HANDLER_INITIALIZED:
pres_process_msg_from_msgq(syshdr_p->Cmd, msg_p);
break;
case SUB_MSG_CONFIGAPP_SUBSCRIBE:
case SUB_MSG_CONFIGAPP_TERMINATE:
case SUB_MSG_CONFIGAPP_NOTIFY_ACK:
configapp_process_msg(syshdr_p->Cmd, msg_p);
break;
case THREAD_UNLOAD:
destroy_misc_app_thread();
break;
default:
MISC_ERROR(MISC_F_PREFIX"invalid msg <%d> received",
fname, syshdr_p->Cmd);
break;
}
cprReleaseSysHeader(syshdr_p);
cpr_free(msg_p);
}
}
}
/**
*
* Perform cleaning up resoruces of misc. application task.

View File

@ -122,11 +122,6 @@
#endif
#include "plat_debug.h"
/**
* Mutex to manage message queue list.
*/
extern pthread_mutex_t msgQueueListMutex;
/**
* Boolean to check that cprPreInit been called
*/
@ -168,21 +163,8 @@ cprPreInit (void)
return CPR_SUCCESS;
}
pre_init_called = TRUE;
/*
* Create message queue list mutex
*/
returnCode = pthread_mutex_init(&msgQueueListMutex, NULL);
if (returnCode != 0) {
CPR_ERROR("%s: MsgQueue Mutex init failure %d\n", fname, returnCode);
return CPR_FAILURE;
}
#ifdef CPR_TIMERS_ENABLED
returnCode = cpr_timer_pre_init();
if (returnCode != 0) {
CPR_ERROR("%s: timer pre init failed %d\n", fname, returnCode);
return CPR_FAILURE;
}
#endif
(void)fname;
(void)returnCode;
return CPR_SUCCESS;
}

View File

@ -9,7 +9,6 @@
#include <errno.h>
#include <unistd.h>
#include <sys/resource.h>
#include "thread_monitor.h"
#include "prtypes.h"
#include "mozilla/Assertions.h"

View File

@ -1228,76 +1228,6 @@ cprRC_t start_timer_service_loop (void)
*
*/
void process_expired_timers() {
static const char fname[] = "process_expired_timer";
cprCallBackTimerMsg_t *timerMsg;
void *syshdr;
boolean processingTimers;
/* nothing to do if no timers running */
if (timerListHead == NULL) {
return;
}
/* nothing to do if head has not expired */
if (timerListHead->duration > 0) {
return;
}
/* There are one or more expired timers on the list */
processingTimers = TRUE;
while (processingTimers) {
if (timerListHead != NULL) {
/*
* Send msg to queue to indicate this timer has expired
*/
if (timerListHead->duration <= 0) {
timerMsg = (cprCallBackTimerMsg_t *)
cpr_malloc(sizeof(cprCallBackTimerMsg_t));
if (timerMsg) {
timerMsg->expiredTimerName =
timerListHead->cprTimerPtr->name;
//CPR_INFO("%s: timer %s expired..\n",fname,
// timerMsg->expiredTimerName);
timerMsg->expiredTimerId =
timerListHead->cprTimerPtr->applicationTimerId;
timerMsg->usrData =
timerListHead->cprTimerPtr->data;
syshdr = cprGetSysHeader(timerMsg);
if (syshdr) {
fillInSysHeader(syshdr,
timerListHead->cprTimerPtr->applicationMsgId,
sizeof(cprCallBackTimerMsg_t), timerMsg);
if (cprSendMessage(timerListHead->cprTimerPtr->callBackMsgQueue,
timerMsg, (void **) &syshdr) == CPR_FAILURE) {
cprReleaseSysHeader(syshdr);
cpr_free(timerMsg);
CPR_ERROR("%s - Call to cprSendMessage failed\n", fname);
CPR_ERROR("%s - Unable to send timer %s expiration msg\n",
fname, timerListHead->cprTimerPtr->name);
}
} else {
cpr_free(timerMsg);
CPR_ERROR("%s - Call to cprGetSysHeader failed\n", fname);
CPR_ERROR("%s - Unable to send timer %s expiration msg\n",
fname, timerListHead->cprTimerPtr->name);
}
} else {
CPR_ERROR("%s - Call to cpr_malloc failed\n", fname);
CPR_ERROR("%s - Unable to send timer %s expiration msg\n",
fname, timerListHead->cprTimerPtr->name);
}
(void) removeTimer(timerListHead->cprTimerPtr);
} else {
/* The rest of the timers on the list have not yet expired */
processingTimers = FALSE;
}
} else {
/* The timer list is now empty */
processingTimers = FALSE;
}
} /* still more to process */
}
/**

View File

@ -8,43 +8,10 @@
#include "plat_api.h"
#include "cpr_string.h"
#ifdef SIP_OS_WINDOWS
#include <windows.h>
#include <process.h>
#include <winuser.h>
#else
#include <errno.h>
#include <sys/time.h>
#include <time.h>
#endif /* SIP_OS_WINDOWS */
#ifdef SIP_OS_WINDOWS
extern cprMsgQueue_t sip_msgq;
extern cprMsgQueue_t gsm_msgq;
extern cprMsgQueue_t tmr_msgq;
extern void gsm_shutdown();
extern void sip_shutdown();
/*
* Buffer to hold the messages sent/received by CPR. All
* CPR does is pass four bytes (CNU msg type) and an unsigned
* four bytes (pointer to the msg buffer).
*/
static char rcvBuffer[100];
#define MSG_BUF 0xF000
#else
#define OS_MSGTQL 31 /* need to check number for MV linux and put here */
/*
* Internal CPR API
*/
extern pthread_t cprGetThreadId(cprThread_t thread);
/*
* Extended internal message queue node
*
@ -75,7 +42,6 @@ typedef struct cpr_msg_queue_s
{
struct cpr_msg_queue_s *next;
const char *name;
pthread_t thread;
int32_t queueId;
uint16_t currentCount;
uint32_t totalCount;
@ -85,8 +51,6 @@ typedef struct cpr_msg_queue_s
uint32_t selfQErrors;
uint16_t extendedQDepth;
uint16_t maxExtendedQDepth;
pthread_mutex_t mutex; /* lock for managing extended queue */
pthread_cond_t cond; /* signal for queue/dequeue */
cpr_msgq_node_t *head; /* extended queue head (newest element) */
cpr_msgq_node_t *tail; /* extended queue tail (oldest element) */
} cpr_msg_queue_t;
@ -108,10 +72,6 @@ typedef enum
*/
static cpr_msg_queue_t *msgQueueList = NULL;
/*
* Mutex to manage message queue list
*/
pthread_mutex_t msgQueueListMutex;
/*
* CPR_MAX_MSG_Q_DEPTH
@ -211,8 +171,6 @@ cprPostMessage (cpr_msg_queue_t *msgq, void *msg, void **ppUserData)
return CPR_MSGQ_POST_FAILED;
}
pthread_mutex_lock(&msgq->mutex);
/*
* Fill in data
*/
@ -239,110 +197,14 @@ cprPostMessage (cpr_msg_queue_t *msgq, void *msg, void **ppUserData)
}
msgq->currentCount++;
pthread_cond_signal(&msgq->cond);
pthread_mutex_unlock(&msgq->mutex);
return CPR_MSGQ_POST_SUCCESS;
}
#endif /* !SIP_OS_WINDOWS */
/*
* Functions
*/
/**
* Creates a message queue
*
* @param name - name of the message queue
* @param depth - the message queue depth, optional field which will
* default if set to zero(0). This parameter is currently
* not supported on Windows.
*
* @return Msg queue handle or NULL if init failed, errno provided
*
* @note the actual message queue depth will be bounded by the
* standard system message queue depth and CPR_MAX_MSG_Q_DEPTH.
* If 'depth' is outside of the bounds, the value will be
* reset automatically.
*/
cprMsgQueue_t
cprCreateMessageQueue (const char *name, uint16_t depth)
{
cpr_msg_queue_t *msgq;
#ifndef SIP_OS_WINDOWS
static int key_id = 100; /* arbitrary starting number */
pthread_cond_t _cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t _lock = PTHREAD_MUTEX_INITIALIZER;
#endif
msgq = cpr_calloc(1, sizeof(cpr_msg_queue_t));
if (msgq == NULL) {
printf("%s: Malloc failed: %s\n", __FUNCTION__,
name ? name : "unnamed");
errno = ENOMEM;
return NULL;
}
msgq->name = name ? name : "unnamed";
#ifndef SIP_OS_WINDOWS
msgq->queueId = key_id++;
msgq->cond = _cond;
msgq->mutex = _lock;
/*
* Add message queue to list for statistics reporting
*/
pthread_mutex_lock(&msgQueueListMutex);
msgq->next = msgQueueList;
msgQueueList = msgq;
pthread_mutex_unlock(&msgQueueListMutex);
#endif /* SIP_OS_WINDOWS */
return msgq;
}
/**
* Associate a thread with the message queue
*
* @param msgQueue - msg queue to set
* @param thread - CPR thread to associate with queue
*
* @return CPR_SUCCESS or CPR_FAILURE
*
* @note Nothing is done to prevent overwriting the thread ID
* when the value has already been set.
*/
cprRC_t
cprSetMessageQueueThread (cprMsgQueue_t msgQueue, cprThread_t thread)
{
cpr_msg_queue_t *msgq;
if ((!msgQueue) || (!thread)) {
CPR_ERROR("%s: Invalid input\n", __FUNCTION__);
return CPR_FAILURE;
}
#ifdef SIP_OS_WINDOWS
((cpr_msg_queue_t *)msgQueue)->handlePtr = thread;
#else
msgq = (cpr_msg_queue_t *) msgQueue;
if (msgq->thread != 0) {
CPR_ERROR("%s: over-writing previously msgq thread name for %s",
__FUNCTION__, msgq->name);
}
msgq->thread = cprGetThreadId(thread);
#endif /* SIP_OS_WINDOWS */
return CPR_SUCCESS;
}
/**
* Retrieve a message from a particular message queue
*
@ -360,301 +222,9 @@ cprSetMessageQueueThread (cprMsgQueue_t msgQueue, cprThread_t thread)
void *
cprGetMessage (cprMsgQueue_t msgQueue, boolean waitForever, void **ppUserData)
{
void *buffer = NULL;
#ifdef SIP_OS_WINDOWS
struct msgbuffer *rcvMsg = (struct msgbuffer *)rcvBuffer;
cpr_msg_queue_t *pCprMsgQueue;
MSG msg;
cpr_thread_t *pThreadPtr;
#else
cpr_msg_queue_t *msgq = (cpr_msg_queue_t *) msgQueue;
cpr_msgq_node_t *node;
struct timespec timeout;
struct timeval tv;
struct timezone tz;
#endif
if (!msgQueue) {
CPR_ERROR("%s - invalid msgQueue\n", __FUNCTION__);
return NULL;
}
/* Initialize ppUserData */
if (ppUserData) {
*ppUserData = NULL;
}
#ifdef SIP_OS_WINDOWS
pCprMsgQueue = (cpr_msg_queue_t *)msgQueue;
memset(&msg, 0, sizeof(MSG));
if (waitForever == TRUE) {
if (GetMessage(&msg, NULL, 0, 0) == -1) {
CPR_ERROR("%s - msgQueue = %x failed: %d\n",
__FUNCTION__, msgQueue, GetLastError());
return NULL;
}
} else {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) == 0) {
/* no message present */
return NULL;
}
}
switch (msg.message) {
case WM_CLOSE:
if (msgQueue == &gsm_msgq)
{
CPR_ERROR("%s - WM_CLOSE GSM msg queue\n", __FUNCTION__);
gsm_shutdown();
}
else if (msgQueue == &sip_msgq)
{
CPR_ERROR("%s - WM_CLOSE SIP msg queue\n", __FUNCTION__);
sip_regmgr_destroy_cc_conns();
sip_shutdown();
}
else if (msgQueue == &tmr_msgq)
{
CPR_ERROR("%s - WM_CLOSE TMR msg queue\n", __FUNCTION__);
}
pThreadPtr=(cpr_thread_t *)pCprMsgQueue->handlePtr;
if (pThreadPtr)
{
CloseHandle(pThreadPtr->u.handlePtr);
}
/* zap the thread ptr, since the thread is going away now */
pCprMsgQueue->handlePtr = NULL;
_endthreadex(0);
break;
case MSG_BUF:
rcvMsg = (struct msgbuffer *)msg.wParam;
buffer = rcvMsg->msgPtr;
if (ppUserData) {
*ppUserData = rcvMsg->usrPtr;
}
cpr_free((void *)msg.wParam);
break;
case MSG_ECHO_EVENT:
{
HANDLE event;
event = (HANDLE*)msg.wParam;
SetEvent( event );
}
break;
case WM_TIMER:
DispatchMessage(&msg);
return NULL;
break;
default:
break;
}
#else
/*
* If waitForever is set, block on the message queue
* until a message is received, else return after
* 25msec of waiting
*/
pthread_mutex_lock(&msgq->mutex);
if (!waitForever)
{
// We'll wait till 25uSec from now
gettimeofday(&tv, &tz);
timeout.tv_nsec = (tv.tv_usec * 1000) + 25000;
timeout.tv_sec = tv.tv_sec;
pthread_cond_timedwait(&msgq->cond, &msgq->mutex, &timeout);
}
else
{
while(msgq->tail==NULL)
{
pthread_cond_wait(&msgq->cond, &msgq->mutex);
}
}
// If there is a message on the queue, de-queue it
if (msgq->tail)
{
node = msgq->tail;
msgq->tail = node->prev;
if (msgq->tail) {
msgq->tail->next = NULL;
}
if (msgq->head == node) {
msgq->head = NULL;
}
msgq->currentCount--;
/*
* Pull out the data
*/
if (ppUserData) {
*ppUserData = node->pUserData;
}
buffer = node->msg;
}
pthread_mutex_unlock(&msgq->mutex);
#endif /* SIP_OS_WINDOWS */
return buffer;
return NULL;
}
/**
* Place a message on a particular queue. Note that caller may
* block (see comments below)
*
* @param msgQueue - msg queue on which to place the message
* @param msg - pointer to the msg to place on the queue
* @param ppUserData - pointer to a pointer to user defined data
*
* @return CPR_SUCCESS or CPR_FAILURE, errno provided
*
* @note 1. Messages queues are set to be non-blocking, those cases
* where the system call fails with a would-block error code
* (EAGAIN) the function will attempt other mechanisms described
* below.
* @note 2. If enabled with an extended message queue, either via a
* call to cprCreateMessageQueue with depth value or a call to
* cprSetExtendMessageQueueDepth() (when unit testing), the message
* will be added to the extended message queue and the call will
* return successfully. When room becomes available on the
* system's message queue, those messages will be added.
* @note 3. If the message queue becomes full and no space is availabe
* on the extended message queue, then the function will attempt
* to resend the message up to CPR_ATTEMPTS_TO_SEND and the
* calling thread will *BLOCK* CPR_SND_TIMEOUT_WAIT_INTERVAL
* milliseconds after each failed attempt. If unsuccessful
* after all attempts then EGAIN error code is returned.
* @note 4. This applies to all CPR threads, including the timer thread.
* So it is possible that the timer thread would be forced to
* sleep which would have the effect of delaying all active
* timers. The work to fix this rare situation is not considered
* worth the effort to fix....so just leaving as is.
*/
cprRC_t
cprSendMessage (cprMsgQueue_t msgQueue, void *msg, void **ppUserData)
{
#ifdef SIP_OS_WINDOWS
struct msgbuffer *sendMsg;
cpr_thread_t *pCprThread;
HANDLE *hThread;
#else
static const char error_str[] = "%s: Msg not sent to %s queue: %s\n";
cpr_msgq_post_result_e rc;
cpr_msg_queue_t *msgq = (cpr_msg_queue_t *) msgQueue;
int16_t attemptsToSend = CPR_ATTEMPTS_TO_SEND;
uint16_t numAttempts = 0;
#endif
if (!msgQueue) {
CPR_ERROR("%s - msgQueue is NULL\n", __FUNCTION__);
return CPR_FAILURE;
}
#ifdef SIP_OS_WINDOWS
pCprThread = (cpr_thread_t *)(((cpr_msg_queue_t *)msgQueue)->handlePtr);
if (!pCprThread) {
CPR_ERROR("%s - msgQueue(%x) not associated with a thread\n",
__FUNCTION__, msgQueue);
return CPR_FAILURE;
}
hThread = (HANDLE*)(pCprThread->u.handlePtr);
if (!hThread) {
CPR_ERROR("%s - msgQueue(%x)'s thread(%x) not assoc. with Windows\n",
__FUNCTION__, msgQueue, pCprThread);
return CPR_FAILURE;
}
/* Package up the message */
sendMsg = (struct msgbuffer *)cpr_calloc(1, sizeof(struct msgbuffer));
if (!sendMsg) {
CPR_ERROR("%s - No memory\n", __FUNCTION__);
return CPR_FAILURE;
}
sendMsg->mtype = PHONE_IPC_MSG;
/* Save the address of the message */
sendMsg->msgPtr = msg;
/* Allow the ppUserData to be optional */
if (ppUserData) {
sendMsg->usrPtr = *ppUserData;
}
/* Post the message */
if (hThread == NULL || PostThreadMessage(pCprThread->threadId, MSG_BUF,
(WPARAM)sendMsg, 0) == 0 ) {
CPR_ERROR("%s - Msg not sent: %d\n", __FUNCTION__, GetLastError());
cpr_free(sendMsg);
return CPR_FAILURE;
}
return CPR_SUCCESS;
#else
/*
* Attempt to send message
*/
do {
/*
* Post the message to the Queue
*/
rc = cprPostMessage(msgq, msg, ppUserData);
if (rc == CPR_MSGQ_POST_SUCCESS) {
cprPegSendMessageStats(msgq, numAttempts);
return CPR_SUCCESS;
} else if (rc == CPR_MSGQ_POST_FAILED) {
CPR_ERROR("%s: Msg not sent to %s queue: %d\n",
__FUNCTION__, msgq->name, errno);
msgq->sendErrors++;
/*
* If posting to calling thread's own queue,
* then peg the self queue error.
*/
if (pthread_self() == msgq->thread) {
msgq->selfQErrors++;
}
return CPR_FAILURE;
}
/*
* Did not succeed in sending the message, so continue
* to attempt up to the CPR_ATTEMPTS_TO_SEND.
*/
attemptsToSend--;
if (attemptsToSend > 0) {
/*
* Force a context-switch of the thread attempting to
* send the message, in order to help the case where
* the msg queue is full and the owning thread may get
* a a chance be scheduled so it can drain it (Note:
* no guarantees, more of a "last-ditch effort" to
* recover...especially when temporarily over-whelmed).
*/
cprSleep(CPR_SND_TIMEOUT_WAIT_INTERVAL);
msgq->reTries++;
numAttempts++;
}
} while (attemptsToSend > 0);
CPR_ERROR(error_str, __FUNCTION__, msgq->name, "FULL");
msgq->sendErrors++;
return CPR_FAILURE;
#endif /* SIP_OS_WINDOWS */
}
/**
* cprGetDepth
*
@ -671,13 +241,6 @@ cprSendMessage (cprMsgQueue_t msgQueue, void *msg, void **ppUserData)
*/
uint16_t cprGetDepth (cprMsgQueue_t msgQueue)
{
#ifdef SIP_OS_WINDOWS
return 0;
#else
cpr_msg_queue_t *msgq;
msgq = (cpr_msg_queue_t *) msgQueue;
return msgq->currentCount;
#endif /* SIP_OS_WINDOWS */
}

View File

@ -115,11 +115,6 @@
#include <sys/msg.h>
#include <sys/ipc.h>
/**
* Mutex to manage message queue list.
*/
extern pthread_mutex_t msgQueueListMutex;
/**
* Boolean to check that cprPreInit been called
*/
@ -162,21 +157,8 @@ cprPreInit (void)
}
pre_init_called = TRUE;
/*
* Create message queue list mutex
*/
returnCode = pthread_mutex_init(&msgQueueListMutex, NULL);
if (returnCode != 0) {
CPR_ERROR("%s: MsgQueue Mutex init failure %d\n", fname, returnCode);
return CPR_FAILURE;
}
#ifdef CPR_TIMERS_ENABLED
returnCode = cpr_timer_pre_init();
if (returnCode != 0) {
CPR_ERROR("%s: timer pre init failed %d\n", fname, returnCode);
return CPR_FAILURE;
}
#endif
(void)fname;
(void)returnCode;
return CPR_SUCCESS;
}

View File

@ -9,7 +9,6 @@
#include <errno.h>
#include <unistd.h>
#include <sys/resource.h>
#include "thread_monitor.h"
#include "prtypes.h"
#include "mozilla/Assertions.h"

View File

@ -1236,75 +1236,5 @@ cprRC_t start_timer_service_loop (void)
*
*/
void process_expired_timers() {
static const char fname[] = "process_expired_timer";
cprCallBackTimerMsg_t *timerMsg;
void *syshdr;
boolean processingTimers;
/* nothing to do if no timers running */
if (timerListHead == NULL) {
return;
}
/* nothing to do if head has not expired */
if (timerListHead->duration > 0) {
return;
}
/* There are one or more expired timers on the list */
processingTimers = TRUE;
while (processingTimers) {
if (timerListHead != NULL) {
/*
* Send msg to queue to indicate this timer has expired
*/
if (timerListHead->duration <= 0) {
timerMsg = (cprCallBackTimerMsg_t *)
cpr_malloc(sizeof(cprCallBackTimerMsg_t));
if (timerMsg) {
timerMsg->expiredTimerName =
timerListHead->cprTimerPtr->name;
//CPR_INFO("%s: timer %s expired..\n",fname,
// timerMsg->expiredTimerName);
timerMsg->expiredTimerId =
timerListHead->cprTimerPtr->applicationTimerId;
timerMsg->usrData =
timerListHead->cprTimerPtr->data;
syshdr = cprGetSysHeader(timerMsg);
if (syshdr) {
fillInSysHeader(syshdr,
timerListHead->cprTimerPtr->applicationMsgId,
sizeof(cprCallBackTimerMsg_t), timerMsg);
if (cprSendMessage(timerListHead->cprTimerPtr->callBackMsgQueue,
timerMsg, (void **) &syshdr) == CPR_FAILURE) {
cprReleaseSysHeader(syshdr);
cpr_free(timerMsg);
CPR_ERROR("%s - Call to cprSendMessage failed\n", fname);
CPR_ERROR("%s - Unable to send timer %s expiration msg\n",
fname, timerListHead->cprTimerPtr->name);
}
} else {
cpr_free(timerMsg);
CPR_ERROR("%s - Call to cprGetSysHeader failed\n", fname);
CPR_ERROR("%s - Unable to send timer %s expiration msg\n",
fname, timerListHead->cprTimerPtr->name);
}
} else {
CPR_ERROR("%s - Call to cpr_malloc failed\n", fname);
CPR_ERROR("%s - Unable to send timer %s expiration msg\n",
fname, timerListHead->cprTimerPtr->name);
}
(void) removeTimer(timerListHead->cprTimerPtr);
} else {
/* The rest of the timers on the list have not yet expired */
processingTimers = FALSE;
}
} else {
/* The timer list is now empty */
processingTimers = FALSE;
}
} /* still more to process */
}

View File

@ -8,10 +8,6 @@
#include "cpr_types.h"
#include "cpr_threads.h"
#ifndef SIP_OS_WINDOWS
#include <pthread.h>
#endif /* !SIP_OS_WINDOWS */
__BEGIN_DECLS
/**
@ -32,76 +28,7 @@ typedef void* cprMsgQueue_t;
/* Maximum message size allowed by CNU */
#define CPR_MAX_MSG_SIZE 8192
/* Our CNU msgtype */
#ifdef SIP_OS_WINDOWS
#define PHONE_IPC_MSG 0xF005
/* Msg buffer layout */
struct msgbuffer {
int32_t mtype; /* Message type */
void *msgPtr; /* Ptr to msg */
void *usrPtr; /* Ptr to user data */
};
#else
#define PHONE_IPC_MSG 1
/*
* Mutex for updating the message queue list
*/
extern pthread_mutex_t msgQueueListMutex;
#endif /* SIP_OS_WINDOWS */
/* Function prototypes */
/**
* Creates a message queue
*
* @brief The cprCreateMessageQueue function is called to allow the OS to
* perform whatever work is needed to create a message queue.
* If the name is present, CPR should assign this name to the message queue to assist in
* debugging. The message queue depth is the second input parameter and is for
* setting the desired queue depth. This parameter may not be supported by all OS.
* Its primary intention is to set queue depth beyond the default queue depth
* limitation.
* On any OS where there is no limit on the message queue depth or
* its queue depth is sufficiently large then this parameter is ignored on that
* OS.
*
* @param[in] name - name of the message queue (optional)
* @param[in] depth - the message queue depth, optional field which should
* default if set to zero(0)
*
* @return Msg queue handle or NULL if init failed, errno should be provided
*
* @note the actual message queue depth will be bounded by the
* standard system message queue depth and CPR_MAX_MSG_Q_DEPTH.
* If 'depth' is outside of the bounds, the value will be
* reset automatically.
*/
cprMsgQueue_t
cprCreateMessageQueue(const char *name, uint16_t depth);
#ifdef CPR_USE_SET_MESSAGE_QUEUE_THREAD
/**
* cprSetMessageQueueThread
* @brief Associate a thread with the message queue
*
* This method is used by pSIPCC to associate a thread and a message queue.
* @param[in] msgQueue - msg queue to set
* @param[in] thread - CPR thread to associate with queue
*
* @return CPR_SUCCESS or CPR_FAILURE
*
* @note Nothing is done to prevent overwriting the thread ID
* when the value has already been set.
*/
cprRC_t
cprSetMessageQueueThread(cprMsgQueue_t msgQueue, cprThread_t thread);
#endif
/**
* cprGetMessage
@ -128,44 +55,6 @@ cprGetMessage(cprMsgQueue_t msgQueue,
boolean waitForever,
void** usrPtr);
/**
* cprSendMessage
* @brief Place a message on a particular queue. Note that caller may
* block (see comments below)
*
* @param[in] msgQueue - msg queue on which to place the message
* @param[in] msg - pointer to the msg to place on the queue
* @param[in] ppUserData - pointer to a pointer to user defined data
*
* @return CPR_SUCCESS or CPR_FAILURE, errno should be provided
*
* @note 1. Messages queues are set to be non-blocking, those cases
* where the system call fails with a would-block error code
* (EAGAIN) the function will attempt other mechanisms described
* below.
* @note 2. If enabled with an extended message queue, either via a
* call to cprCreateMessageQueue with depth value or a call to
* cprSetExtendMessageQueueDepth() (when unit testing), the message
* will be added to the extended message queue and the call will
* return successfully. When room becomes available on the
* system's message queue, those messages will be added.
* @note 3. If the message queue becomes full and no space is availabe
* on the extended message queue, then the function will attempt
* to resend the message up to CPR_ATTEMPTS_TO_SEND and the
* calling thread will *BLOCK* CPR_SND_TIMEOUT_WAIT_INTERVAL
* milliseconds after each failed attempt. If unsuccessful
* after all attempts then EGAIN error code is returned.
* @note 4. This applies to all CPR threads, including the timer thread.
* So it is possible that the timer thread would be forced to
* sleep which would have the effect of delaying all active
* timers. The work to fix this rare situation is not considered
* worth the effort to fix....so just leaving as is.
*/
cprRC_t
cprSendMessage(cprMsgQueue_t msgQueue,
void* msg,
void** usrPtr);
/**
* cprGetDepth
*

View File

@ -125,11 +125,6 @@
#endif
#include "plat_debug.h"
/**
* Mutex to manage message queue list.
*/
extern pthread_mutex_t msgQueueListMutex;
/**
* Boolean to check that cprPreInit been called
*/
@ -171,21 +166,8 @@ cprPreInit (void)
return CPR_SUCCESS;
}
pre_init_called = TRUE;
/*
* Create message queue list mutex
*/
returnCode = pthread_mutex_init(&msgQueueListMutex, NULL);
if (returnCode != 0) {
CPR_ERROR("%s: MsgQueue Mutex init failure %d\n", fname, returnCode);
return CPR_FAILURE;
}
#if CPR_TIMERS_ENABLED
returnCode = cpr_timer_pre_init();
if (returnCode != 0) {
CPR_ERROR("%s: timer pre init failed %d\n", fname, returnCode);
return CPR_FAILURE;
}
#endif
(void)fname;
(void)returnCode;
return CPR_SUCCESS;
}

View File

@ -5,7 +5,6 @@
#include "cpr.h"
#include "cpr_stdlib.h"
#include "cpr_stdio.h"
#include "thread_monitor.h"
#include "prtypes.h"
#include "mozilla/Assertions.h"
#include <pthread.h>

View File

@ -1228,76 +1228,6 @@ cprRC_t start_timer_service_loop (void)
*
*/
void process_expired_timers() {
static const char fname[] = "process_expired_timer";
cprCallBackTimerMsg_t *timerMsg;
void *syshdr;
boolean processingTimers;
/* nothing to do if no timers running */
if (timerListHead == NULL) {
return;
}
/* nothing to do if head has not expired */
if (timerListHead->duration > 0) {
return;
}
/* There are one or more expired timers on the list */
processingTimers = TRUE;
while (processingTimers) {
if (timerListHead != NULL) {
/*
* Send msg to queue to indicate this timer has expired
*/
if (timerListHead->duration <= 0) {
timerMsg = (cprCallBackTimerMsg_t *)
cpr_malloc(sizeof(cprCallBackTimerMsg_t));
if (timerMsg) {
timerMsg->expiredTimerName =
timerListHead->cprTimerPtr->name;
//CPR_INFO("%s: timer %s expired..\n",fname,
// timerMsg->expiredTimerName);
timerMsg->expiredTimerId =
timerListHead->cprTimerPtr->applicationTimerId;
timerMsg->usrData =
timerListHead->cprTimerPtr->data;
syshdr = cprGetSysHeader(timerMsg);
if (syshdr) {
fillInSysHeader(syshdr,
timerListHead->cprTimerPtr->applicationMsgId,
sizeof(cprCallBackTimerMsg_t), timerMsg);
if (cprSendMessage(timerListHead->cprTimerPtr->callBackMsgQueue,
timerMsg, (void **) &syshdr) == CPR_FAILURE) {
cprReleaseSysHeader(syshdr);
cpr_free(timerMsg);
CPR_ERROR("%s - Call to cprSendMessage failed\n", fname);
CPR_ERROR("%s - Unable to send timer %s expiration msg\n",
fname, timerListHead->cprTimerPtr->name);
}
} else {
cpr_free(timerMsg);
CPR_ERROR("%s - Call to cprGetSysHeader failed\n", fname);
CPR_ERROR("%s - Unable to send timer %s expiration msg\n",
fname, timerListHead->cprTimerPtr->name);
}
} else {
CPR_ERROR("%s - Call to cpr_malloc failed\n", fname);
CPR_ERROR("%s - Unable to send timer %s expiration msg\n",
fname, timerListHead->cprTimerPtr->name);
}
(void) removeTimer(timerListHead->cprTimerPtr);
} else {
/* The rest of the timers on the list have not yet expired */
processingTimers = FALSE;
}
} else {
/* The timer list is now empty */
processingTimers = FALSE;
}
} /* still more to process */
}
/**

View File

@ -70,21 +70,6 @@ void cprEnableSwap (void);
#define CIPPORT_EPH_HI 0xCFFF
/*
* Msg queue information needed to hide OS differences in implementation.
* To use msg queues, the application code may pass in a name to the
* create function for msg queues. CPR does not use this field, it is
* solely for the convenience of the application and to aid in debugging.
*/
typedef struct {
const char *name;
uint16_t queueId;
uint16_t currentCount;
void *handlePtr;
} cpr_msg_queue_t;
__END_DECLS

View File

@ -49,9 +49,6 @@ static uint32_t removed_count; /* Number of timers removed. */
static uint32_t inserted_count; /* Number of timers inserted. */
static uint32_t cpr_timer_init; /* Bool indicating the timer system is initialized */
cprMsgQueue_t tmr_msgq;
cprThread_t tmr_thread;
/*
* Internal CPR function to fill in data in the sysheader.
@ -533,73 +530,6 @@ cpr_timer_expired (void)
void
cpr_timer_event_process (void)
{
unsigned int now; /* Current time */
cprTimerBlk *timer; /* User to traverse timer list */
cprCallBackTimerMsg_t *timerMsg;
void *syshdr;
cprDisableSwap();
now = current_time();
timer = cprTimerPendingList;
while (timer != NULL) {
if (timer->expiration_time <= now) {
/* Timer has expired. */
timer_remove(timer); /* Remove from active list */
timer->flags &= ~TIMER_ACTIVE;
expired_count++; /* Debug counter */
cprEnableSwap();
/* Send msg to queue to indicate this timer has expired */
timerMsg = (cprCallBackTimerMsg_t *)
cpr_malloc(sizeof (cprCallBackTimerMsg_t));
if (timerMsg) {
timerMsg->expiredTimerName = timer->name;
timerMsg->expiredTimerId = timer->applicationTimerId;
timerMsg->usrData = timer->data;
syshdr = cprGetSysHeader(timerMsg);
if (syshdr) {
fillInSysHeader(syshdr, timer->applicationMsgId,
sizeof(cprCallBackTimerMsg_t), timerMsg);
if (cprSendMessage(timer->callBackMsgQueue,
timerMsg, (void **) &syshdr) == CPR_FAILURE) {
cprReleaseSysHeader(syshdr);
cpr_free(timerMsg);
CPR_ERROR("Call to cprSendMessage failed.\n");
CPR_ERROR("Unable to send timer %s expiration msg.\n",
timer->name);
}
} else {
cpr_free(timerMsg);
CPR_ERROR("Call to cprGetSysHeader failed.\n");
CPR_ERROR("Unable to send timer %s expiration msg.\n",
timer->name);
}
} else {
CPR_ERROR("Call to cpr_malloc failed.\n");
CPR_ERROR("Unable to send timer %s expiration msg.\n",
timer->name);
}
cprDisableSwap();
/* Timer expiration function may have manipulated the
* timer list. Need to start over at front of timer list looking
* for expired timers.
*/
timer = cprTimerPendingList; /* Start at front of list */
} else {
/* No more expired timers. Bail */
break;
}
}
cprEnableSwap();
}
@ -621,18 +551,6 @@ cpr_timer_event_process (void)
void
cpr_timer_tick (void)
{
/* windows is driving this at a 20ms rate */
ticker += 20;
if (cpr_timer_init) {
/* Only kick the timer task if there is a timer which
* has expired and ready to be processed.
*/
if (cpr_timer_expired()) {
/* Timer task is initialized and we have an expired timer...Kick it. */
cprSendMessage(tmr_msgq, tmr_msg, NULL);
}
}
}
@ -656,42 +574,6 @@ current_time (void)
}
/*------------------------------------------------------------------------------
* NAME: CPRTMRTask()
*
* PARAMETERS:
* None.
*
* RETURNS:
* SUCCESS
*
* DESCRIPTION:
* This is the windows version of the CPR timer task
*
*----------------------------------------------------------------------------*/
int32_t
CPRTMRTask (void *data)
{
void *msg;
while (cpr_timer_init) {
/* Wait for tick */
msg = cprGetMessage(tmr_msgq, TRUE, NULL);
if (msg) {
/*
* No need to free the msg here as the only msg
* sent to the timer task is a static string to
* wake it up.
*/
cpr_timer_event_process();
}
}
return (CPR_SUCCESS);
}
/*------------------------------------------------------------------------------
* NAME: cprTimerSystemInit()
*
@ -712,8 +594,6 @@ cprTimerSystemInit (void)
/* Create timer lists and free buffer pool */
cprTimerPendingList = NULL;
tmr_msgq = cprCreateMessageQueue("TMRQ", 0);
expired_count = 0;
removed_count = 0;
inserted_count = 0;
@ -721,13 +601,6 @@ cprTimerSystemInit (void)
ticker = 0;
cpr_timer_init = 1;
tmr_thread = cprCreateThread("CprTmrTsk", (cprThreadStartRoutine)CPRTMRTask,
CPRTMR_STK, CPRTMR_PRIO, NULL);
if (!tmr_thread) {
CPR_ERROR("Failed to create CPR Timer Task");
}
cprSetMessageQueueThread(tmr_msgq, tmr_thread);
// bind_show_keyword("timers", display_active_timers);
}
@ -736,7 +609,4 @@ void
cpr_timer_stop (void)
{
cpr_timer_init = 0;
/* Kick timer to wake it up */
cprSendMessage(tmr_msgq, tmr_msg, NULL);
cprDestroyThread(tmr_thread);
}

View File

@ -30,8 +30,7 @@ CSF_IMPLEMENT_WRAP(CC_SIPCCCall, cc_call_handle_t);
CC_SIPCCCall::CC_SIPCCCall (cc_call_handle_t aCallHandle) :
callHandle(aCallHandle),
pMediaData(new CC_SIPCCCallMediaData(nullptr, false, false, -1)),
m_lock("CC_SIPCCCall")
pMediaData(new CC_SIPCCCallMediaData(nullptr, false, false, -1))
{
CSFLogInfo( logTag, "Creating CC_SIPCCCall %u", callHandle );
@ -164,7 +163,6 @@ bool CC_SIPCCCall::endCall()
bool CC_SIPCCCall::sendDigit (cc_digit_t digit)
{
AudioTermination * pAudio = VcmSIPCCBinding::getAudioTermination();
mozilla::MutexAutoLock lock(m_lock);
// Convert public digit (as enum or char) to RFC2833 form.
int digitId = -1;
@ -345,7 +343,6 @@ bool CC_SIPCCCall::setAudioMute(bool mute)
pMediaData->audioMuteState = mute;
// we need to set the mute status of all audio streams in the map
{
mozilla::MutexAutoLock lock(m_lock);
for (StreamMapType::iterator entry = pMediaData->streamMap.begin(); entry != pMediaData->streamMap.end(); entry++)
{
if (entry->second.isVideo == false)
@ -379,7 +376,6 @@ bool CC_SIPCCCall::setVideoMute(bool mute)
pMediaData->videoMuteState = mute;
// we need to set the mute status of all audio streams in the map
{
mozilla::MutexAutoLock lock(m_lock);
for (StreamMapType::iterator entry = pMediaData->streamMap.begin(); entry != pMediaData->streamMap.end(); entry++)
{
if (entry->second.isVideo == true)
@ -412,7 +408,6 @@ void CC_SIPCCCall::addStream(int streamId, bool isVideo)
CSFLogInfo( logTag, "addStream: %d video=%s callhandle=%u",
streamId, isVideo ? "TRUE" : "FALSE", callHandle);
{
mozilla::MutexAutoLock lock(m_lock);
pMediaData->streamMap[streamId].isVideo = isVideo;
}
// The new stream needs to be given any properties that the call has for it.
@ -477,8 +472,6 @@ void CC_SIPCCCall::addStream(int streamId, bool isVideo)
void CC_SIPCCCall::removeStream(int streamId)
{
mozilla::MutexAutoLock lock(m_lock);
if ( pMediaData->streamMap.erase(streamId) != 1)
{
CSFLogError( logTag, "removeStream stream that was never in the streamMap: %d", streamId);
@ -491,7 +484,6 @@ bool CC_SIPCCCall::setVolume(int volume)
AudioTermination * pAudio = VcmSIPCCBinding::getAudioTermination();
{
mozilla::MutexAutoLock lock(m_lock);
for (StreamMapType::iterator entry = pMediaData->streamMap.begin(); entry != pMediaData->streamMap.end(); entry++)
{
if (entry->second.isVideo == false)
@ -540,7 +532,6 @@ void CC_SIPCCCall::createOffer (cc_media_options_t *options, Timecard *tc) {
*/
void CC_SIPCCCall::createAnswer (Timecard *tc) {
CCAPI_CreateAnswer(callHandle, tc);
}
void CC_SIPCCCall::setLocalDescription(cc_jsep_action_t action,

View File

@ -17,8 +17,6 @@ typedef struct Timecard Timecard;
#include "common/Wrapper.h"
#include "common/csf_common.h"
#include "mozilla/Mutex.h"
#include "base/lock.h"
namespace CSF
{
@ -38,21 +36,18 @@ namespace CSF
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_SIPCCCallMediaData)
CC_SIPCCCallMediaData():
remoteWindow(nullptr),
streamMapMutex("CC_SIPCCCallMediaData"),
audioMuteState(false),
videoMuteState(false),
volume(-1){}
CC_SIPCCCallMediaData(VideoWindowHandle remoteWindow,
bool audioMuteState, bool videoMuteState, int volume):
remoteWindow(remoteWindow),
streamMapMutex("CC_SIPCCCallMediaData"),
audioMuteState(audioMuteState),
videoMuteState(videoMuteState),
volume(volume) {}
VideoWindowHandle remoteWindow;
ExternalRendererHandle extRenderer;
VideoFormat videoFormat;
mozilla::Mutex streamMapMutex;
StreamMapType streamMap;
bool audioMuteState;
bool videoMuteState;
@ -135,8 +130,6 @@ namespace CSF
private:
virtual bool setAudioMute(bool mute);
virtual bool setVideoMute(bool mute);
mozilla::Mutex m_lock;
};
}

View File

@ -31,14 +31,15 @@ CC_DevicePtr CC_SIPCCDevice::createDevice ()
CC_SIPCCDevicePtr pSIPCCDevice = CC_SIPCCDevice::wrap(deviceHandle);
pSIPCCDevice->enableVideo(true);
pSIPCCDevice->enableCamera(true);
return pSIPCCDevice.get();
}
CC_SIPCCDevice::CC_SIPCCDevice (cc_device_handle_t aDeviceHandle)
: deviceHandle(aDeviceHandle)
{
enableVideo(true);
enableCamera(true);
}
CC_DeviceInfoPtr CC_SIPCCDevice::getDeviceInfo ()

View File

@ -313,7 +313,6 @@ CC_SIPCCService::CC_SIPCCService()
: loggingMask(0),
bCreated(false),
bStarted(false),
m_lock("CC_SIPCCService"),
bUseConfig(false)
{
// Only one instance allowed!
@ -606,8 +605,6 @@ void CC_SIPCCService::onDeviceEvent(ccapi_device_event_e type, cc_device_handle_
return;
}
mozilla::MutexAutoLock lock(_self->m_lock);
CC_SIPCCDevicePtr devicePtr = CC_SIPCCDevice::wrap(handle);
if (devicePtr == nullptr)
{
@ -638,8 +635,6 @@ void CC_SIPCCService::onFeatureEvent(ccapi_device_event_e type, cc_deviceinfo_re
return;
}
mozilla::MutexAutoLock lock(_self->m_lock);
cc_device_handle_t hDevice = CCAPI_Device_getDeviceID();
CC_DevicePtr devicePtr = CC_SIPCCDevice::wrap(hDevice).get();
if (devicePtr == nullptr)
@ -670,8 +665,6 @@ void CC_SIPCCService::onLineEvent(ccapi_line_event_e eventType, cc_lineid_t line
return;
}
mozilla::MutexAutoLock lock(_self->m_lock);
CC_LinePtr linePtr = CC_SIPCCLine::wrap(line).get();
if (linePtr == nullptr)
{
@ -700,8 +693,6 @@ void CC_SIPCCService::onCallEvent(ccapi_call_event_e eventType, cc_call_handle_t
return;
}
mozilla::MutexAutoLock lock(_self->m_lock);
CC_SIPCCCallPtr callPtr = CC_SIPCCCall::wrap(handle);
if (callPtr == nullptr)
{
@ -739,7 +730,6 @@ void CC_SIPCCService::onCallEvent(ccapi_call_event_e eventType, cc_call_handle_t
void CC_SIPCCService::addCCObserver ( CC_Observer * observer )
{
mozilla::MutexAutoLock lock(m_lock);
if (observer == nullptr)
{
CSFLogError( logTag, "NULL value for \"observer\" passed to addCCObserver().");
@ -751,14 +741,12 @@ void CC_SIPCCService::addCCObserver ( CC_Observer * observer )
void CC_SIPCCService::removeCCObserver ( CC_Observer * observer )
{
mozilla::MutexAutoLock lock(m_lock);
ccObservers.erase(observer);
}
//Notify Observers
void CC_SIPCCService::notifyDeviceEventObservers (ccapi_device_event_e eventType, CC_DevicePtr devicePtr, CC_DeviceInfoPtr info)
{
// m_lock must be held by the function that called us
set<CC_Observer*>::const_iterator it = ccObservers.begin();
for ( ; it != ccObservers.end(); it++ )
{
@ -768,7 +756,6 @@ void CC_SIPCCService::notifyDeviceEventObservers (ccapi_device_event_e eventType
void CC_SIPCCService::notifyFeatureEventObservers (ccapi_device_event_e eventType, CC_DevicePtr devicePtr, CC_FeatureInfoPtr info)
{
// m_lock must be held by the function that called us
set<CC_Observer*>::const_iterator it = ccObservers.begin();
for ( ; it != ccObservers.end(); it++ )
{
@ -778,7 +765,6 @@ void CC_SIPCCService::notifyFeatureEventObservers (ccapi_device_event_e eventTyp
void CC_SIPCCService::notifyLineEventObservers (ccapi_line_event_e eventType, CC_LinePtr linePtr, CC_LineInfoPtr info)
{
// m_lock must be held by the function that called us
set<CC_Observer*>::const_iterator it = ccObservers.begin();
for ( ; it != ccObservers.end(); it++ )
{
@ -788,7 +774,6 @@ void CC_SIPCCService::notifyLineEventObservers (ccapi_line_event_e eventType, CC
void CC_SIPCCService::notifyCallEventObservers (ccapi_call_event_e eventType, CC_CallPtr callPtr, CC_CallInfoPtr info)
{
// m_lock must be held by the function that called us
set<CC_Observer*>::const_iterator it = ccObservers.begin();
for ( ; it != ccObservers.end(); it++ )
{
@ -868,7 +853,6 @@ void CC_SIPCCService::dtmfBurst(int digit, int direction, int duration)
{
CC_SIPCCCallMediaDataPtr pMediaData = (*it)->getMediaData();
mozilla::MutexAutoLock lock(pMediaData->streamMapMutex);
for (StreamMapType::iterator entry = pMediaData->streamMap.begin(); entry != pMediaData->streamMap.end(); entry++)
{
if (entry->second.isVideo == false)
@ -979,7 +963,6 @@ void CC_SIPCCService::onKeyFrameRequested( int stream )
{
CC_SIPCCCallMediaDataPtr pMediaData = (*it)->getMediaData();
mozilla::MutexAutoLock lock(pMediaData->streamMapMutex);
for (StreamMapType::iterator entry = pMediaData->streamMap.begin(); entry != pMediaData->streamMap.end(); entry++)
{
if ((entry->first==stream) && (entry->second.isVideo == true))

View File

@ -23,12 +23,10 @@ extern "C" {
#include "CSFVideoControlWrapper.h"
#include "CSFMediaProvider.h"
#include "base/lock.h"
#include "base/waitable_event.h"
#include <vector>
#include <set>
#include "mozilla/Mutex.h"
namespace CSF
{
@ -129,7 +127,6 @@ namespace CSF
// SIPCC lifecycle
bool bCreated;
bool bStarted;
mozilla::Mutex m_lock;
// Media Lifecycle
VcmSIPCCBinding vcmMediaBridge;