Leaked source code of windows server 2003
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.

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