MMAlloc.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:6k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. unit MMAlloc;
  2. {$I COMPILER.INC}
  3. interface
  4. uses
  5.     {$IFDEF WIN32}
  6.     Windows,
  7.     SyncObjs,
  8.     {$ELSE}
  9.     WinTypes,
  10.     WinProcs,
  11.     {$ENDIF}
  12.     SysUtils,
  13.     Classes,
  14.     MMObj,
  15.     MMUtils;
  16. type
  17.     TMMAllocator = class(TObject)
  18.     private
  19.        FBuffers: TList;
  20.        {$IFDEF WIN32}
  21.        FSection: TCriticalSection;
  22.        {$ENDIF}
  23.     public
  24.        constructor Create;
  25.        destructor  Destroy; override;
  26.        procedure Discard;
  27.        procedure DiscardFreeBuffers;
  28.        function  AllocBufferEx(dwFlags, dwSize: DWORD): Pointer;
  29.        function  AllocBuffer(dwFlags, dwSize: DWORD): Pointer;
  30.        procedure FreeBuffer(var lpBuffer: Pointer);
  31.        procedure DiscardBuffer(var lpBuffer: Pointer);
  32.     end;
  33. implementation
  34. type
  35.     PMMBuffer    = ^TMMBuffer;
  36.     TMMBuffer    = record
  37.        lpPointer : Pointer;
  38.        dwLength  : DWORD;
  39.        dwRefCount: integer;
  40.     end;
  41. {== TMMAllocator ==============================================================}
  42. constructor TMMAllocator.Create;
  43. begin
  44.    inherited Create;
  45.    FBuffers := TList.Create;
  46.    {$IFDEF WIN32}
  47.    FSection := TCriticalSection.Create;
  48.    {$ENDIF}
  49. end;
  50. {-- TMMAllocator --------------------------------------------------------------}
  51. destructor TMMAllocator.Destroy;
  52. begin
  53.    Discard;
  54.    FBuffers.Free;
  55.    {$IFDEF WIN32}
  56.    FSection.Free;
  57.    {$ENDIF}
  58.    inherited Destroy;
  59. end;
  60. {-- TMMAllocator --------------------------------------------------------------}
  61. procedure TMMAllocator.Discard;
  62. var
  63.    i: integer;
  64. begin
  65.    {$IFDEF WIN32}
  66.    FSection.Enter;
  67.    {$ENDIF}
  68.    try
  69.       for i := FBuffers.Count-1 downto 0 do
  70.       begin
  71.          GlobalFreePtr(PMMBuffer(FBuffers[i])^.lpPointer);
  72.          Dispose(FBuffers[i]);
  73.          FBuffers.Delete(i);
  74.       end;
  75.    finally
  76.       {$IFDEF WIN32}
  77.        FSection.Leave;
  78.        {$ENDIF}
  79.    end;
  80. end;
  81. {-- TMMAllocator --------------------------------------------------------------}
  82. procedure TMMAllocator.DiscardFreeBuffers;
  83. var
  84.    i: integer;
  85. begin
  86.    {$IFDEF WIN32}
  87.    FSection.Enter;
  88.    {$ENDIF}
  89.    try
  90.       for i := FBuffers.Count-1 downto 0 do
  91.       begin
  92.          with PMMBuffer(FBuffers[i])^ do
  93.          begin
  94.             if (dwRefCount = 0) then
  95.             begin
  96.                GlobalFreePtr(PMMBuffer(FBuffers[i])^.lpPointer);
  97.                Dispose(FBuffers[i]);
  98.                FBuffers.Delete(i);
  99.             end;
  100.          end;
  101.       end;
  102.    finally
  103.       {$IFDEF WIN32}
  104.        FSection.Leave;
  105.        {$ENDIF}
  106.    end;
  107. end;
  108. {-- TMMAllocator --------------------------------------------------------------}
  109. function TMMAllocator.AllocBufferEx(dwFlags: DWORD; dwSize: DWORD): Pointer;
  110. var
  111.    i: integer;
  112.    P: PMMBuffer;
  113. begin
  114.    Result := nil;
  115.    {$IFDEF WIN32}
  116.    FSection.Enter;
  117.    {$ENDIF}
  118.    try
  119.       for i := 0 to FBuffers.Count-1 do
  120.       begin
  121.          with PMMBuffer(FBuffers[i])^ do
  122.          begin
  123.             if (dwRefCount = 0) and (dwLength = dwSize) then
  124.             begin
  125.                Result := lpPointer;
  126.                inc(dwRefCount);
  127.                break;
  128.             end;
  129.          end;
  130.       end;
  131.       if (Result = nil) then
  132.       begin
  133.          { free all unused buffers }
  134.          DiscardFreeBuffers;
  135.          New(P);
  136.          with P^ do
  137.          begin
  138.             lpPointer  := GlobalAllocPtr(dwFlags,dwSize);
  139.             dwLength   := dwSize;
  140.             dwRefCount := 1;
  141.          end;
  142.          FBuffers.Add(P);
  143.          Result := P^.lpPointer;
  144.       end;
  145.    finally
  146.       {$IFDEF WIN32}
  147.       FSection.Leave;
  148.       {$ENDIF}
  149.    end;
  150. end;
  151. {-- TMMAllocator --------------------------------------------------------------}
  152. function TMMAllocator.AllocBuffer(dwFlags,dwSize: DWORD): Pointer;
  153. var
  154.    i: integer;
  155.    P: PMMBuffer;
  156. begin
  157.    Result := nil;
  158.    {$IFDEF WIN32}
  159.    FSection.Enter;
  160.    {$ENDIF}
  161.    try
  162.       for i := 0 to FBuffers.Count-1 do
  163.       begin
  164.          with PMMBuffer(FBuffers[i])^ do
  165.          begin
  166.             if (dwRefCount = 0) and (dwLength = dwSize) then
  167.             begin
  168.                Result := lpPointer;
  169.                inc(dwRefCount);
  170.                break;
  171.             end;
  172.          end;
  173.       end;
  174.       if (Result = nil) then
  175.       for i := 0 to FBuffers.Count-1 do
  176.       begin
  177.          with PMMBuffer(FBuffers[i])^ do
  178.          begin
  179.             if (dwRefCount = 0) and (dwLength >= dwSize) then
  180.             begin
  181.                Result := lpPointer;
  182.                inc(dwRefCount);
  183.                break;
  184.             end;
  185.          end;
  186.       end;
  187.       if (Result = nil) then
  188.       begin
  189.          New(P);
  190.          with P^ do
  191.          begin
  192.             lpPointer  := GlobalAllocPtr(dwFlags,dwSize);
  193.             dwLength   := dwSize;
  194.             dwRefCount := 1;
  195.          end;
  196.          FBuffers.Add(P);
  197.          Result := P^.lpPointer;
  198.       end;
  199.    finally
  200.       {$IFDEF WIN32}
  201.       FSection.Leave;
  202.       {$ENDIF}
  203.    end;
  204. end;
  205. {-- TMMAllocator --------------------------------------------------------------}
  206. procedure TMMAllocator.FreeBuffer(var lpBuffer: Pointer);
  207. var
  208.    i: integer;
  209. begin
  210.    if (lpBuffer <> nil) then
  211.    begin
  212.       {$IFDEF WIN32}
  213.       FSection.Enter;
  214.       {$ENDIF}
  215.       try
  216.          for i := 0 to FBuffers.Count-1 do
  217.          with PMMBuffer(FBuffers[i])^ do
  218.          begin
  219.             if (lpBuffer = lpPointer) then
  220.             begin
  221.                dec(dwRefCount);
  222.                lpBuffer := nil;
  223.                break;
  224.             end;
  225.          end;
  226.       finally
  227.          {$IFDEF WIN32}
  228.          FSection.Leave;
  229.          {$ENDIF}
  230.       end;
  231.    end;
  232. end;
  233. {-- TMMAllocator --------------------------------------------------------------}
  234. procedure TMMAllocator.DiscardBuffer(var lpBuffer: Pointer);
  235. var
  236.    i: integer;
  237. begin
  238.    if (lpBuffer <> nil) then
  239.    begin
  240.       {$IFDEF WIN32}
  241.       FSection.Enter;
  242.       {$ENDIF}
  243.       try
  244.          for i := 0 to FBuffers.Count-1 do
  245.          with PMMBuffer(FBuffers[i])^ do
  246.          begin
  247.             if (lpBuffer = lpPointer) then
  248.             begin
  249.                GlobalFreePtr(PMMBuffer(FBuffers[i])^.lpPointer);
  250.                Dispose(FBuffers[i]);
  251.                FBuffers.Delete(i);
  252.                lpBuffer := nil;
  253.                break;
  254.             end;
  255.          end;
  256.       finally
  257.          {$IFDEF WIN32}
  258.          FSection.Leave;
  259.          {$ENDIF}
  260.       end;
  261.    end;
  262. end;
  263. end.