ASYNCIO.H
上传用户:hxb_1234
上传日期:2010-03-30
资源大小:8328k
文件大小:8k
源码类别:

VC书籍

开发平台:

Visual C++

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