asyncio.h
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:7k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. //------------------------------------------------------------------------------
  2. // File: AsyncIo.h
  3. //
  4. // Desc: DirectShow sample code - base library for I/O functionality.
  5. //
  6. // Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
  7. //------------------------------------------------------------------------------
  8. #pragma once
  9. //
  10. // definition of CAsyncFile object that performs file access. It provides
  11. // asynchronous, unbuffered, aligned reads from a file, using a worker thread
  12. // on win95 and potentially overlapped i/o if available.
  13. // !!! Need to use real overlapped i/o if available
  14. // currently only uses worker thread, not overlapped i/o
  15. class CAsyncIo;
  16. class CAsyncStream;
  17. //
  18. //  Model the stream we read from based on a file-like interface
  19. //
  20. class CAsyncStream
  21. {
  22. public:
  23.     virtual ~CAsyncStream() {};
  24.     virtual HRESULT SetPointer(LONGLONG llPos) = 0;
  25.     virtual HRESULT Read(PBYTE pbBuffer,
  26.                          DWORD dwBytesToRead,
  27.                          BOOL bAlign,
  28.                          LPDWORD pdwBytesRead) = 0;
  29.     virtual LONGLONG Size(LONGLONG *pSizeAvailable = NULL) = 0;
  30.     virtual DWORD Alignment() = 0;
  31.     virtual void Lock() = 0;
  32.     virtual void Unlock() = 0;
  33.     //virtual void SetStopHandle(HANDLE hevStop) {}
  34. };
  35. // represents a single request and performs the i/o. Can be called on either
  36. // worker thread or app thread, but must hold pcsFile across file accesses.
  37. // (ie across SetFilePointer/ReadFile pairs)
  38. class CAsyncRequest
  39. {
  40.     CAsyncIo *m_pIo;
  41.     CAsyncStream *m_pStream;
  42.     LONGLONG      m_llPos;
  43.     BOOL        m_bAligned;
  44.     LONG  m_lLength;
  45.     BYTE*  m_pBuffer;
  46.     LPVOID  m_pContext;
  47.     DWORD m_dwUser;
  48.     HRESULT     m_hr;
  49. public:
  50.     // init the params for this request. Issue the i/o
  51.     // if overlapped i/o is possible.
  52.     HRESULT Request(
  53.      CAsyncIo *pIo,
  54.         CAsyncStream *pStream,
  55.      LONGLONG llPos,
  56. LONG lLength,
  57.         BOOL bAligned,
  58. BYTE* pBuffer,
  59. LPVOID pContext, // filter's context
  60. DWORD dwUser); // downstream filter's context
  61.     // issue the i/o if not overlapped, and block until i/o complete.
  62.     // returns error code of file i/o
  63.     HRESULT Complete();
  64.     // cancels the i/o. blocks until i/o is no longer pending
  65.     HRESULT Cancel()
  66.     {
  67. return S_OK;
  68.     };
  69.     // accessor functions
  70.     LPVOID GetContext()
  71.     {
  72.      return m_pContext;
  73.     };
  74.     DWORD GetUser()
  75.     {
  76. return m_dwUser;
  77.     };
  78.     HRESULT GetHResult() {
  79.         return m_hr;
  80.     };
  81.     // we set m_lLength to the actual length
  82.     LONG GetActualLength() {
  83.         return m_lLength;
  84.     };
  85.     LONGLONG GetStart() {
  86.         return m_llPos;
  87.     };
  88. };
  89. typedef CGenericList<CAsyncRequest> CRequestList;
  90. // this class needs a worker thread, but the ones defined in classesbase
  91. // are not suitable (they assume you have one message sent or posted per
  92. // request, whereas here for efficiency we want just to set an event when
  93. // there is work on the queue).
  94. //
  95. // we create CAsyncRequest objects and queue them on m_listWork. The worker
  96. // thread pulls them off, completes them and puts them on m_listDone.
  97. // The events m_evWork and m_evDone are set when the corresponding lists are
  98. // not empty.
  99. //
  100. // Synchronous requests are done on the caller thread. These should be
  101. // synchronised by the caller, but to make sure we hold m_csFile across
  102. // the SetFilePointer/ReadFile code.
  103. //
  104. // Flush by calling BeginFlush. This rejects all further requests (by
  105. // setting m_bFlushing within m_csLists), cancels all requests and moves them
  106. // to the done list, and sets m_evDone to ensure that no WaitForNext operations
  107. // will block. Call EndFlush to cancel this state.
  108. //
  109. // we support unaligned calls to SyncRead. This is done by opening the file
  110. // twice if we are using unbuffered i/o (m_dwAlign > 1).
  111. // !!!fix this to buffer on top of existing file handle?
  112. class CAsyncIo
  113. {
  114.     CCritSec m_csReader;
  115.     CAsyncStream *m_pStream;
  116.     CCritSec m_csLists;      // locks access to the list and events
  117.     BOOL m_bFlushing;        // true if between BeginFlush/EndFlush
  118.     CRequestList m_listWork;
  119.     CRequestList m_listDone;
  120.     CAMEvent m_evWork;         // set when list is not empty
  121.     CAMEvent m_evDone;
  122.     // for correct flush behaviour: all protected by m_csLists
  123.     LONG    m_cItemsOut;    // nr of items not on listDone or listWork
  124.     BOOL    m_bWaiting;     // TRUE if someone waiting for m_evAllDone
  125.     CAMEvent m_evAllDone;   // signal when m_cItemsOut goes to 0 if m_cWaiting
  126.     CAMEvent m_evStop;         // set when thread should exit
  127.     HANDLE m_hThread;
  128.     LONGLONG Size() {
  129.         ASSERT(m_pStream != NULL);
  130.         return m_pStream->Size();
  131.     };
  132.     // start the thread
  133.     HRESULT StartThread(void);
  134.     // stop the thread and close the handle
  135.     HRESULT CloseThread(void);
  136.     // manage the list of requests. hold m_csLists and ensure
  137.     // that the (manual reset) event hevList is set when things on
  138.     // the list but reset when the list is empty.
  139.     // returns null if list empty
  140.     CAsyncRequest* GetWorkItem();
  141.     // get an item from the done list
  142.     CAsyncRequest* GetDoneItem();
  143.     // put an item on the work list
  144.     HRESULT PutWorkItem(CAsyncRequest* pRequest);
  145.     // put an item on the done list
  146.     HRESULT PutDoneItem(CAsyncRequest* pRequest);
  147.     // called on thread to process any active requests
  148.     void ProcessRequests(void);
  149.     // initial static thread proc calls ThreadProc with DWORD
  150.     // param as this
  151.     static DWORD WINAPI InitialThreadProc(LPVOID pv) {
  152. CAsyncIo * pThis = (CAsyncIo*) pv;
  153. return pThis->ThreadProc();
  154.     };
  155.     DWORD ThreadProc(void);
  156. public:
  157.     CAsyncIo(CAsyncStream *pStream);
  158.     ~CAsyncIo();
  159.     // open the file
  160.     HRESULT Open(LPCTSTR pName);
  161.     // ready for async activity - call this before
  162.     // calling Request
  163.     HRESULT AsyncActive(void);
  164.     // call this when no more async activity will happen before
  165.     // the next AsyncActive call
  166.     HRESULT AsyncInactive(void);
  167.     // queue a requested read. must be aligned.
  168.     HRESULT Request(
  169.      LONGLONG llPos,
  170. LONG lLength,
  171.                 BOOL bAligned,
  172. BYTE* pBuffer,
  173. LPVOID pContext,
  174. DWORD dwUser);
  175.     // wait for the next read to complete
  176.     HRESULT WaitForNext(
  177.      DWORD dwTimeout,
  178. LPVOID *ppContext,
  179. DWORD * pdwUser,
  180.                 LONG * pcbActual
  181.                 );
  182.     // perform a read of an already aligned buffer
  183.     HRESULT SyncReadAligned(
  184.      LONGLONG llPos,
  185. LONG lLength,
  186. BYTE* pBuffer,
  187.                 LONG* pcbActual,
  188.                 PVOID pvContext
  189.                 );
  190.     // perform a synchronous read. will be buffered
  191.     // if not aligned.
  192.     HRESULT SyncRead(
  193.                 LONGLONG llPos,
  194.                 LONG lLength,
  195.                 BYTE* pBuffer);
  196.     // return length
  197.     HRESULT Length(LONGLONG *pllTotal, LONGLONG* pllAvailable);
  198.     // all Reader positions, read lengths and memory locations must
  199.     // be aligned to this.
  200.     HRESULT Alignment(LONG* pl);
  201.     HRESULT BeginFlush();
  202.     HRESULT EndFlush();
  203.     LONG Alignment()
  204.     {
  205.         return m_pStream->Alignment();
  206.     };
  207.     BOOL IsAligned(LONG l) {
  208. if ((l & (Alignment() -1)) == 0) {
  209.     return TRUE;
  210. } else {
  211.     return FALSE;
  212. }
  213.     };
  214.     BOOL IsAligned(LONGLONG ll) {
  215. return IsAligned( (LONG) (ll & 0xffffffff));
  216.     };
  217.     //  Accessor
  218.     HANDLE StopEvent() const { return m_evDone; }
  219. };