BufferManager.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Net.Sockets;
  5. namespace SuperSocket.Common
  6. {
  7. /// <summary>
  8. /// This class creates a single large buffer which can be divided up and assigned to SocketAsyncEventArgs objects for use
  9. /// with each socket I/O operation. This enables bufffers to be easily reused and gaurds against fragmenting heap memory.
  10. ///
  11. /// The operations exposed on the BufferManager class are not thread safe.
  12. /// </summary>
  13. public class BufferManager
  14. {
  15. int m_numBytes; // the total number of bytes controlled by the buffer pool
  16. byte[] m_buffer; // the underlying byte array maintained by the Buffer Manager
  17. Stack<int> m_freeIndexPool; //
  18. int m_currentIndex;
  19. int m_bufferSize;
  20. /// <summary>
  21. /// Initializes a new instance of the <see cref="BufferManager"/> class.
  22. /// </summary>
  23. /// <param name="totalBytes">The total bytes.</param>
  24. /// <param name="bufferSize">Size of the buffer.</param>
  25. public BufferManager(int totalBytes, int bufferSize)
  26. {
  27. m_numBytes = totalBytes;
  28. m_currentIndex = 0;
  29. m_bufferSize = bufferSize;
  30. m_freeIndexPool = new Stack<int>();
  31. }
  32. /// <summary>
  33. /// Allocates buffer space used by the buffer pool
  34. /// </summary>
  35. public void InitBuffer()
  36. {
  37. // create one big large buffer and divide that out to each SocketAsyncEventArg object
  38. m_buffer = new byte[m_numBytes];
  39. }
  40. /// <summary>
  41. /// Assigns a buffer from the buffer pool to the specified SocketAsyncEventArgs object
  42. /// </summary>
  43. /// <returns>true if the buffer was successfully set, else false</returns>
  44. public bool SetBuffer(SocketAsyncEventArgs args)
  45. {
  46. if (m_freeIndexPool.Count > 0)
  47. {
  48. args.SetBuffer(m_buffer, m_freeIndexPool.Pop(), m_bufferSize);
  49. }
  50. else
  51. {
  52. if ((m_numBytes - m_bufferSize) < m_currentIndex)
  53. {
  54. return false;
  55. }
  56. args.SetBuffer(m_buffer, m_currentIndex, m_bufferSize);
  57. m_currentIndex += m_bufferSize;
  58. }
  59. return true;
  60. }
  61. /// <summary>
  62. /// Removes the buffer from a SocketAsyncEventArg object. This frees the buffer back to the
  63. /// buffer pool
  64. /// </summary>
  65. public void FreeBuffer(SocketAsyncEventArgs args)
  66. {
  67. m_freeIndexPool.Push(args.Offset);
  68. args.SetBuffer(null, 0, 0);
  69. }
  70. }
  71. }