Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

337 lines
7.9 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: wirecd.cpp
  6. * Content:
  7. *
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 07/16/99 pnewson Created
  12. * 08/03/99 pnewson General clean up, updated target to DVID
  13. * 01/14/2000 rodtoll Updated to support multiple targets. Frame will
  14. * automatically allocate memory as needed for targets.
  15. * rodtoll Added SetEqual function to making copying of frame
  16. * in Queue easier.
  17. * rodtoll Added support for "user controlled memory" frames.
  18. * When the default constructor is used with the UserOwn_XXXX
  19. * functions the frames use user specified buffers.
  20. * (Removes a buffer copy when queueing data).
  21. * 01/31/2000 pnewson replace SAssert with DNASSERT
  22. * 02/17/2000 rodtoll Updated so sequence/msg numbers are copied when you SetEqual
  23. * 07/09/2000 rodtoll Added signature bytes
  24. *
  25. ***************************************************************************/
  26. #include "dxvutilspch.h"
  27. #undef DPF_SUBCOMP
  28. #define DPF_SUBCOMP DN_SUBCOMP_VOICE
  29. #define MODULE_ID FRAME
  30. // SetEqual
  31. //
  32. // This function sets the current frame to match the data in frSourceFrame
  33. //
  34. #undef DPF_MODNAME
  35. #define DPF_MODNAME "CFrame::SetEqual"
  36. HRESULT CFrame::SetEqual( const CFrame &frSourceFrame )
  37. {
  38. HRESULT hr;
  39. SetClientId( frSourceFrame.GetClientId());
  40. SetSeqNum(frSourceFrame.GetSeqNum());
  41. SetMsgNum(frSourceFrame.GetMsgNum());
  42. CopyData(frSourceFrame);
  43. SetIsSilence(frSourceFrame.GetIsSilence());
  44. hr = SetTargets( frSourceFrame.GetTargetList(), frSourceFrame.GetNumTargets() );
  45. if( FAILED( hr ) )
  46. {
  47. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error copying frame for queue" );
  48. }
  49. return hr;
  50. }
  51. // GetTargets
  52. //
  53. // This program gets the targets for this frame
  54. #undef DPF_MODNAME
  55. #define DPF_MODNAME "CFrame::GetTargets"
  56. HRESULT CFrame::GetTargets( PDVID pdvidTargets, PDWORD pdwNumTargets ) const
  57. {
  58. DNASSERT( pdwNumTargets != NULL );
  59. if( pdwNumTargets != NULL )
  60. {
  61. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid param" );
  62. return DVERR_INVALIDPARAM;
  63. }
  64. if( *pdwNumTargets < m_dwNumTargets || pdvidTargets == NULL )
  65. {
  66. *pdwNumTargets = m_dwNumTargets;
  67. return DVERR_BUFFERTOOSMALL;
  68. }
  69. *pdwNumTargets = m_dwNumTargets;
  70. memcpy( pdvidTargets, m_pdvidTargets, sizeof(DVID)*m_dwNumTargets );
  71. return DV_OK;
  72. }
  73. // SetTargets
  74. //
  75. // This program sets the targets for this frame. It will expand the
  76. // target list (if required) or use a subset of the current buffer.
  77. //
  78. #undef DPF_MODNAME
  79. #define DPF_MODNAME "CFrame::SetTargets"
  80. HRESULT CFrame::SetTargets( PDVID pdvidTargets, DWORD dwNumTargets )
  81. {
  82. DNASSERT( m_fOwned );
  83. if( dwNumTargets > m_dwMaxTargets )
  84. {
  85. if( m_pdvidTargets != NULL )
  86. {
  87. delete [] m_pdvidTargets;
  88. }
  89. m_pdvidTargets = new DVID[dwNumTargets];
  90. if( m_pdvidTargets == NULL )
  91. {
  92. DPFX(DPFPREP, DVF_ERRORLEVEL, "Memory allocation failure" );
  93. return DVERR_OUTOFMEMORY;
  94. }
  95. m_dwMaxTargets = dwNumTargets;
  96. }
  97. m_dwNumTargets = dwNumTargets;
  98. memcpy( m_pdvidTargets, pdvidTargets, sizeof(DVID)*dwNumTargets );
  99. return DV_OK;
  100. }
  101. // This function is called to return a frame to the frame
  102. // pool that is managing it. If a primary pointer was
  103. // provided, it will be set to NULL.
  104. #undef DPF_MODNAME
  105. #define DPF_MODNAME "CFrame::Return"
  106. void CFrame::Return()
  107. {
  108. // the CInputQueue2 or CInnerQueue class is supposed to give us
  109. // the critical section object. If it does not, these functions
  110. // should not be called.
  111. DNASSERT(m_pCriticalSection != NULL);
  112. BFCSingleLock csl(m_pCriticalSection);
  113. csl.Lock();
  114. // this frame is supposed to be part of a frame pool if
  115. // this function is called
  116. DNASSERT(m_pFramePool != NULL);
  117. // return the frame to the pool, and set the primary
  118. // frame pointer to null to signal to the caller that
  119. // this frame is now gone. Note that this pointer update
  120. // is done within the critical section passed to this
  121. // class, and so the caller should also use this
  122. // critical section to check the pointer value. This
  123. // is true for CInputQueue, which uses the critical
  124. // section for Reset, Enqueue and Dequeue.
  125. m_pFramePool->Return(this);
  126. if (m_ppfrPrimary != NULL)
  127. {
  128. *m_ppfrPrimary = NULL;
  129. }
  130. }
  131. // CFrame Constructor
  132. //
  133. // This is the primary constructor which is used for creating frames
  134. // that are used by the frame pool.
  135. //
  136. // If you want to create a non-pooled frame then use the default constructor
  137. //
  138. #undef DPF_MODNAME
  139. #define DPF_MODNAME "CFrame::CFrame"
  140. CFrame::CFrame(WORD wFrameSize,
  141. WORD wClientNum,
  142. BYTE wSeqNum,
  143. BYTE bMsgNum,
  144. BYTE bIsSilence,
  145. CFramePool* pFramePool,
  146. DNCRITICAL_SECTION* pCriticalSection,
  147. CFrame** ppfrPrimary)
  148. : m_dwSignature(VSIG_FRAME),
  149. m_wFrameSize(wFrameSize),
  150. m_wClientId(wClientNum),
  151. m_wSeqNum(wSeqNum),
  152. m_bMsgNum(bMsgNum),
  153. m_bIsSilence(bIsSilence),
  154. m_wFrameLength(wFrameSize),
  155. m_pFramePool(pFramePool),
  156. m_pCriticalSection(pCriticalSection),
  157. m_ppfrPrimary(ppfrPrimary),
  158. m_fIsLost(false),
  159. m_pdvidTargets(NULL),
  160. m_dwNumTargets(0),
  161. m_dwMaxTargets(0),
  162. m_fOwned(true)
  163. {
  164. m_pbData = new BYTE[m_wFrameSize];
  165. }
  166. // CFrame Constructor
  167. //
  168. // This is the constructor to use when creating a standalone frame. This
  169. // type of frame can take an external buffer to eliminate a buffer copy.
  170. //
  171. // The frame doesn't "own" the buffer memory so it doesn't attempt to
  172. // free it.
  173. //
  174. // To set the data for the frame use the UserOwn_SetData member.
  175. //
  176. // Target information can be handled the same way by using UserOwn_SetTargets
  177. //
  178. #undef DPF_MODNAME
  179. #define DPF_MODNAME "CFrame::CFrame"
  180. CFrame::CFrame(
  181. ): m_dwSignature(VSIG_FRAME),
  182. m_wFrameSize(0),
  183. m_wClientId(0),
  184. m_wSeqNum(0),
  185. m_bMsgNum(0),
  186. m_bIsSilence(true),
  187. m_wFrameLength(0),
  188. m_pFramePool(NULL),
  189. m_pCriticalSection(NULL),
  190. m_ppfrPrimary(NULL),
  191. m_fIsLost(false),
  192. m_pdvidTargets(NULL),
  193. m_dwNumTargets(0),
  194. m_dwMaxTargets(0),
  195. m_fOwned(false)
  196. {
  197. }
  198. #undef DPF_MODNAME
  199. #define DPF_MODNAME "CFrame::~CFrame"
  200. CFrame::~CFrame()
  201. {
  202. if( m_fOwned )
  203. {
  204. delete [] m_pbData;
  205. if( m_pdvidTargets != NULL )
  206. {
  207. delete [] m_pdvidTargets;
  208. }
  209. }
  210. m_dwSignature = VSIG_FRAME_FREE;
  211. }
  212. #undef DPF_MODNAME
  213. #define DPF_MODNAME "CFrame::CopyData"
  214. void CFrame::CopyData(const BYTE* pbData, WORD wFrameLength)
  215. {
  216. DNASSERT(pbData != 0);
  217. memcpy(m_pbData, pbData, wFrameLength);
  218. m_wFrameLength = wFrameLength;
  219. }
  220. #undef DPF_MODNAME
  221. #define DPF_MODNAME "CFramePool::CFramePool"
  222. CFramePool::CFramePool(WORD wFrameSize)
  223. : m_wFrameSize(wFrameSize), m_fCritSecInited(FALSE)
  224. {
  225. // Push a couple of frames into the pool to start with
  226. for (int i = 0; i < 2; ++i)
  227. {
  228. m_vpfrPool.push_back(new CFrame(m_wFrameSize));
  229. }
  230. return;
  231. }
  232. #undef DPF_MODNAME
  233. #define DPF_MODNAME "CFramePool::~CFramePool"
  234. CFramePool::~CFramePool()
  235. {
  236. for (std::vector<CFrame *>::iterator iter1 = m_vpfrPool.begin(); iter1 < m_vpfrPool.end(); ++iter1)
  237. {
  238. delete *iter1;
  239. }
  240. if (m_fCritSecInited)
  241. {
  242. DNDeleteCriticalSection(&m_lock);
  243. }
  244. }
  245. #undef DPF_MODNAME
  246. #define DPF_MODNAME "CFramePool::Get"
  247. CFrame* CFramePool::Get(DNCRITICAL_SECTION* pCriticalSection, CFrame** ppfrPrimary)
  248. {
  249. BFCSingleLock csl(&m_lock);
  250. csl.Lock();
  251. CFrame* pfr;
  252. if (m_vpfrPool.empty())
  253. {
  254. // the pool is empty, return a new frame
  255. pfr = new CFrame(m_wFrameSize);
  256. if( pfr == NULL )
  257. {
  258. DPFX(DPFPREP, 0, "Error allocating memory" );
  259. return NULL;
  260. }
  261. }
  262. else
  263. {
  264. // there are some frames in the pool, pop
  265. // the last one off the back of the vector
  266. pfr = m_vpfrPool.back();
  267. m_vpfrPool.pop_back();
  268. }
  269. pfr->SetCriticalSection(pCriticalSection);
  270. pfr->SetPrimaryPointer(ppfrPrimary);
  271. pfr->SetFramePool(this);
  272. // clear up the rest of the flags, but don't bother messing
  273. // with the data.
  274. pfr->SetIsLost(false);
  275. pfr->SetMsgNum(0);
  276. pfr->SetSeqNum(0);
  277. pfr->SetIsSilence(FALSE);
  278. return pfr;
  279. }
  280. #undef DPF_MODNAME
  281. #define DPF_MODNAME "CFramePool::Return"
  282. void CFramePool::Return(CFrame* pFrame)
  283. {
  284. BFCSingleLock csl(&m_lock);
  285. csl.Lock();
  286. // drop this frame on the back for reuse
  287. m_vpfrPool.push_back(pFrame);
  288. }