Source code of Windows XP (NT5)
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.

262 lines
4.8 KiB

  1. /*++
  2. Copyright (c) 1998, Microsoft Corporation
  3. Module Name:
  4. buffer.c
  5. Abstract:
  6. This module contains code for buffer-management.
  7. Author:
  8. Abolade Gbadegesin (aboladeg) 2-Mar-1998
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include "nathlpp.h"
  13. #include "list.h"
  14. //#include "socket.h"
  15. LIST_ENTRY NhpBufferQueue;
  16. LONG NhpBufferQueueLength;
  17. CRITICAL_SECTION NhpBufferQueueLock;
  18. PNH_BUFFER
  19. NhAcquireFixedLengthBuffer(
  20. VOID
  21. )
  22. /*++
  23. Routine Description:
  24. This routine is invoked to acquire an I/O buffer.
  25. If no buffer is available on the buffer queue, a new one is obtained.
  26. Arguments:
  27. none.
  28. Return Value:
  29. PNH_BUFFER - the buffer allocated
  30. --*/
  31. {
  32. PNH_BUFFER Buffer;
  33. PLIST_ENTRY Link;
  34. EnterCriticalSection(&NhpBufferQueueLock);
  35. if (!IsListEmpty(&NhpBufferQueue)) {
  36. Link = RemoveHeadList(&NhpBufferQueue);
  37. LeaveCriticalSection(&NhpBufferQueueLock);
  38. InterlockedDecrement(&NhpBufferQueueLength);
  39. Buffer = CONTAINING_RECORD(Link, NH_BUFFER, Link);
  40. Buffer->Type = NhFixedLengthBufferType;
  41. return Buffer;
  42. }
  43. LeaveCriticalSection(&NhpBufferQueueLock);
  44. Buffer = NH_ALLOCATE_BUFFER();
  45. if (Buffer) {
  46. Buffer->Type = NhFixedLengthBufferType;
  47. }
  48. return Buffer;
  49. } // NhAcquireFixedLengthBuffer
  50. PNH_BUFFER
  51. NhAcquireVariableLengthBuffer(
  52. ULONG Length
  53. )
  54. /*++
  55. Routine Description:
  56. This routine is invoked to acquire an I/O buffer of non-standard size.
  57. If the length requested is less than or equal to 'NH_BUFFER_SIZE',
  58. a buffer from the shared buffer-queue is returned.
  59. Otherwise, a buffer is especially allocated for the caller.
  60. Arguments:
  61. Length - the length of the buffer required.
  62. Return Value:
  63. PNH_BUFFER - the buffer allocated.
  64. --*/
  65. {
  66. PNH_BUFFER Buffer;
  67. if (Length <= NH_BUFFER_SIZE) {
  68. return NhAcquireFixedLengthBuffer();
  69. }
  70. Buffer = reinterpret_cast<PNH_BUFFER>(
  71. NH_ALLOCATE(FIELD_OFFSET(NH_BUFFER, Buffer[Length]))
  72. );
  73. if (Buffer) { Buffer->Type = NhVariableLengthBufferType; }
  74. return Buffer;
  75. } // NhAcquireVariableLengthBuffer
  76. PNH_BUFFER
  77. NhDuplicateBuffer(
  78. PNH_BUFFER Bufferp
  79. )
  80. /*++
  81. Routine Description:
  82. This routine creates a duplicate of the given buffer,
  83. including both its data and its control information.
  84. N.B. Variable-length buffers cannot be duplicated by this routine.
  85. Arguments:
  86. Bufferp - the buffer to be duplicated
  87. Return Value:
  88. PNH_BUFFER - a pointer to the duplicate
  89. --*/
  90. {
  91. PNH_BUFFER Duplicatep;
  92. //ASSERT(Bufferp->Type == NhFixedLengthBufferType);
  93. if (!(Duplicatep = NhAcquireBuffer())) { return NULL; }
  94. *Duplicatep = *Bufferp;
  95. return Duplicatep;
  96. } // NhDuplicateBuffer
  97. ULONG
  98. NhInitializeBufferManagement(
  99. VOID
  100. )
  101. /*++
  102. Routine Description:
  103. This routine readies the buffer-management for operation.
  104. Arguments:
  105. none.
  106. Return Value:
  107. ULONG - Win32 status code.
  108. --*/
  109. {
  110. ULONG Error = NO_ERROR;
  111. InitializeListHead(&NhpBufferQueue);
  112. NhpBufferQueueLength = 0;
  113. __try {
  114. InitializeCriticalSection(&NhpBufferQueueLock);
  115. } __except(EXCEPTION_EXECUTE_HANDLER) {
  116. /*
  117. NhTrace(
  118. TRACE_FLAG_BUFFER,
  119. "NhInitializeBufferManagement: exception %d creating lock",
  120. Error = GetExceptionCode()
  121. );*/
  122. }
  123. return Error;
  124. } // NhInitializeBufferManagement
  125. VOID
  126. NhReleaseBuffer(
  127. PNH_BUFFER Bufferp
  128. )
  129. /*++
  130. Routine Description:
  131. This routine is called to release a buffer to the buffer queue.
  132. It attempts to place the buffer on the queue for re-use, unless
  133. the queue is full in which case the buffer is immediately freed.
  134. Arguments:
  135. Bufferp - the buffer to be released
  136. Return Value:
  137. none.
  138. --*/
  139. {
  140. if (NhpBufferQueueLength > NH_MAX_BUFFER_QUEUE_LENGTH ||
  141. Bufferp->Type != NhFixedLengthBufferType) {
  142. NH_FREE_BUFFER(Bufferp);
  143. } else {
  144. EnterCriticalSection(&NhpBufferQueueLock);
  145. InsertHeadList(&NhpBufferQueue, &Bufferp->Link);
  146. LeaveCriticalSection(&NhpBufferQueueLock);
  147. InterlockedIncrement(&NhpBufferQueueLength);
  148. }
  149. } // NhReleaseBuffer
  150. VOID
  151. NhShutdownBufferManagement(
  152. VOID
  153. )
  154. /*++
  155. Routine Description:
  156. This routine cleans up resources used by the buffer-management module.
  157. It assumes the list will not be accessed while the clean up is in progress.
  158. Arguments:
  159. none.
  160. Return Value:
  161. none.
  162. --*/
  163. {
  164. PLIST_ENTRY Link;
  165. PNH_BUFFER Bufferp;
  166. while (!IsListEmpty(&NhpBufferQueue)) {
  167. Link = RemoveHeadList(&NhpBufferQueue);
  168. Bufferp = CONTAINING_RECORD(Link, NH_BUFFER, Link);
  169. NH_FREE_BUFFER(Bufferp);
  170. }
  171. DeleteCriticalSection(&NhpBufferQueueLock);
  172. NhpBufferQueueLength = 0;
  173. } // NhShutdownBufferManagement