00001
00002
00003
00004
00005 #ifndef __ASYNCIO_H__
00006 #define __ASYNCIO_H__
00007
00008 class CAsyncIo;
00009 class CAsyncStream;
00010
00011 class CAsyncStream
00012 {
00013 public:
00014 virtual ~CAsyncStream() {};
00015 virtual HRESULT SetPointer(LONGLONG llPos) = 0;
00016 virtual HRESULT Read(PBYTE pbBuffer,
00017 DWORD dwBytesToRead,
00018 BOOL bAlign,
00019 LPDWORD pdwBytesRead) = 0;
00020 virtual HRESULT Size(LONGLONG* pllSizeTotal, LONGLONG *pSizeAvailable) = 0;
00021 virtual DWORD Alignment() = 0;
00022 virtual void Lock() = 0;
00023 virtual void Unlock() = 0;
00024
00025 };
00026
00027 class CAsyncRequest
00028 {
00029 CAsyncIo *m_pIo;
00030 CAsyncStream *m_pStream;
00031 LONGLONG m_llPos;
00032 BOOL m_bAligned;
00033 LONG m_lLength;
00034 BYTE* m_pBuffer;
00035 LPVOID m_pContext;
00036 DWORD m_dwUser;
00037 HRESULT m_hr;
00038
00039 public:
00040
00041
00042 HRESULT Request(
00043 CAsyncIo *pIo,
00044 CAsyncStream *pStream,
00045 LONGLONG llPos,
00046 LONG lLength,
00047 BOOL bAligned,
00048 BYTE* pBuffer,
00049 LPVOID pContext,
00050 DWORD dwUser);
00051
00052
00053
00054 HRESULT Complete();
00055
00056
00057 HRESULT Cancel()
00058 {
00059 return S_OK;
00060 };
00061
00062
00063 LPVOID GetContext()
00064 {
00065 return m_pContext;
00066 };
00067
00068 DWORD GetUser()
00069 {
00070 return m_dwUser;
00071 };
00072
00073 HRESULT GetHResult() {
00074 return m_hr;
00075 };
00076
00077
00078 LONG GetActualLength() {
00079 return m_lLength;
00080 };
00081
00082 LONGLONG GetStart() {
00083 return m_llPos;
00084 };
00085 };
00086
00087 typedef CGenericList<CAsyncRequest> CRequestList;
00088
00089 class CAsyncIo
00090 {
00091
00092 CCritSec m_csReader;
00093 CAsyncStream *m_pStream;
00094
00095 CCritSec m_csLists;
00096 BOOL m_bFlushing;
00097 CRequestList m_listWork;
00098 CRequestList m_listDone;
00099 CAMEvent m_evWork;
00100 CAMEvent m_evDone;
00101
00102
00103 LONG m_cItemsOut;
00104 BOOL m_bWaiting;
00105 CAMEvent m_evAllDone;
00106
00107 CAMEvent m_evStop;
00108 HANDLE m_hThread;
00109
00110 LONGLONG Size() {
00111 ASSERT(m_pStream != NULL);
00112 LONGLONG llTotal;
00113 m_pStream->Size(&llTotal, NULL);
00114 return llTotal;
00115 };
00116
00117
00118 HRESULT StartThread(void);
00119
00120
00121 HRESULT CloseThread(void);
00122
00123
00124
00125
00126
00127 CAsyncRequest* GetWorkItem();
00128
00129
00130 CAsyncRequest* GetDoneItem();
00131
00132
00133 HRESULT PutWorkItem(CAsyncRequest* pRequest);
00134
00135
00136 HRESULT PutDoneItem(CAsyncRequest* pRequest);
00137
00138
00139 void ProcessRequests(void);
00140
00141
00142
00143 static DWORD WINAPI InitialThreadProc(LPVOID pv) {
00144 CAsyncIo * pThis = (CAsyncIo*) pv;
00145 return pThis->ThreadProc();
00146 };
00147
00148 DWORD ThreadProc(void);
00149
00150 public:
00151
00152 CAsyncIo(CAsyncStream *pStream);
00153 ~CAsyncIo();
00154
00155
00156 HRESULT Open(LPCTSTR pName);
00157
00158
00159
00160 HRESULT AsyncActive(void);
00161
00162
00163
00164 HRESULT AsyncInactive(void);
00165
00166
00167 HRESULT Request(
00168 LONGLONG llPos,
00169 LONG lLength,
00170 BOOL bAligned,
00171 BYTE* pBuffer,
00172 LPVOID pContext,
00173 DWORD dwUser);
00174
00175
00176 HRESULT WaitForNext(
00177 DWORD dwTimeout,
00178 LPVOID *ppContext,
00179 DWORD * pdwUser,
00180 LONG * pcbActual
00181 );
00182
00183
00184 HRESULT SyncReadAligned(
00185 LONGLONG llPos,
00186 LONG lLength,
00187 BYTE* pBuffer,
00188 LONG* pcbActual,
00189 PVOID pvContext
00190 );
00191
00192
00193
00194 HRESULT SyncRead(
00195 LONGLONG llPos,
00196 LONG lLength,
00197 BYTE* pBuffer);
00198
00199
00200 HRESULT Length(LONGLONG *pllTotal, LONGLONG* pllAvailable);
00201
00202
00203
00204 HRESULT Alignment(LONG* pl);
00205
00206 HRESULT BeginFlush();
00207 HRESULT EndFlush();
00208
00209 LONG Alignment()
00210 {
00211 return m_pStream->Alignment();
00212 };
00213
00214 BOOL IsAligned(LONG l) {
00215 if ((l & (Alignment() -1)) == 0) {
00216 return TRUE;
00217 } else {
00218 return FALSE;
00219 }
00220 };
00221
00222 BOOL IsAligned(LONGLONG ll) {
00223 return IsAligned( (LONG) (ll & 0xffffffff));
00224 };
00225
00226
00227 HANDLE StopEvent() const { return m_evDone; }
00228 };
00229
00230 #endif