I had a look at the patch, and came up with a similar patch avoiding
usage of "NonWin32Queue" and instead using new OsIntPtrMsg message,
OsMsgQ and OsMsgPool. I also made minor improvements to close mic device
code resulting in faster shutdown.
The patch doesn't change priorities of any threads. Otherwise it should
be equivalent to the published patch. Please test it and report
improved/worsened audio quality. For me, there are no problems with
minimized windows if I use wxCommunicator. What client do you use that
use experience this problem?
Please note that these fixes are only temporary until the audio
subsystem is replaced with new wrapped drivers.
Jaro
Index: sipXmediaLib/src/mp/dmaTaskWnt.cpp
===================================================================
--- sipXmediaLib/src/mp/dmaTaskWnt.cpp (revision 82)
+++ sipXmediaLib/src/mp/dmaTaskWnt.cpp (working copy)
@@ -31,6 +31,7 @@
#include "mp/MpMediaTask.h"
#include "mp/dmaTask.h"
#include "os/OsMsgPool.h"
+#include "os/OsIntPtrMsg.h"
// DEFINES
@@ -41,6 +42,11 @@
extern void closeSpeakerDevices();
// EXTERNAL VARIABLES
+extern OsMsgPool* gMicStatusPool; // MicThreadWnt
+extern OsMsgQ* gMicStatusQueue; // MicThreadWnt
+extern OsMsgPool* gSpeakerStatusPool; // SpeakerThreadWnt
+extern OsMsgQ* gSpeakerStatusQueue; // SpeakerThreadWnt
+
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS
UtlString DmaTask::mRingDeviceName = "" ;
@@ -200,7 +206,19 @@
// fire off alt heartbeat mechanism.
}
+ OsIntPtrMsg msg(OsIntPtrMsg::MP_TASK_MSG, 0); // dummy message
+ gMicStatusPool = new OsMsgPool("MicStatusPool", msg,
+ 40, 60, 100, 5,
+ OsMsgPool::SINGLE_CLIENT);
+ gSpeakerStatusPool = new OsMsgPool("SpeakerStatusPool", msg,
+ 40, 60, 100, 5,
+ OsMsgPool::SINGLE_CLIENT);
+ gMicStatusQueue = new OsMsgQ(40, OsMsgQBase::DEF_MAX_MSG_LEN,
+ OsMsgQBase::Q_PRIORITY, "MicStatusQueue");
+ gSpeakerStatusQueue = new OsMsgQ(40, OsMsgQBase::DEF_MAX_MSG_LEN,
+ OsMsgQBase::Q_PRIORITY, "SpeakerStatusQueue");
+
// start a thread to receive microphone input
// mic thread will prime the device input queue
// hMicThread = (void *)_beginthreadex(
@@ -264,15 +282,41 @@
* and that handle the audio input and output.
*/
void dmaShutdown()
-{
- PostThreadMessage(dwMicThreadID, WIM_CLOSE, 0, 0L);
- WaitForSingleObject(hMicThread, INFINITE);
- PostThreadMessage(dwSpkrThreadID, WOM_CLOSE, 0, 0L);
- WaitForSingleObject(hSpkrThread, INFINITE);
+{
+ OsIntPtrMsg *pMsg = (OsIntPtrMsg*)gMicStatusPool->findFreeMsg();
+ pMsg->setData1(WIM_CLOSE);
+ if (gMicStatusQueue->sendFromISR(*pMsg) != OS_SUCCESS)
+ {
+ osPrintf("Problem with sending message in dmaShutdown\n");
+ }
+
+ pMsg = (OsIntPtrMsg*)gSpeakerStatusPool->findFreeMsg();
+ pMsg->setData1(WOM_CLOSE);
+ if (gSpeakerStatusQueue->sendFromISR(*pMsg) != OS_SUCCESS)
+ {
+ osPrintf("Problem with sending message in dmaShutdown\n");
+ }
+
+ WaitForSingleObject(hMicThread, INFINITE);
+ WaitForSingleObject(hSpkrThread, INFINITE);
+
+ delete gMicStatusQueue;
+ gMicStatusQueue = NULL;
+ delete gMicStatusPool;
+ gMicStatusPool = NULL;
+ delete gSpeakerStatusQueue;
+ gSpeakerStatusQueue = NULL;
+ delete gSpeakerStatusPool;
+ gSpeakerStatusPool = NULL;
}
void dmaSignalMicDeviceChange()
{
- // We do simple signal WIM_DATA without data
- PostThreadMessage(dwMicThreadID, WIM_DATA, 0, 0L);
+ // We do simple signal WIM_DATA without data
+ OsIntPtrMsg *pMsg = (OsIntPtrMsg*)gMicStatusPool->findFreeMsg();
+ pMsg->setData1(WIM_DATA);
+ if (gMicStatusQueue->sendFromISR(*pMsg) != OS_SUCCESS)
+ {
+ osPrintf("Problem with sending message in dmaSignalMicDeviceChange\n");
+ }
}
\ No newline at end of file
Index: sipXmediaLib/src/mp/MicThreadWnt.cpp
===================================================================
--- sipXmediaLib/src/mp/MicThreadWnt.cpp (revision 82)
+++ sipXmediaLib/src/mp/MicThreadWnt.cpp (working copy)
@@ -29,6 +29,7 @@
#include "mp/MpMediaTask.h"
#include "os/OsMsgPool.h"
#include "os/OsDefs.h"
+#include "os/OsIntPtrMsg.h"
#ifdef RTL_ENABLED
# include <rtl_macro.h>
@@ -57,8 +58,9 @@
#endif /* HISTORY ] */
static HWAVEIN audioInH;
static OsMsgPool* DmaMsgPool = NULL;
+OsMsgPool* gMicStatusPool = NULL;
+OsMsgQ* gMicStatusQueue = NULL;
-
/* ============================ FUNCTIONS ================================= */
@@ -71,15 +73,22 @@
}
#endif /* HISTORY ] */
- int retval = PostThreadMessage(dwInstance, wMsg, dwParam, GetTickCount());
+ OsIntPtrMsg *pMsg = (OsIntPtrMsg*)gMicStatusPool->findFreeMsg();
- if (retval == 0)
+ if (pMsg)
{
- Sleep(500);
- retval = PostThreadMessage(dwInstance, wMsg, dwParam, GetTickCount());
- if (retval == 0)
- osPrintf("Could not PostTheadMessage after two tries.\n");
+ // message was taken from pool
+ pMsg->setData1(wMsg);
+ pMsg->setData2(dwParam);
+ if (gMicStatusQueue->sendFromISR(*pMsg) != OS_SUCCESS)
+ {
+ osPrintf("Problem with sending message in micOutCallBackProc\n");
+ }
}
+ else
+ {
+ osPrintf("Could not create message in micOutCallBackProc\n");
+ }
}
/**
@@ -110,6 +119,25 @@
else return OS_UNSPECIFIED;
}
+// This function waits for given status message on mic device
+static void waitForMicStatusMessage(unsigned int message)
+{
+ UtlBoolean bSuccess = FALSE;
+ unsigned int micStatus = 0;
+ OsMsg *pMsg = NULL;
+ do
+ {
+ bSuccess = (gMicStatusQueue->receive(pMsg) == OS_SUCCESS);
+ if (bSuccess && pMsg)
+ {
+ OsIntPtrMsg *pIntMsg = (OsIntPtrMsg*)pMsg;
+ micStatus = (unsigned int)pIntMsg->getData1();
+ pIntMsg->releaseMsg();
+ pMsg = NULL;
+ }
+ } while (bSuccess && (micStatus != message));
+}
+
int openAudioIn(HWAVEIN *pAudioInH,
int nChannels, int nSamplesPerSec, int nBitsPerSample)
{
@@ -347,8 +375,6 @@
WAVEINCAPS devcaps;
DWORD bufLen = ((N_SAMPLES * BITS_PER_SAMPLE) / 8);
MMRESULT ret;
- MSG tMsg;
- BOOL bSuccess ;
gMicDeviceId = WAVE_MAPPER;
@@ -380,10 +406,7 @@
return 1;
}
- do
- {
- bSuccess = GetMessage(&tMsg, NULL, 0, 0) ;
- } while (bSuccess && (tMsg.message != WIM_OPEN)) ;
+ waitForMicStatusMessage(WIM_OPEN);
ret = waveInStart(audioInH);
if (ret != MMSYSERR_NOERROR)
@@ -420,13 +443,36 @@
return 0 ;
}
+static void waitForDeviceResetCompletion()
+{
+ int i;
+ bool bStillResetting;
+ int iterations = 0;
+ do
+ {
+ bStillResetting = false;
+
+ for (i = 0; i < N_OUT_BUFFERS; i++)
+ {
+ if (hInHdr[i] && (pInHdr[i]->dwFlags & WHDR_INQUEUE))
+ {
+ bStillResetting = true;
+ }
+ }
+
+ if (bStillResetting)
+ {
+ Sleep(10);
+ }
+ }
+ while (bStillResetting && ++iterations < 100);
+}
+
void closeMicDevice()
{
DWORD bufLen = ((N_SAMPLES * BITS_PER_SAMPLE) / 8);
MMRESULT ret;
- MSG tMsg;
- BOOL bSuccess ;
int i ;
// Cleanup
@@ -442,7 +488,7 @@
{
showWaveError("waveInStop", ret, -1, __LINE__);
}
- Sleep(500) ;
+ waitForDeviceResetCompletion();
for (i=0; i<N_IN_BUFFERS; i++)
{
@@ -456,7 +502,7 @@
inPostUnprep(i, TRUE, bufLen, TRUE);
}
}
- Sleep(500) ;
+ Sleep(50);
ret = waveInClose(audioInH);
if (ret != MMSYSERR_NOERROR)
@@ -464,10 +510,7 @@
showWaveError("waveInClose", ret, -1, __LINE__);
}
- do
- {
- bSuccess = GetMessage(&tMsg, NULL, 0, 0) ;
- } while (bSuccess && (tMsg.message != WIM_CLOSE)) ;
+ waitForMicStatusMessage(WIM_CLOSE);
audioInH = NULL;
}
@@ -480,7 +523,8 @@
WAVEHDR* pWH;
MMRESULT ret;
int recorded;
- MSG tMsg;
+ OsMsg *pMsg = NULL;
+ OsIntPtrMsg *pMicMsg = NULL;
BOOL bGotMsg ;
int n;
bool bDone ;
@@ -497,10 +541,11 @@
bRunning = true ;
}
- MpBufferMsg* pMsg = new MpBufferMsg(MpBufferMsg::AUD_RECORDED);
- DmaMsgPool = new OsMsgPool("DmaTask", (*(OsMsg*)pMsg),
- 40, 60, 100, 5,
- OsMsgPool::SINGLE_CLIENT);
+ MpBufferMsg *pBuffMsg = new MpBufferMsg(MpBufferMsg::AUD_RECORDED);
+ DmaMsgPool = new OsMsgPool("DmaTask", (*(OsMsg*)pBuffMsg),
+ 40, 60, 100, 5,
+ OsMsgPool::SINGLE_CLIENT);
+ delete pBuffMsg;
// Initialize Buffers
for (i=0; i<N_IN_BUFFERS; i++)
@@ -538,25 +583,33 @@
bDone = false ;
while (!bDone)
{
- bGotMsg = GetMessage(&tMsg, NULL, 0, 0);
- if (bGotMsg)
+ bGotMsg = (gMicStatusQueue->receive(pMsg) == OS_SUCCESS);
+
+ if (bGotMsg && pMsg)
{
- switch (tMsg.message)
+ pMicMsg = (OsIntPtrMsg*)pMsg;
+ intptr_t msgType = pMicMsg->getData1();
+ intptr_t data2 = pMicMsg->getData2();
+ pMicMsg->releaseMsg();
+ pMicMsg = NULL;
+ pMsg = NULL;
+
+ switch (msgType)
{
case WIM_DATA:
// Check if we got data - if not - then this signals a device
change
- if (!tMsg.wParam) {
+ if (!data2)
+ {
if (DmaTask::isInputDeviceChanged())
{
- DmaTask::clearInputDeviceChanged() ;
+ DmaTask::clearInputDeviceChanged();
- closeMicDevice() ;
- openMicDevice(bRunning, pWH) ;
-
+ closeMicDevice();
+ openMicDevice(bRunning, pWH);
}
break;
}
- pWH = (WAVEHDR *) tMsg.wParam;
+ pWH = (WAVEHDR *)data2;
n = (pWH->dwUser) & USER_BUFFER_MASK;
#ifdef IHISTORY /* [ */
@@ -634,9 +687,9 @@
closeMicDevice() ;
- bRunning = false ;
+ bRunning = false;
delete DmaMsgPool;
- delete pMsg;
+ DmaMsgPool = NULL;
return 0;
}
Index: sipXmediaLib/src/mp/SpeakerThreadWnt.cpp
===================================================================
--- sipXmediaLib/src/mp/SpeakerThreadWnt.cpp (revision 93)
+++ sipXmediaLib/src/mp/SpeakerThreadWnt.cpp (working copy)
@@ -28,6 +28,7 @@
#include "mp/MprToSpkr.h"
#include "mp/MpMediaTask.h"
#include "os/OsDefs.h"
+#include "os/OsIntPtrMsg.h"
#ifdef RTL_ENABLED
# include <rtl_macro.h>
@@ -58,6 +59,9 @@
static HGLOBAL hOutHdr[N_OUT_BUFFERS];
static WAVEHDR* pOutHdr[N_OUT_BUFFERS];
static HGLOBAL hOutBuf[N_OUT_BUFFERS];
+OsMsgPool* gSpeakerStatusPool = NULL;
+OsMsgQ* gSpeakerStatusQueue = NULL;
+
#ifdef OHISTORY /* [ */
static int histOut[OHISTORY];
static int lastOut;
@@ -91,15 +95,22 @@
}
static void CALLBACK TimerCallbackProc(UINT wTimerID, UINT msg, DWORD dwUser,
DWORD dw1, DWORD dw2)
-{
- int retval = PostThreadMessage(dwUser, WM_ALT_HEARTBEAT, 0,
GetTickCount());
- if (retval == 0)
- {
- Sleep(500);
- retval = PostThreadMessage(dwUser, WM_ALT_HEARTBEAT, 0,
GetTickCount());
- if (retval == 0)
- osPrintf("Could not PostTheadMessage after two tries.\n");
- }
+{
+ OsIntPtrMsg *pMsg = (OsIntPtrMsg*)gSpeakerStatusPool->findFreeMsg();
+
+ if (pMsg)
+ {
+ // message was taken from pool
+ pMsg->setData1(WM_ALT_HEARTBEAT);
+ if (gSpeakerStatusQueue->sendFromISR(*pMsg) != OS_SUCCESS)
+ {
+ osPrintf("Problem with sending message in TimerCallbackProc\n");
+ }
+ }
+ else
+ {
+ osPrintf("Could not create message in TimerCallbackProc\n");
+ }
}
// Call back for speaker audio
@@ -112,17 +123,42 @@
}
#endif /* OHISTORY ] */
- int retval = PostThreadMessage(dwInstance, wMsg, dwParam, GetTickCount());
+ OsIntPtrMsg *pMsg = (OsIntPtrMsg*)gSpeakerStatusPool->findFreeMsg();
- if (retval == 0)
+ if (pMsg)
{
- Sleep(500);
- retval = PostThreadMessage(dwInstance, wMsg, dwParam, GetTickCount());
- if (retval == 0)
- osPrintf("Could not PostTheadMessage after two tries.\n");
+ // message was taken from pool
+ pMsg->setData1(wMsg);
+ pMsg->setData2(dwParam);
+ if (gSpeakerStatusQueue->sendFromISR(*pMsg) != OS_SUCCESS)
+ {
+ osPrintf("Problem with sending message in speakerCallbackProc\n");
+ }
}
+ else
+ {
+ osPrintf("Could not create message in speakerCallbackProc\n");
+ }
}
+// This function waits for given message on speaker device
+static void waitForSpeakerStatusMessage(unsigned int message)
+{
+ UtlBoolean bSuccess = FALSE;
+ unsigned int speakerStatus = 0;
+ OsMsg *pMsg = NULL;
+ do
+ {
+ bSuccess = (gSpeakerStatusQueue->receive(pMsg) == OS_SUCCESS);
+ if (bSuccess && pMsg)
+ {
+ OsIntPtrMsg *pIntMsg = (OsIntPtrMsg*)pMsg;
+ speakerStatus = (unsigned int)pIntMsg->getData1();
+ pIntMsg->releaseMsg();
+ pMsg = NULL;
+ }
+ } while (bSuccess && (speakerStatus != message));
+}
// This function will attempt to open a user specified audio device.
// If it fails, we will try to open any audio device that meets our requested
format
@@ -320,8 +356,6 @@
DWORD bufLen = ((N_SAMPLES * BITS_PER_SAMPLE) / 8);
int i ;
MMRESULT ret;
- MSG tMsg;
- BOOL bSuccess ;
// set the different device ids
gRingDeviceId = WAVE_MAPPER;
@@ -368,12 +402,8 @@
return 1;
}
- do
- {
- bSuccess = GetMessage(&tMsg, NULL, 0, 0) ;
- } while (bSuccess && (tMsg.message != WOM_OPEN)) ;
+ waitForSpeakerStatusMessage(WOM_OPEN);
-
/*
* Open in-call device
*/
@@ -384,12 +414,8 @@
return 1;
}
- do
- {
- bSuccess = GetMessage(&tMsg, NULL, 0, 0) ;
- } while (bSuccess && tMsg.message != WOM_OPEN) ;
+ waitForSpeakerStatusMessage(WOM_OPEN);
-
// Pre load some data
for (i=0; i<smSpkrQPreload; i++)
{
@@ -421,7 +447,7 @@
// if waveOutReset was not called) we give up after 100 iterations
// (equals 1 second). if this happens then we could be left with some
// active data in the buffers.
-void waitForDeviceResetCompletion()
+static void waitForDeviceResetCompletion()
{
int i;
bool bStillResetting;
@@ -451,10 +477,7 @@
{
MMRESULT ret;
int i ;
- MSG tMsg;
- BOOL bSuccess ;
-
// Clean up ringer audio
if (audioOutH)
{
@@ -488,10 +511,7 @@
}
audioOutH = NULL;
- do
- {
- bSuccess = GetMessage(&tMsg, NULL, 0, 0) ;
- } while (bSuccess && (tMsg.message != WOM_CLOSE)) ;
+ waitForSpeakerStatusMessage(WOM_CLOSE);
}
// Clean up call audio
@@ -527,10 +547,7 @@
}
audioOutCallH = NULL;
- do
- {
- bSuccess = GetMessage(&tMsg, NULL, 0, 0) ;
- } while (bSuccess && (tMsg.message != WOM_CLOSE)) ;
+ waitForSpeakerStatusMessage(WOM_CLOSE);
}
}
@@ -541,7 +558,8 @@
WAVEHDR* pWH;
MMRESULT ret;
int played;
- MSG tMsg;
+ OsMsg *pMsg = NULL;
+ OsIntPtrMsg *pSpeakerMsg = NULL;
BOOL bGotMsg ;
int n;
bool bDone ;
@@ -597,7 +615,7 @@
bDone = false ;
while (!bDone)
{
- bGotMsg = GetMessage(&tMsg, NULL, 0, 0);
+ bGotMsg = (gSpeakerStatusQueue->receive(pMsg) == OS_SUCCESS);
// when switching devices, ringer to in-call we need to make
// sure any outstanding buffers are flushed
@@ -622,9 +640,16 @@
}
}
- if (bGotMsg)
+ if (bGotMsg && pMsg)
{
- switch (tMsg.message)
+ pSpeakerMsg = (OsIntPtrMsg*)pMsg;
+ intptr_t msgType = pSpeakerMsg->getData1();
+ intptr_t data2 = pSpeakerMsg->getData2();
+ pSpeakerMsg->releaseMsg();
+ pSpeakerMsg = NULL;
+ pMsg = NULL;
+
+ switch (msgType)
{
case WM_ALT_HEARTBEAT:
res = MpMediaTask::signalFrameStart();
@@ -694,7 +719,7 @@
}
break ;
case WOM_DONE:
- pWH = (WAVEHDR *) tMsg.wParam;
+ pWH = (WAVEHDR *) data2;
n = (pWH->dwUser) & USER_BUFFER_MASK;
#ifdef OHISTORY /* [ */
lastWH[last] = pWH;
Index: sipXportLib/include/os/OsIntPtrMsg.h
===================================================================
--- sipXportLib/include/os/OsIntPtrMsg.h (revision 0)
+++ sipXportLib/include/os/OsIntPtrMsg.h (revision 0)
@@ -0,0 +1,79 @@
+//
+// Copyright (C) 2004-2006 SIPfoundry Inc.
+// Licensed by SIPfoundry under the LGPL license.
+//
+// Copyright (C) 2004-2006 Pingtel Corp. All rights reserved.
+// Licensed to SIPfoundry under a Contributor Agreement.
+//
+// $$
+///////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef OsIntPtrMsg_h__
+#define OsIntPtrMsg_h__
+
+// SYSTEM INCLUDES
+// APPLICATION INCLUDES
+#include "os/OsDefs.h"
+#include "utl/UtlContainable.h"
+#include "os/OsMsg.h"
+
+
+// DEFINES
+// MACROS
+// EXTERNAL FUNCTIONS
+// EXTERNAL VARIABLES
+// CONSTANTS
+// STRUCTS
+// TYPEDEFS
+// FORWARD DECLARATIONS
+
+//:Base class for message queue buffers
+
+class OsIntPtrMsg : public OsMsg
+{
+ /* //////////////////////////// PUBLIC ////////////////////////////////////
*/
+public:
+ static const UtlContainableType TYPE ; /** < Class type used for runtime
checking */
+
+ /* ============================ CREATORS ==================================
*/
+
+ OsIntPtrMsg(const unsigned char msgType,
+ const unsigned char msgSubType,
+ intptr_t pData1 = 0,
+ intptr_t pData2 = 0);
+ //:Constructor
+
+ OsIntPtrMsg(const OsIntPtrMsg& rOsMsg);
+ //:Copy constructor
+
+ virtual OsMsg* createCopy(void) const;
+ //:Create a copy of this msg object (which may be of a derived type)
+
+ /* ============================ MANIPULATORS ==============================
*/
+
+ OsIntPtrMsg& operator=(const OsIntPtrMsg& rhs);
+ //:Assignment operator
+
+ /* ============================ ACCESSORS =================================
*/
+ intptr_t getData1() const { return mpData1; }
+ intptr_t getData2() const { return mpData2; }
+
+ void setData1(intptr_t val) { mpData1 = val; }
+ void setData2(intptr_t val) { mpData2 = val; }
+
+ /* ============================ INQUIRY ===================================
*/
+
+ /* //////////////////////////// PROTECTED /////////////////////////////////
*/
+protected:
+ intptr_t mpData1;
+ intptr_t mpData2;
+
+ /* //////////////////////////// PRIVATE ///////////////////////////////////
*/
+private:
+
+};
+
+/* ============================ INLINE METHODS ============================ */
+
+#endif // OsIntPtrMsg_h__
Index: sipXportLib/src/os/OsIntPtrMsg.cpp
===================================================================
--- sipXportLib/src/os/OsIntPtrMsg.cpp (revision 0)
+++ sipXportLib/src/os/OsIntPtrMsg.cpp (revision 0)
@@ -0,0 +1,82 @@
+//
+// Copyright (C) 2004-2006 SIPfoundry Inc.
+// Licensed by SIPfoundry under the LGPL license.
+//
+// Copyright (C) 2004-2006 Pingtel Corp. All rights reserved.
+// Licensed to SIPfoundry under a Contributor Agreement.
+//
+// $$
+///////////////////////////////////////////////////////////////////////////////
+
+// SYSTEM INCLUDES
+#include <assert.h>
+
+// APPLICATION INCLUDES
+#include "os/OsIntPtrMsg.h"
+
+// EXTERNAL FUNCTIONS
+// EXTERNAL VARIABLES
+// CONSTANTS
+const UtlContainableType OsIntPtrMsg::TYPE = "OsIntPtrMsg" ;
+
+// STATIC VARIABLE INITIALIZATIONS
+
+/* //////////////////////////// PUBLIC //////////////////////////////////// */
+
+/* ============================ CREATORS ================================== */
+
+// Constructor
+OsIntPtrMsg::OsIntPtrMsg(const unsigned char msgType,
+ const unsigned char msgSubType,
+ intptr_t pData1,
+ intptr_t pData2)
+ : OsMsg(msgType, msgSubType),
+ mpData1(pData1),
+ mpData2(pData2)
+{
+ // all of the required work is done by the initializers
+}
+
+// Copy constructor
+OsIntPtrMsg::OsIntPtrMsg(const OsIntPtrMsg& rOsMsg) :
+ OsMsg(rOsMsg),
+ mpData1(rOsMsg.mpData1),
+ mpData2(rOsMsg.mpData2)
+{
+}
+
+// Create a copy of this msg object (which may be of a derived type)
+OsMsg* OsIntPtrMsg::createCopy(void) const
+{
+ return new OsIntPtrMsg(*this);
+}
+
+
+/* ============================ MANIPULATORS ============================== */
+
+// Assignment operator
+OsIntPtrMsg& OsIntPtrMsg::operator=(const OsIntPtrMsg& rhs)
+{
+ if (this != &rhs) // handle the assignment to self case
+ {
+ OsMsg::operator=(rhs);
+ mpData1 = rhs.mpData1;
+ mpData2 = rhs.mpData2;
+ }
+
+ return *this;
+}
+
+
+/* ============================ ACCESSORS ================================= */
+
+/* ============================ INQUIRY =================================== */
+
+/* //////////////////////////// PROTECTED ///////////////////////////////// */
+
+/* //////////////////////////// PRIVATE /////////////////////////////////// */
+
+
+/* ============================ FUNCTIONS ================================= */
+
+
_______________________________________________
sipxtapi-dev mailing list
[email protected]
List Archive: http://list.sipfoundry.org/archive/sipxtapi-dev/