1
0

BufferPool.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #ifndef NULLSOFT_BUFFERPOOLH
  2. #define NULLSOFT_BUFFERPOOLH
  3. #include <wmsdk.h>
  4. #include "../nu/AutoLock.h"
  5. #include <deque>
  6. #include <iostream>
  7. #include <cassert>
  8. using namespace Nullsoft::Utility;
  9. class Buffer;
  10. class Pool
  11. {
  12. public:
  13. virtual void ReturnBuffer(Buffer *buffer) = 0;
  14. };
  15. class Buffer : public INSSBuffer
  16. {
  17. public:
  18. Buffer(size_t _size, Pool *_pool)
  19. : size(_size),
  20. length(0),
  21. pool(_pool),
  22. refCount(1)
  23. {
  24. buffer = new unsigned char[size];
  25. }
  26. ~Buffer()
  27. {
  28. delete[] buffer;
  29. }
  30. ULONG STDMETHODCALLTYPE AddRef()
  31. {
  32. return ++refCount;
  33. }
  34. ULONG STDMETHODCALLTYPE Release()
  35. {
  36. assert(refCount > 0);
  37. if (--refCount == 0)
  38. {
  39. length = 0;
  40. pool->ReturnBuffer(this);
  41. }
  42. return refCount;
  43. }
  44. HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject)
  45. {
  46. if (IID_INSSBuffer == iid)
  47. {
  48. *ppvObject = static_cast<INSSBuffer *>(this);
  49. AddRef();
  50. return S_OK;
  51. }
  52. else
  53. {
  54. *ppvObject = 0;
  55. return E_NOINTERFACE;
  56. }
  57. }
  58. HRESULT STDMETHODCALLTYPE GetBuffer(BYTE **ppdwBuffer)
  59. {
  60. *ppdwBuffer = (BYTE *)buffer;
  61. return S_OK;
  62. }
  63. HRESULT STDMETHODCALLTYPE GetBufferAndLength(BYTE **ppdwBuffer, DWORD *pdwLength)
  64. {
  65. *ppdwBuffer = (BYTE *)buffer;
  66. *pdwLength = length;
  67. return S_OK;
  68. }
  69. HRESULT STDMETHODCALLTYPE GetLength(DWORD *pdwLength)
  70. {
  71. *pdwLength = length;
  72. return S_OK;
  73. }
  74. HRESULT STDMETHODCALLTYPE GetMaxLength(DWORD *pdwLength)
  75. {
  76. *pdwLength = size;
  77. return S_OK;
  78. }
  79. HRESULT STDMETHODCALLTYPE SetLength(DWORD dwLength)
  80. {
  81. length = dwLength;
  82. return S_OK;
  83. }
  84. bool CanFit(size_t sizeCompare)
  85. {
  86. return (sizeCompare <= size);
  87. }
  88. size_t size, length;
  89. Pool *pool;
  90. int refCount;
  91. unsigned char *buffer;
  92. };
  93. class BufferPool : public Pool
  94. {
  95. typedef std::deque<Buffer *> PoolList;
  96. public:
  97. long limit;
  98. BufferPool() : allocSize(0),
  99. poolSize(0),
  100. limit(0)
  101. {}
  102. ~BufferPool()
  103. {
  104. FreeBuffers();
  105. }
  106. void FreeBuffers()
  107. {
  108. AutoLock lock (bufferGuard);
  109. while (!pool.empty())
  110. {
  111. Buffer *buff = pool.front();
  112. delete buff;
  113. pool.pop_front();
  114. poolSize = 0;
  115. }
  116. }
  117. void ReturnBuffer(Buffer *buffer)
  118. {
  119. AutoLock lock (bufferGuard);
  120. pool.push_back(buffer);
  121. }
  122. Buffer *SearchForBuffer(size_t size)
  123. {
  124. PoolList::iterator itr;
  125. AutoLock lock (bufferGuard);
  126. for (itr = pool.begin();itr != pool.end();itr++)
  127. {
  128. if ((*itr)->CanFit(size))
  129. {
  130. Buffer *buff = *itr;
  131. pool.erase(itr);
  132. buff->AddRef();
  133. return buff;
  134. }
  135. }
  136. return 0;
  137. }
  138. void PreAllocate(size_t count)
  139. {
  140. if (!allocSize)
  141. return ;
  142. for (size_t i = 0;i != count;i++)
  143. {
  144. AutoLock lock (bufferGuard);
  145. pool.push_back( new Buffer(allocSize , this));
  146. }
  147. }
  148. INSSBuffer *GetBuffer(size_t size)
  149. {
  150. Buffer *buff = SearchForBuffer(size);
  151. /*
  152. while (!buff && poolSize>=limit && limit)
  153. {
  154. Sleep(1);
  155. buff = SearchForBuffer(size);
  156. }*/
  157. if (!buff)
  158. {
  159. poolSize++;
  160. std::cerr << "poolsize = " << poolSize << std::endl;
  161. buff = new Buffer(allocSize ? allocSize : size, this);
  162. }
  163. return buff;
  164. }
  165. void test()
  166. {
  167. std::cerr << "pool.size() == " << pool.size();
  168. std::cerr << " and poolsize == " << poolSize << std::endl;
  169. }
  170. void SetAllocSize(long size)
  171. {
  172. allocSize = size;
  173. }
  174. PoolList pool;
  175. LockGuard bufferGuard;
  176. size_t allocSize;
  177. size_t poolSize;
  178. };
  179. #endif