Windows NT 4.0 source code leak
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.

250 lines
5.8 KiB

4 years ago
  1. // IOQueue.h -- Definition of class CIOQueue
  2. #ifndef _IOQUEUE_H__
  3. #define _IOQUEUE_H__
  4. #include "DataRing.h"
  5. #include "UnbuffIO.h"
  6. #ifdef _DEBUG
  7. #define FOREVER 5000
  8. #else
  9. #define FOREVER INFINITE
  10. #endif // _DEBUG
  11. class CIOQueue;
  12. typedef enum _IOState { Unused, Emptied, Active, Transputting, IOCompleted,
  13. Pending, EndOfFile, IOError
  14. } IOState;
  15. typedef struct _IOControl
  16. {
  17. PUINT pdwIOBlock;
  18. IOState ioState;
  19. UINT ibFileLow;
  20. UINT ibFileHigh;
  21. BOOL fWriting;
  22. UINT cdwTransfer;
  23. CIOQueue *pioq;
  24. UINT dwLastError;
  25. struct _IOControl *piocPendingLink;
  26. } IOControl;
  27. typedef IOControl *PIOControl;
  28. class CIOQueue : public CDataRing
  29. {
  30. friend void BlockIOCompletion(PVOID pvEnvironment, PVOID pvTransaction,
  31. UINT uiCompletionCode, UINT cbTransferred
  32. );
  33. public:
  34. enum { C_BLOCKS= 5 };
  35. // Destructor --
  36. virtual ~CIOQueue();
  37. // Queries --
  38. UINT CbBlockSize();
  39. UINT CBufferBlocks();
  40. protected:
  41. // Constructor --
  42. CIOQueue();
  43. // Initialing --
  44. BOOL InitialIOQueue(CUnbufferedIO *puio);
  45. // Gating I/O --
  46. void EnableStream(BOOL fWritable);
  47. // Queries --
  48. BOOL Attached();
  49. private:
  50. enum { CB_BLOCKS = 0x10000,
  51. MAX_ACTIVE_IOS = 8,
  52. WAIT_TIMER_MS = 5000
  53. };
  54. #ifdef _DEBUG
  55. BOOL m_fInCriticalSection;
  56. #endif // _DEBUG
  57. CUnbufferedIO *m_puio;
  58. UINT m_cbBlock;
  59. UINT m_cdwBlock;
  60. IOControl m_aioc[C_BLOCKS];
  61. BOOL m_fAwaitingIO;
  62. HANDLE m_hevAwaitingIO;
  63. UINT m_cdwRingBuffer;
  64. PUINT m_pdwRingBuffer;
  65. PUINT m_pdwBufferLimit;
  66. PUINT m_pdwRingNext; // Note that full and empty
  67. PUINT m_pdwRingLimit; // situations can be identical!!
  68. UINT m_cdwReserved;
  69. UINT m_cdwInTransit;
  70. BOOL m_fUsed; // This flag resolves full/empty confusions.
  71. BOOL m_fAttached;
  72. BOOL m_fEOF;
  73. BOOL m_fIOError;
  74. // CDataRing Virtual Interfaces --
  75. const UINT *RawNextDWordsIn (PUINT pcdw);
  76. PUINT RawNextDWordsOut(PUINT pcdw);
  77. void RawFlushOutput(BOOL fForceAll);
  78. BOOL RawEmptyRing();
  79. // Ring management --
  80. void ReloadRing();
  81. UINT CdwBuffered();
  82. UINT CdwAvailable();
  83. UINT CdwAvailableForReading();
  84. UINT CdwAvailableForWriting();
  85. // Transaction management --
  86. void BeginCritical();
  87. void EndCritical();
  88. #ifdef _DEBUG
  89. BOOL InCritical();
  90. #endif // _DEBUG
  91. // Transaction Control --
  92. IOState StartBlockIO(PIOControl pioc, BOOL fFront= FALSE);
  93. IOState DeferBlockIO(PIOControl pioc, BOOL fFront= FALSE);
  94. void FinishBlockIO(PIOControl pioc, UINT uiCompletionCode,
  95. UINT cbTransferred
  96. );
  97. void AwaitQuiescence();
  98. void MarkCompleted(PIOControl pioc);
  99. void DiscardPendingIOs();
  100. void StartPendingIOs();
  101. // Message Box Interface
  102. BOOL AskForDiskSpace();
  103. // Virtual routines to be defined by subclasses
  104. virtual BOOL NextFileAddress(PUINT pibFileLow, PUINT pibFileHigh, PUINT pcdw)= 0;
  105. virtual void ReleaseFileBlock(UINT ibFileLow, UINT ibFileHigh)= 0;
  106. };
  107. typedef CIOQueue *PCIOQueue;
  108. extern CRITICAL_SECTION csBlockIOControl;
  109. inline void CIOQueue::BeginCritical()
  110. {
  111. ASSERT(m_hevAwaitingIO);
  112. EnterCriticalSection(&csBlockIOControl);
  113. #ifdef _DEBUG
  114. m_fInCriticalSection= TRUE;
  115. #endif // _DEBUG
  116. }
  117. inline void CIOQueue::EndCritical()
  118. {
  119. ASSERT(InCritical());
  120. LeaveCriticalSection(&csBlockIOControl);
  121. #ifdef _DEBUG
  122. m_fInCriticalSection= FALSE;
  123. #endif // _DEBUG
  124. }
  125. #ifdef _DEBUG
  126. inline BOOL CIOQueue::InCritical()
  127. {
  128. return m_fInCriticalSection;
  129. }
  130. #endif // _DEBUG
  131. inline UINT CIOQueue::CbBlockSize() { return m_cbBlock; }
  132. inline UINT CIOQueue::CBufferBlocks() { return C_BLOCKS; }
  133. inline BOOL CIOQueue::Attached() { return m_fAttached; }
  134. inline UINT CIOQueue::CdwBuffered()
  135. {
  136. ASSERT(Initialed());
  137. ASSERT(Attached());
  138. // Ring pointers use modulo increments:
  139. ASSERT(m_pdwRingLimit >= m_pdwRingBuffer && m_pdwRingLimit < m_pdwBufferLimit);
  140. ASSERT(m_pdwRingNext >= m_pdwRingBuffer && m_pdwRingNext < m_pdwBufferLimit);
  141. if (m_pdwRingNext < m_pdwRingLimit) return m_pdwRingLimit - m_pdwRingNext;
  142. if (m_pdwRingNext > m_pdwRingLimit) return (m_pdwRingLimit - m_pdwRingBuffer)
  143. +(m_pdwBufferLimit - m_pdwRingNext );
  144. return (m_fUsed)? 0 : (m_pdwBufferLimit - m_pdwRingBuffer);
  145. }
  146. inline UINT CIOQueue::CdwAvailable()
  147. {
  148. ASSERT(Initialed());
  149. ASSERT(Attached());
  150. return m_cdwRingBuffer - CdwBuffered();
  151. }
  152. inline UINT CIOQueue::CdwAvailableForReading()
  153. {
  154. ASSERT(!Writable());
  155. ASSERT(m_cdwInTransit <= CdwAvailable());
  156. return CdwAvailable() - m_cdwInTransit;
  157. }
  158. inline UINT CIOQueue::CdwAvailableForWriting()
  159. {
  160. ASSERT(Writable());
  161. ASSERT(m_cdwInTransit <= CdwBuffered());
  162. return CdwBuffered() - m_cdwInTransit;
  163. }
  164. inline BOOL CIOQueue::AskForDiskSpace()
  165. {
  166. ASSERT(m_puio);
  167. return m_puio->AskForDiskSpace();
  168. }
  169. #endif // _IOQUEUE_H__