CnIocpSimpleMemPool.pas 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. {******************************************************************************}
  2. { CnPack For Delphi/C++Builder }
  3. { 中国人自己的开放源码第三方开发包 }
  4. { (C)Copyright 2001-2016 CnPack 开发组 }
  5. { ------------------------------------ }
  6. { }
  7. { 本开发包是开源的自由软件,您可以遵照 CnPack 的发布协议来修 }
  8. { 改和重新发布这一程序。 }
  9. { }
  10. { 发布这一开发包的目的是希望它有用,但没有任何担保。甚至没有 }
  11. { 适合特定目的而隐含的担保。更详细的情况请参阅 CnPack 发布协议。 }
  12. { }
  13. { 您应该已经和开发包一起收到一份 CnPack 发布协议的副本。如果 }
  14. { 还没有,可访问我们的网站: }
  15. { }
  16. { 网站地址:http://www.cnpack.org }
  17. { 电子邮件:master@cnpack.org }
  18. { }
  19. {******************************************************************************}
  20. unit CnIocpSimpleMemPool;
  21. {* |<PRE>
  22. ================================================================================
  23. * 软件名称:网络通讯组件包
  24. * 单元名称:Windows完成端口(IOCP)组件使用的简单内存池实现单元
  25. * 单元作者:cnwinds
  26. * 菩提(cxmld@126.com) 移植修改
  27. * 备 注:
  28. * 1.TCnMemPoolMgr类是内存池管理的实现。
  29. * CnMemPoolMgr是TCnMemPoolMgr类的全局对象,可以通过该对象使用内存池。
  30. * 他将大小(MemorySize)相同的内存块(TCnMemoryBlockItem)放在一个(TCnMemoryTypeItem)中进行管理。
  31. * TCnMemPoolMgr类中管理多个内存类型块(TCnMemoryTypeItem)。
  32. * 一个内存类型块(TCnMemoryTypeItem)中包含了多个内存块(TCnMemoryBlockItem)。
  33. * 阀值(Threshold)控制在一个TMemoryTypeItem中内存块的个数。
  34. * 在系统频繁申请内存块的时候,总个数会大于阀值。
  35. * 当系统对内存块的并发使用数低于阀值的时候释放内存块,让总个数等于阀值。
  36. * 这个策略可以避免繁忙的时候频繁申请、释放内存,或者空闲的时候浪费内存。
  37. * 2.TCnMemoryPool是一个控件。为了能可视化开发而产生的类。
  38. * 可能出现多个控件的内存块大小相同,这样将对应到同一个内存类型块(TCnMemoryTypeItem)
  39. * 出现这种情况多个控件将共用内存类型块(TCnMemoryTypeItem)中的内存块。阀值将取他们设置的最大值。
  40. *
  41. TODO >>>
  42. * 1.TCnIocpMemPool类增加了一个方法:GetFreeMemoryType, 获取一个空闲的内存类型
  43. * 2.TCnIocpMemPool分配的内存大小是固定,最大值由每一次分配决定
  44. * 3.增加 TCnIocpSimpleMemPool来包装 TCnIocpMemPool的功能, 即租用内存和归还内存
  45. * 4.使用"租用"和"归还"是为了区别正常的"分配内存"和"释放内存"
  46. * 5.TCnIocpSimpleMemPool对应一个内存类型, 每个内存类型的类型值,自动获取
  47. * 6.二个自定义名词(可能名字起得不够好):"内存块"和"内存类型块"
  48. * 每个 TCnIocpSimpleMemPool 对应一个内存类型块, 它由多个"内存块"组成.每次用户
  49. * 租用就是得到一个整的"内存块", 大小由第一次租用时确定.
  50. * TCnIocpMemPool包含了多个 "内存类型块", 即每注册一次时,就分配一个"内存类型块"
  51. TODO >>>
  52. *
  53. * 开发平台:PWin2000Pro + Delphi 7.01
  54. * 兼容测试:PWin9X/2000/XP + Delphi 5/6/7 + C++Builder 5/6
  55. * 本 地 化:该单元中的字符串均符合本地化处理方式
  56. * 单元标识:$Id$
  57. * 修改记录:2008.09.16 V1.0
  58. * 创建单元
  59. ================================================================================
  60. |</PRE>}
  61. interface
  62. {$I CnPack.inc}
  63. uses
  64. SysUtils, Classes, SyncObjs, Windows, Controls;
  65. const
  66. SCnErrorNotRegister = '没有注册该内存类型(%d)!';
  67. SCnErrorBlockNotRent = '内存块没有被借出!';
  68. SCnErrorBlockUnknow = '没有该内存块!';
  69. type
  70. TCreateMemoryEvent = procedure(Sender: TObject; var MemoryPtr: Pointer) of object;
  71. TFreeMemoryEvent = procedure(Sender: TObject; MemoryPtr: Pointer) of object;
  72. TCnMemoryBlockItem = record
  73. {* 内存块头}
  74. MemoryBlockPtr: Pointer; //内存指针
  75. RentTime: Cardinal; //租用时间
  76. IsRent: Boolean; //是否租用
  77. RentCount: Cardinal; //租用次数
  78. Size: Cardinal;
  79. end;
  80. PCnMemoryBlockItem = ^TCnMemoryBlockItem;
  81. TCnMemoryTypeItem = record
  82. {* 内存类型块头}
  83. RefCount: Cardinal; //该类型块的引用次数
  84. MemorySize: Cardinal; //内存块的大小
  85. CreateMemoryProc: TCreateMemoryEvent; //创建内存方法指针
  86. FreeMemoryProc: TFreeMemoryEvent; //释放内存方法指针
  87. Threshold: Cardinal; //内存块个数的阀值
  88. //如果缓存的块数多于该值则要启动清理程序。
  89. IdelCount: Cardinal; //空闲内存块的个数
  90. Lock: TCriticalSection; //互锁相关
  91. MemoryBlockList: TList; //内存块列表
  92. end;
  93. PCnMemoryTypeItem = ^TCnMemoryTypeItem;
  94. TCnSimpleMemPoolMgr = class
  95. private
  96. FLock: TCriticalSection;
  97. FMemoryTypeList: TList;
  98. function RegisterMemoryTypeItem(MemorySize: Cardinal;
  99. CreateMemoryProc: TCreateMemoryEvent;
  100. FreeMemoryProc: TFreeMemoryEvent): PCnMemoryTypeItem;
  101. {* 注册内存类型块(带线程锁)}
  102. procedure UnregisterMemoryTypeItem(MemoryTypeItem: PCnMemoryTypeItem);
  103. {* 注销内存类型块}
  104. function CreateMemoryBlockItem(MemoryTypeItem: PCnMemoryTypeItem): PCnMemoryBlockItem;
  105. procedure FreeMemoryBlockItem(MemoryTypeItem: PCnMemoryTypeItem;
  106. MemoryBlockItem: PCnMemoryBlockItem);
  107. function FindMemoryTypeItem(MemorySize: Cardinal;
  108. CreateMemoryProc: TCreateMemoryEvent;
  109. FreeMemoryProc: TFreeMemoryEvent): PCnMemoryTypeItem;
  110. procedure Clear;
  111. public
  112. constructor Create;
  113. destructor Destroy; override;
  114. function RegisterMemoryType(MemorySize: Cardinal;
  115. CreateMemoryProc: TCreateMemoryEvent;
  116. FreeMemoryProc: TFreeMemoryEvent): PCnMemoryTypeItem;
  117. {* 注册内存类型块 参数:内存类型, 创建和释放方法指针
  118. 两方法指针是事件通知,同时可以自定义分配内存与释放内存的方法}
  119. procedure UnregisterMemoryType(MemoryTypeItem: PCnMemoryTypeItem);
  120. {* 注销内存类型块}
  121. procedure SetThreshold(MemoryTypeItem: PCnMemoryTypeItem; Threshold: Cardinal);
  122. {* 设置租用内存块的阀值。
  123. 阀值和上限的区别:
  124. 阀值表示当系统空闲的时候建议不要超过的值。上限表示任何时候都不能超过该值。
  125. }
  126. procedure RentMemory(MemoryTypeItem: PCnMemoryTypeItem; var MemoryPtr: Pointer);
  127. {* 租用一块内存}
  128. procedure ReturnMemory(MemoryTypeItem: PCnMemoryTypeItem; MemoryPtr: Pointer);
  129. {* 返还一块内存}
  130. end;
  131. TCnCustomSimpleMemPool = class (TComponent)
  132. private
  133. FMemorySize: Cardinal;
  134. FThreshold : Cardinal;
  135. FOnCreateMemory : TCreateMemoryEvent;
  136. FOnFreeMemory : TFreeMemoryEvent;
  137. FMemTypeItem : PCnMemoryTypeItem;
  138. FIsReg: Boolean; //是否已经注册到内存池管理器了
  139. procedure EnsureRegister;
  140. procedure DoRegister;
  141. procedure DoUnregister;
  142. procedure SetThreshold(const Value: Cardinal);
  143. procedure SetMemorySize(const Value: Cardinal);
  144. procedure SetOnCreateMemory(const Value: TCreateMemoryEvent);
  145. procedure SetOnFreeMemory(const Value: TFreeMemoryEvent);
  146. public
  147. constructor Create(AOwner: TComponent); override;
  148. destructor Destroy; override;
  149. procedure RentMemory(var MemoryPtr: Pointer);
  150. {* 租用内存}
  151. procedure ReturnMemory(MemoryPtr: Pointer);
  152. {* 归还内存}
  153. public
  154. property MemorySize: Cardinal read FMemorySize write SetMemorySize;
  155. {* 内存块的大小}
  156. property Threshold : Cardinal read FThreshold write SetThreshold;
  157. {* 内存块的数量阀值(不是最大值,即可分配更多的内存块)}
  158. property OnCreateMemory : TCreateMemoryEvent read FOnCreateMemory write SetOnCreateMemory;
  159. {* 自定义在系统中分配内存的方法,默认实现采用 GetMemory}
  160. property OnFreeMemory: TFreeMemoryEvent read FOnFreeMemory write SetOnFreeMemory;
  161. {* 自定义在系统中释放内存的方法,默认实现采用 FreeMemory}
  162. end;
  163. TCnIocpSimpleMemPool = class(TCnCustomSimpleMemPool)
  164. published
  165. property MemorySize;
  166. {* 内存块的大小}
  167. property Threshold;
  168. {* 内存块的数量阀值(不是最大值,即可分配更多的内存块)}
  169. property OnCreateMemory;
  170. {* 自定义在系统中分配内存的方法,默认实现采用 GetMemory}
  171. property OnFreeMemory;
  172. {* 自定义在系统中释放内存的方法,默认实现采用 FreeMemory}
  173. end;
  174. var
  175. CnSimpleMemPoolMgr: TCnSimpleMemPoolMgr;
  176. implementation
  177. { TCnSimpleMemPoolMgr }
  178. constructor TCnSimpleMemPoolMgr.Create;
  179. begin
  180. FMemoryTypeList := TList.Create;
  181. FLock := TCriticalSection.Create;
  182. end;
  183. destructor TCnSimpleMemPoolMgr.Destroy;
  184. begin
  185. Clear;
  186. FreeAndNil(FMemoryTypeList);
  187. FreeAndNil(FLock);
  188. inherited;
  189. end;
  190. procedure TCnSimpleMemPoolMgr.Clear;
  191. var
  192. TypeItem: PCnMemoryTypeItem;
  193. I: Integer;
  194. begin
  195. // 清除所有内存块
  196. FLock.Enter;
  197. try
  198. for I := 0 to FMemoryTypeList.Count - 1 do
  199. begin
  200. TypeItem := PCnMemoryTypeItem(FMemoryTypeList[I]);
  201. UnregisterMemoryTypeItem(TypeItem);
  202. end;
  203. finally
  204. FLock.Release;
  205. end;
  206. end;
  207. function TCnSimpleMemPoolMgr.RegisterMemoryTypeItem(MemorySize: Cardinal;
  208. CreateMemoryProc: TCreateMemoryEvent; FreeMemoryProc: TFreeMemoryEvent): PCnMemoryTypeItem;
  209. begin
  210. Result := New(PCnMemoryTypeItem);
  211. Result^.Lock := TCriticalSection.Create;
  212. Result^.RefCount := 1;
  213. Result^.MemorySize := MemorySize;
  214. Result^.MemoryBlockList := TList.Create;
  215. Result^.CreateMemoryProc := CreateMemoryProc;
  216. Result^.FreeMemoryProc := FreeMemoryProc;
  217. Result^.Threshold := 20;
  218. Result^.IdelCount := 0;
  219. end;
  220. procedure TCnSimpleMemPoolMgr.UnregisterMemoryTypeItem(MemoryTypeItem: PCnMemoryTypeItem);
  221. var
  222. I: Integer;
  223. begin
  224. for I := 0 to MemoryTypeItem^.MemoryBlockList.Count - 1 do
  225. FreeMemoryBlockItem(MemoryTypeItem, MemoryTypeItem^.MemoryBlockList[I]);
  226. FreeAndNil(MemoryTypeItem^.Lock);
  227. FreeAndNil(MemoryTypeItem^.MemoryBlockList);
  228. Dispose(MemoryTypeItem);
  229. end;
  230. function TCnSimpleMemPoolMgr.CreateMemoryBlockItem(
  231. MemoryTypeItem: PCnMemoryTypeItem): PCnMemoryBlockItem;
  232. var
  233. Size: Integer;
  234. begin
  235. Size := MemoryTypeItem^.MemorySize;
  236. //创建内存块
  237. Result := New(PCnMemoryBlockItem);
  238. //申请内存。如果没有设置回调函数则使用GetMemory申请内存。
  239. if (Assigned(MemoryTypeItem.CreateMemoryProc)) then
  240. MemoryTypeItem^.CreateMemoryProc(Self, Result^.MemoryBlockPtr)
  241. else
  242. Result^.MemoryBlockPtr := GetMemory(Size);
  243. Result^.RentTime := 0;
  244. Result^.IsRent := False;
  245. Result^.RentCount := 0;
  246. Result^.Size := Size;
  247. end;
  248. procedure TCnSimpleMemPoolMgr.FreeMemoryBlockItem(MemoryTypeItem: PCnMemoryTypeItem;
  249. MemoryBlockItem: PCnMemoryBlockItem);
  250. begin
  251. //释放内存
  252. if (Assigned(MemoryTypeItem.FreeMemoryProc)) then
  253. MemoryTypeItem.FreeMemoryProc(Self, MemoryBlockItem^.MemoryBlockPtr)
  254. else
  255. FreeMemory(MemoryBlockItem^.MemoryBlockPtr);
  256. //释放内存块
  257. Dispose(MemoryBlockItem);
  258. end;
  259. function TCnSimpleMemPoolMgr.FindMemoryTypeItem(MemorySize: Cardinal;
  260. CreateMemoryProc: TCreateMemoryEvent; FreeMemoryProc: TFreeMemoryEvent): PCnMemoryTypeItem;
  261. var
  262. I: Integer;
  263. begin
  264. FLock.Enter;
  265. try
  266. for I := 0 to FMemoryTypeList.Count - 1 do
  267. begin
  268. Result := PCnMemoryTypeItem(FMemoryTypeList[I]);
  269. if (Result^.MemorySize = MemorySize) and
  270. (@Result^.CreateMemoryProc = @CreateMemoryProc) and
  271. (@Result^.FreeMemoryProc = @FreeMemoryProc) then Exit;
  272. end;
  273. Result := nil;
  274. finally
  275. FLock.Release;
  276. end;
  277. end;
  278. function TCnSimpleMemPoolMgr.RegisterMemoryType(MemorySize: Cardinal;
  279. CreateMemoryProc: TCreateMemoryEvent; FreeMemoryProc: TFreeMemoryEvent): PCnMemoryTypeItem;
  280. begin
  281. Result := FindMemoryTypeItem(MemorySize, CreateMemoryProc, FreeMemoryProc);
  282. if Result = nil then //不存在,就创建
  283. begin
  284. Result := RegisterMemoryTypeItem(MemorySize, CreateMemoryProc, FreeMemoryProc);
  285. FLock.Enter;
  286. try
  287. FMemoryTypeList.Add(Result); //并加入List中
  288. finally
  289. FLock.Release;
  290. end;
  291. end else
  292. begin
  293. Inc(Result^.RefCount); //存在则增加引用计数
  294. end;
  295. end;
  296. procedure TCnSimpleMemPoolMgr.UnregisterMemoryType(MemoryTypeItem: PCnMemoryTypeItem);
  297. begin
  298. //减少引用计数
  299. Dec(MemoryTypeItem^.RefCount);
  300. if MemoryTypeItem^.RefCount <> 0 then Exit;
  301. FLock.Enter;
  302. try
  303. FMemoryTypeList.Remove(MemoryTypeItem);
  304. finally
  305. FLock.Release;
  306. end;
  307. UnregisterMemoryTypeItem(MemoryTypeItem);
  308. end;
  309. procedure TCnSimpleMemPoolMgr.SetThreshold(MemoryTypeItem: PCnMemoryTypeItem; Threshold: Cardinal);
  310. begin
  311. //如果一个MemoryTypeItem有多个引用,则使用最大的阀值
  312. if MemoryTypeItem <> nil then
  313. begin
  314. if MemoryTypeItem^.RefCount = 1 then
  315. MemoryTypeItem^.Threshold := Threshold
  316. else
  317. if MemoryTypeItem^.Threshold < Threshold then
  318. MemoryTypeItem^.Threshold := Threshold;
  319. end;
  320. end;
  321. procedure TCnSimpleMemPoolMgr.RentMemory(MemoryTypeItem: PCnMemoryTypeItem; var MemoryPtr: Pointer);
  322. var
  323. BlockItem: PCnMemoryBlockItem;
  324. begin
  325. //不需要循环查找,只要找到第一个内存块,如果被租用则表示所有内存块都已经被租用了。
  326. MemoryTypeItem^.Lock.Enter;
  327. try
  328. if MemoryTypeItem^.MemoryBlockList.Count > 0 then
  329. begin
  330. BlockItem := PCnMemoryBlockItem(MemoryTypeItem^.MemoryBlockList[0]);
  331. if not BlockItem^.IsRent then //第0个内存块是否已租用
  332. begin
  333. MemoryTypeItem^.MemoryBlockList.Remove(BlockItem);
  334. MemoryTypeItem^.MemoryBlockList.Add(BlockItem); //将内存块重新放入到LIST的最后
  335. MemoryPtr := BlockItem.MemoryBlockPtr; //取得内存块的指针
  336. Inc(BlockItem^.RentCount); //租用总数+1
  337. BlockItem^.RentTime := GetTickCount; //租用时间
  338. BlockItem^.IsRent := True; //置租用标志
  339. //空闲内存块个数减一
  340. Dec(MemoryTypeItem^.IdelCount);
  341. Exit;
  342. end;
  343. end;
  344. // 新创建一个内存块
  345. BlockItem := CreateMemoryBlockItem(MemoryTypeItem);
  346. MemoryPtr := BlockItem^.MemoryBlockPtr;
  347. Inc(BlockItem^.RentCount);
  348. BlockItem^.RentTime := GetTickCount;
  349. BlockItem^.IsRent := True;
  350. BlockItem^.Size := MemoryTypeItem^.MemorySize;
  351. MemoryTypeItem^.MemoryBlockList.Add(BlockItem);
  352. finally
  353. MemoryTypeItem^.Lock.Release;
  354. end;
  355. end;
  356. procedure TCnSimpleMemPoolMgr.ReturnMemory(MemoryTypeItem: PCnMemoryTypeItem; MemoryPtr: Pointer);
  357. var
  358. I: Integer;
  359. BlockItem: PCnMemoryBlockItem;
  360. ReleaseCount: Cardinal;
  361. UsedCount: Cardinal;
  362. TotalCount: Cardinal;
  363. begin
  364. //对内存块的调整不是强制性的,原则是在方便的时候调整一下内块的个数
  365. MemoryTypeItem^.Lock.Enter;
  366. try
  367. ReleaseCount := 0;
  368. //判断是否要删除内存块
  369. TotalCount := MemoryTypeItem^.MemoryBlockList.Count;
  370. if TotalCount > MemoryTypeItem^.Threshold then
  371. begin
  372. UsedCount := TotalCount - MemoryTypeItem^.IdelCount;
  373. if UsedCount < MemoryTypeItem^.Threshold then
  374. begin
  375. //计算要删除内存块的个数
  376. //不表示一定要删除这么多个内存块,理想情况下会删除这么多内存块
  377. ReleaseCount := TotalCount - MemoryTypeItem^.Threshold;
  378. end;
  379. end;
  380. for I := MemoryTypeItem^.MemoryBlockList.Count - 1 downto 0 do
  381. begin
  382. BlockItem := PCnMemoryBlockItem(MemoryTypeItem^.MemoryBlockList[I]);
  383. if MemoryPtr = BlockItem^.MemoryBlockPtr then //查询内存块(比较地址相同)
  384. begin
  385. if BlockItem^.IsRent then
  386. begin
  387. //归还内存块
  388. BlockItem^.RentTime := 0;
  389. BlockItem^.IsRent := False;
  390. MemoryTypeItem^.MemoryBlockList.Remove(BlockItem);
  391. MemoryTypeItem^.MemoryBlockList.Insert(0, BlockItem); //插入到第0个
  392. //空闲内存块个数加一
  393. Inc(MemoryTypeItem^.IdelCount);
  394. Exit;
  395. end
  396. else
  397. raise Exception.Create(SCnErrorBlockNotRent); //没有被租用异常
  398. end;
  399. //释放内存块
  400. if (ReleaseCount <> 0) and (not BlockItem^.IsRent) then
  401. begin
  402. FreeMemoryBlockItem(MemoryTypeItem, BlockItem);
  403. MemoryTypeItem^.MemoryBlockList.Remove(BlockItem);
  404. Dec(ReleaseCount);
  405. end;
  406. end;
  407. raise Exception.Create(SCnErrorBlockUnknow); //没有找到内存块抛出异常
  408. finally
  409. MemoryTypeItem^.Lock.Release;
  410. end;
  411. end;
  412. { TCnIocpSimpleMemPool }
  413. constructor TCnCustomSimpleMemPool.Create(AOwner: TComponent);
  414. begin
  415. inherited;
  416. FThreshold := 20;
  417. FMemorySize := 1024;
  418. FIsReg := False;
  419. //使用延迟注册方式,避免初始化参数造成反复注册
  420. //DoRegister;
  421. end;
  422. destructor TCnCustomSimpleMemPool.Destroy;
  423. begin
  424. DoUnregister;
  425. inherited;
  426. end;
  427. procedure TCnCustomSimpleMemPool.EnsureRegister;
  428. begin
  429. if not FIsReg then
  430. DoRegister;
  431. end;
  432. procedure TCnCustomSimpleMemPool.DoRegister;
  433. begin
  434. if (not (csDesigning in ComponentState)) and (not FIsReg) then
  435. begin
  436. FMemTypeItem := CnSimpleMemPoolMgr.RegisterMemoryType(
  437. FMemorySize, FOnCreateMemory, FOnFreeMemory);
  438. CnSimpleMemPoolMgr.SetThreshold(FMemTypeItem, Threshold);
  439. FIsReg := True;
  440. end;
  441. end;
  442. procedure TCnCustomSimpleMemPool.DoUnregister;
  443. begin
  444. if FIsReg then
  445. begin
  446. CnSimpleMemPoolMgr.UnregisterMemoryType(FMemTypeItem);
  447. FIsReg := False;
  448. end;
  449. end;
  450. procedure TCnCustomSimpleMemPool.RentMemory(var MemoryPtr: Pointer);
  451. begin
  452. EnsureRegister;
  453. CnSimpleMemPoolMgr.RentMemory(FMemTypeItem, MemoryPtr);
  454. end;
  455. procedure TCnCustomSimpleMemPool.ReturnMemory(MemoryPtr: Pointer);
  456. begin
  457. EnsureRegister;
  458. CnSimpleMemPoolMgr.ReturnMemory(FMemTypeItem, MemoryPtr);
  459. end;
  460. procedure TCnCustomSimpleMemPool.SetMemorySize(const Value: Cardinal);
  461. begin
  462. if FMemorySize <> Value then
  463. begin
  464. if FIsReg then DoUnregister;
  465. FMemorySize := Value;
  466. end;
  467. end;
  468. procedure TCnCustomSimpleMemPool.SetThreshold(const Value: Cardinal);
  469. begin
  470. if FThreshold <> Value then
  471. begin
  472. FThreshold := Value;
  473. if FIsReg then
  474. CnSimpleMemPoolMgr.SetThreshold(FMemTypeItem, FThreshold);
  475. end;
  476. end;
  477. procedure TCnCustomSimpleMemPool.SetOnCreateMemory(const Value: TCreateMemoryEvent);
  478. begin
  479. if @FOnCreateMemory <> @Value then
  480. begin
  481. if FIsReg then DoUnregister;
  482. FOnCreateMemory := Value;
  483. end;
  484. end;
  485. procedure TCnCustomSimpleMemPool.SetOnFreeMemory(const Value: TFreeMemoryEvent);
  486. begin
  487. if @FOnFreeMemory <> @Value then
  488. begin
  489. if FIsReg then DoUnregister;
  490. FOnFreeMemory := Value;
  491. end;
  492. end;
  493. initialization
  494. CnSimpleMemPoolMgr := TCnSimpleMemPoolMgr.Create;
  495. finalization
  496. CnSimpleMemPoolMgr.Free;
  497. end.