From 316a2e507ad522655d80b3d18ba2ee295acc5947 Mon Sep 17 00:00:00 2001 From: yanmorin <yanmorin> Date: Sun, 30 Oct 2005 02:26:00 +0000 Subject: [PATCH] Mutex Cleaning --- src/managerimpl.cpp | 93 ++++++--------- src/managerimpl.h | 284 +++++++++++++++++++++----------------------- src/sipvoiplink.cpp | 12 +- 3 files changed, 181 insertions(+), 208 deletions(-) diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp index 2b97be5efb..9f7374e643 100644 --- a/src/managerimpl.cpp +++ b/src/managerimpl.cpp @@ -196,9 +196,9 @@ ManagerImpl::setGui (GuiFramework* gui) Call * ManagerImpl::pushBackNewCall (CALLID id, enum CallType type) { + ost::MutexLock m(_mutex); Call* call = new Call(id, type, _voIPLinkVector.at(DFT_VOIP_LINK)); // Set the wanted voip-link (first of the list) - ost::MutexLock m(_mutex); _callVector.push_back(call); return call; } @@ -232,7 +232,7 @@ ManagerImpl::deleteCall (CALLID id) while(iter!=_callVector.end()) { Call *call = *iter; if (call != NULL && call->getId() == id) { - if (call->getFlagNotAnswered() || call->isIncomingType()) { + if (call->getFlagNotAnswered() && call->isIncomingType()) { decWaitingCall(); } delete (*iter); *iter = NULL; @@ -256,7 +256,7 @@ ManagerImpl::outgoingCall (const std::string& to) CALLID id = generateNewCallId(); Call *call = pushBackNewCall(id, Outgoing); _debug("Outgoing Call with identifiant %d\n", id); - + ost::MutexLock m(_mutex); call->setState(Call::Progressing); call->setCallerIdNumber(to); if (call->outgoingCall(to) == 0) { @@ -347,7 +347,7 @@ ManagerImpl::onHoldCall (CALLID id) if ( call->getState() == Call::OnHold || call->isNotAnswered()) { return 1; } - setCurrentCallId(0); + _currentCallId = 0; return call->onHold(); } @@ -358,18 +358,19 @@ ManagerImpl::onHoldCall (CALLID id) int ManagerImpl::offHoldCall (CALLID id) { - stopTone(); ost::MutexLock m(_mutex); + stopTone(); Call* call = getCall(id); - if (call == NULL) { + if (call == 0) { return -1; } if (call->getState() == Call::OffHold) { return 1; } - setCurrentCallId(id); + _currentCallId = id; int returnValue = call->offHold(); - if (returnValue) { + // start audio if it's ok + if (returnValue != -1) { getAudioDriver()->startStream(); } return returnValue; @@ -384,10 +385,10 @@ ManagerImpl::transferCall (CALLID id, const std::string& to) { ost::MutexLock m(_mutex); Call* call = getCall(id); - if (call == NULL) { + if (call == 0) { return -1; } - setCurrentCallId(0); + _currentCallId = 0; return call->transfer(to); } @@ -430,7 +431,7 @@ ManagerImpl::refuseCall (CALLID id) } int refuse = call->refuse(); - setCurrentCallId(0); + _currentCallId = 0; deleteCall(id); stopTone(); return refuse; @@ -630,7 +631,7 @@ ManagerImpl::callSetInfo(CALLID id, const std::string& name, const std::string& { ost::MutexLock m(_mutex); Call* call = getCall(id); - if (call != NULL) { + if (call != 0) { call->setCallerIdName(name); call->setCallerIdNumber(number); } @@ -775,7 +776,7 @@ ManagerImpl::peerHungupCall (CALLID id) deleteCall(id); call->setState(Call::Hungup); - setCurrentCallId(0); + _currentCallId = 0; return 1; } @@ -929,8 +930,9 @@ ManagerImpl::ringback () { void ManagerImpl::callBusy(CALLID id) { playATone(Tone::TONE_BUSY); + ost::MutexLock m(_mutex); Call* call = getCall(id); - if (call != NULL) { + if (call != 0) { call->setState(Call::Busy); } } @@ -941,11 +943,12 @@ ManagerImpl::callBusy(CALLID id) { void ManagerImpl::callFailure(CALLID id) { playATone(Tone::TONE_BUSY); + _mutex.enterMutex(); Call* call = getCall(id); - if (call != NULL) { - getCall(id)->setState(Call::Error); + if (call != 0) { + call->setState(Call::Error); } - + _mutex.leaveMutex(); if (_gui) { _gui->callFailure(id); } @@ -959,7 +962,7 @@ ManagerImpl::getTelephoneTone() return _telephoneTone->getCurrentTone(); } else { - return NULL; + return 0; } } @@ -1068,9 +1071,11 @@ ManagerImpl::generateNewCallId (void) CALLID random_id = (unsigned)rand(); // Check if already a call with this id exists + _mutex.enterMutex(); while (getCall(random_id) != NULL && random_id != 0) { random_id = rand(); } + _mutex.leaveMutex(); // If random_id is not attributed, returns it. return random_id; } @@ -1324,7 +1329,6 @@ ManagerImpl::getEvents() { bool ManagerImpl::getCallStatus(const std::string& sequenceId) { - ost::MutexLock m(_mutex); // TODO: implement account std::string accountId = "acc1"; std::string code; @@ -1333,44 +1337,20 @@ ManagerImpl::getCallStatus(const std::string& sequenceId) Call* call; if (_gui!=NULL) { + ost::MutexLock m(_mutex); CallVector::iterator iter = _callVector.begin(); while(iter!=_callVector.end()){ call = (*iter); switch( call->getState() ) { - case Call::Progressing: - code="110"; - status="Trying"; - break; - - case Call::Ringing: - code="111"; - status = "Ringing"; - break; - - case Call::Answered: - code="112"; - status = "Established"; - break; - - case Call::Busy: - code="113"; - status = "Busy"; - break; - - case Call::OnHold: - code="114"; - status = "Held"; - break; - - case Call::OffHold: - code="115"; - status = "Unheld"; - break; - - default: - code="125"; - status="Other"; + case Call::Progressing: code="110"; status="Trying"; break; + case Call::Ringing: code="111"; status = "Ringing"; break; + case Call::Answered: code="112"; status = "Established"; break; + case Call::Busy: code="113"; status = "Busy"; break; + case Call::OnHold: code="114"; status = "Held"; break; + case Call::OffHold: code="115"; status = "Unheld"; break; + default: code="125"; status="Other"; } + // No Congestion // No Wrong Number // 116 <CSeq> <call-id> <acc> <destination> Busy @@ -1599,11 +1579,10 @@ ManagerImpl::getDirListing(const std::string& sequenceId, const std::string& pat void ManagerImpl::switchCall(CALLID id) { - CALLID currentCallId = getCurrentCallId(); - if (currentCallId!=0 && id!=currentCallId) { - onHoldCall(currentCallId); + if (_currentCallId!=0 && id!=_currentCallId) { + //onHoldCall(_currentCallId); <-- this function block _mutex... } - setCurrentCallId(id); + _currentCallId = id; } -// EOF + diff --git a/src/managerimpl.h b/src/managerimpl.h index 7b20064f2e..a79a8c4a49 100644 --- a/src/managerimpl.h +++ b/src/managerimpl.h @@ -81,94 +81,83 @@ typedef std::list<std::string> TokenList; class ManagerImpl { public: - ManagerImpl (void); - ~ManagerImpl (void); + ManagerImpl (void); + ~ManagerImpl (void); // Init a new VoIPLink, audio codec and audio driver - void init (void); - void terminate (void); + void init (void); + void terminate (void); // Set the graphic user interface - void setGui (GuiFramework* gui); + void setGui (GuiFramework* gui); - // Accessor to error - //Error* error(void) const { return _error; } - // Accessor to audiodriver - // it multi-thread and use mutex internally - AudioLayer* getAudioDriver(void) const { return _audiodriverPA ;} - - // Accessor to current call id - CALLID getCurrentCallId (void) { - ost::MutexLock m(_mutex); return _currentCallId; - } - // Modifior of current call id - void setCurrentCallId (CALLID id) { - ost::MutexLock m(_mutex); _currentCallId = id; - } - - // Accessor to VoIPLinkVector + // it's multi-thread and use mutex internally + AudioLayer* getAudioDriver(void) const { return _audiodriverPA ;} + + // Accessor to VoIPLinkVector VoIPLinkVector* getVoIPLinkVector (void) {return &_voIPLinkVector;} - // Codec Descriptor + // Codec Descriptor CodecDescriptorVector* getCodecDescVector(void) {return &_codecDescVector;} /* - * Attribute a new random id for a new call - * and check if it's already attributed to existing calls. - * If not exists, returns 'id' otherwise return 0 - */ - CALLID generateNewCallId (void); + * Attribute a new random id for a new call + * and check if it's already attributed to existing calls. + * If not exists, returns 'id' otherwise return 0 + */ + CALLID generateNewCallId (void); - /* - * Add a new call at the end of the CallVector with identifiant 'id' - */ + /* + * Add a new call at the end of the CallVector with identifiant 'id' + */ Call* pushBackNewCall (CALLID id, enum CallType type); void callSetInfo(CALLID id, const std::string& name, const std::string& number); bool callCanBeAnswered(CALLID id); bool callCanBeClosed(CALLID id); bool callIsOnHold(CALLID id); - /* - * Functions which occur with a user's action - */ - int outgoingCall (const std::string& to); - int hangupCall (CALLID id); - int cancelCall (CALLID id); - int answerCall (CALLID id); - int onHoldCall (CALLID id); - int offHoldCall (CALLID id); - int transferCall (CALLID id, const std::string& to); + /* + * Functions which occur with a user's action + */ + int outgoingCall (const std::string& to); + int hangupCall (CALLID id); + int cancelCall (CALLID id); + int answerCall (CALLID id); + int onHoldCall (CALLID id); + int offHoldCall (CALLID id); + int transferCall (CALLID id, const std::string& to); void mute(); void unmute(); - int refuseCall (CALLID id); + int refuseCall (CALLID id); - bool saveConfig (void); - int registerVoIPLink (void); - int unregisterVoIPLink (void); + bool saveConfig (void); + int registerVoIPLink (void); + int unregisterVoIPLink (void); - /** - * Handle choice of the DTMF-send-way - * - * @param id: callid of the line. + /** + * Handle choice of the DTMF-send-way + * + * @param id: callid of the line. * @param code: pressed key. - */ - bool sendDtmf (CALLID id, char code); - bool playDtmf (char code); - bool playTone (); + */ + bool sendDtmf (CALLID id, char code); + bool playDtmf (char code); + bool playTone (); void stopTone(); - - int incomingCall (CALLID id, const std::string& name, const std::string& number); - void peerAnsweredCall (CALLID id); - int peerRingingCall (CALLID id); - int peerHungupCall (CALLID id); - void displayTextMessage (CALLID id, const std::string& message); - void displayErrorText (CALLID id, const std::string& message); - void displayError (const std::string& error); - void displayStatus (const std::string& status); + CALLID getCurrentCallId() { ost::MutexLock m(_mutex); return _currentCallId; } + + int incomingCall (CALLID id, const std::string& name, const std::string& number); + void peerAnsweredCall (CALLID id); + int peerRingingCall (CALLID id); + int peerHungupCall (CALLID id); + void displayTextMessage (CALLID id, const std::string& message); + void displayErrorText (CALLID id, const std::string& message); + void displayError (const std::string& error); + void displayStatus (const std::string& status); void displayConfigError(const std::string& message); - void startVoiceMessageNotification (const std::string& nb_msg); - void stopVoiceMessageNotification (void); + void startVoiceMessageNotification (const std::string& nb_msg); + void stopVoiceMessageNotification (void); // configuration function requests bool getEvents(); @@ -179,27 +168,25 @@ public: bool getConfigAll(const std::string& sequenceId); bool getConfig(const std::string& section, const std::string& name, TokenList& arg); bool setConfig(const std::string& section, const std::string& name, const std::string& value); - bool setConfig(const std::string& section, const std::string& name, -int value); + bool setConfig(const std::string& section, const std::string& name, int value); bool getConfigList(const std::string& sequenceId, const std::string& name); // configuration function for extern // throw an Conf::ConfigTreeItemException if not found int getConfigInt(const std::string& section, const std::string& name); - std::string getConfigString(const std::string& section, const std::string& -name); + std::string getConfigString(const std::string& section, const std::string& name); /* * Handle audio sounds heard by a caller while they wait for their * connection to a called party to be completed. */ - void ringback (); + void ringback (); /* * Handle played music when an incoming call occurs */ - void ringtone (); - void congestion (); + void ringtone (); + void congestion (); void callBusy(CALLID id); void callFailure(CALLID id); @@ -214,46 +201,38 @@ name); /* * Notification of incoming call when you are already busy */ - void notificationIncomingCall (void); + void notificationIncomingCall (void); /* * Get information about firewall * @param stunSvrAddr: stun server */ - void getStunInfo (StunAddress4& stunSvrAddr); - bool useStun (void); + void getStunInfo (StunAddress4& stunSvrAddr); + bool useStun (void); /* * Inline functions to manage volume control * Read by main thread and AudioLayer thread * Write by main thread only */ - unsigned short getSpkrVolume(void) { - return _spkr_volume; - } - void setSpkrVolume(unsigned short spkr_vol) { - _spkr_volume = spkr_vol; - } - unsigned short getMicVolume(void) { - return _mic_volume; - } - void setMicVolume(unsigned short mic_vol) { - _mic_volume = mic_vol; - } + unsigned short getSpkrVolume(void) { return _spkr_volume; } + void setSpkrVolume(unsigned short spkr_vol) { _spkr_volume = spkr_vol; } + unsigned short getMicVolume(void) { return _mic_volume; } + void setMicVolume(unsigned short mic_vol) { _mic_volume = mic_vol; } - bool hasLoadedSetup() { return _setupLoaded; } - - /* - * Manage information about firewall - */ - inline int getFirewallPort (void) { return _firewallPort; } - inline void setFirewallPort (int port) { _firewallPort = port; } - inline std::string getFirewallAddress (void) { return _firewallAddr; } + /* + * Manage information about firewall + */ + inline int getFirewallPort (void) { return _firewallPort; } + inline void setFirewallPort (int port) { _firewallPort = port; } + inline std::string getFirewallAddress (void) { return _firewallAddr; } /* * Init default values for the different fields */ - void initConfigFile (void); + void initConfigFile (void); + bool hasLoadedSetup() { return _setupLoaded; } + enum REGISTRATION_STATE { UNREGISTERED, @@ -264,28 +243,26 @@ name); REGISTRATION_STATE getRegistrationState() { return _registerState; } private: + /** + * Create .PROGNAME directory in home user and create + * configuration tree from the settings file if this file exists. + * + * @return 0 if creating file failed + * 1 if config-file exists + * 2 if file doesn't exist yet. + */ + int createSettingsPath (void); - - /** - * Create .PROGNAME directory in home user and create - * configuration tree from the settings file if this file exists. - * - * @return 0 if creating file failed - * 1 if config-file exists - * 2 if file doesn't exist yet. - */ - int createSettingsPath (void); - - /* - * Initialize audiocodec - */ - void initAudioCodec(void); + /* + * Initialize audiocodec + */ + void initAudioCodec(void); void unloadAudioCodec(void); - /* - * Initialize audiodriver - */ - void selectAudioDriver (void); + /* + * Initialize audiodriver + */ + void selectAudioDriver (void); /* * Initialize zeroconf module and scanning @@ -322,45 +299,62 @@ private: * @return false if the driver is uninitialize */ bool playATone(Tone::TONEID toneId); - //bool playATone(unsigned int tone); - ///////////////////// - // Private variables - ///////////////////// - ToneGenerator* _tone; + ///////////////////// + // Private variables + ///////////////////// + ToneGenerator* _tone; TelephoneTone* _telephoneTone; ost::Mutex _toneMutex; int _toneType; - //Error* _error; - GuiFramework* _gui; - AudioLayer* _audiodriverPA; - DTMF _key; + // + // Multithread variable with extern accessor and change only inside the main thread + // + /** Vector of VoIPLink */ + VoIPLinkVector _voIPLinkVector; + /** Vector of CodecDescriptor */ + CodecDescriptorVector _codecDescVector; - /* - * Vector of VoIPLink - */ - VoIPLinkVector _voIPLinkVector; - - /* - * Vector of calls - */ - CallVector _callVector; + + // + // Multithread variable with extern accessor (mutex inside) + // + AudioLayer* _audiodriverPA; + + // + // Multithread variable (protected by _mutex) + // + /** Mutex to protect access to code section */ + ost::Mutex _mutex; + /* Vector of calls */ + CallVector _callVector; + // Current callid : protected implicitely by function using _mutex + CALLID _currentCallId; + // functions that set mutex: + // terminate, pushBackNewCall, generateNewCallId, outgoingCall (after gen/push) + // hangupCall, cancelCall, answerCall, onHoldCall, offHoldCall, transferCall, refuseCall, + // callSetInfo, callCanBeClosed, callCanBeAnswered, callIsOnHold, incomingCall, + // peerAnsweredCall, peerRingingCall, peerHunguCall, callBusy, callFailure + // getCallStatus, getCurrentCallId + // functions that are called by those functions + // getCall, deleteCall, stopTone, switchCall, decWaitingCall, setCurrentCallId, getAudioDriver, ringtone, incWaitingCall + + // warning, incomingCallWaiting | incWaitingCall | decWaitingCall are prtected by _incomingCallMutex + - /* - * Vector of CodecDescriptor - */ - CodecDescriptorVector _codecDescVector; + // + // Multithread variable (non protected) + // + GuiFramework* _gui; + // Main thread + DTMF _key; // map of codec (for configlist request) CodecMap _codecMap; - /* - * Mutex to protect access to code section - */ - ost::Mutex _mutex; - /** + * Multithreaded * Incomings Call: */ ost::Mutex _incomingCallMutex; @@ -368,14 +362,12 @@ private: void incWaitingCall(void); void decWaitingCall(void); - // Current callid - CALLID _currentCallId; /** * Path of the ConfigFile */ - std::string _path; - int _exist; + std::string _path; + int _exist; int _setupLoaded; // To handle volume control @@ -384,8 +376,8 @@ private: short _mic_volume_before_mute; // To handle firewall - int _firewallPort; - std::string _firewallAddr; + int _firewallPort; + std::string _firewallAddr; // true if we tried to register Once void initRegisterVoIPLink(); diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp index c62464975b..586537613f 100644 --- a/src/sipvoiplink.cpp +++ b/src/sipvoiplink.cpp @@ -547,10 +547,10 @@ SipVoIPLink::offhold (CALLID id) eXosip_unlock (); // Enable audio - if (_audiortp.createNewSession (getSipCall(id)) < 0) { - _debug("FATAL: Unable to start sound (%s:%d)\n", __FILE__, __LINE__); - i = -1; - } + if (_audiortp.createNewSession (getSipCall(id)) < 0) { + _debug("FATAL: Unable to start sound (%s:%d)\n", __FILE__, __LINE__); + i = -1; + } return i; } @@ -665,7 +665,9 @@ SipVoIPLink::getEvent (void) _audiortp.closeRtpSession(); sipcall->newIncomingCall(event); - _audiortp.createNewSession(sipcall); + if(!Manager::instance().callIsOnHold(id)) { + _audiortp.createNewSession(sipcall); + } } } else { eXosip_call_send_answer(event->tid, 488, NULL); -- GitLab