mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-12 09:56:12 +02:00
lazcollections: TLazThreadedQueue, allow subclasses to Lock/Unlock and access queue.
git-svn-id: trunk@63827 -
This commit is contained in:
parent
3c6130a277
commit
005fe7208d
@ -38,6 +38,8 @@ type
|
|||||||
|
|
||||||
{ TThreadedQueue }
|
{ TThreadedQueue }
|
||||||
|
|
||||||
|
{ TLazThreadedQueue }
|
||||||
|
|
||||||
generic TLazThreadedQueue<T> = class
|
generic TLazThreadedQueue<T> = class
|
||||||
private
|
private
|
||||||
FMonitor: TLazMonitor;
|
FMonitor: TLazMonitor;
|
||||||
@ -50,8 +52,13 @@ type
|
|||||||
FHasRoomEvent: PRTLEvent;
|
FHasRoomEvent: PRTLEvent;
|
||||||
FHasItemEvent: PRTLEvent;
|
FHasItemEvent: PRTLEvent;
|
||||||
FShutDown: boolean;
|
FShutDown: boolean;
|
||||||
function TryPushItem(const AItem: T): boolean;
|
function TryPushItem(const AItem: T): boolean; inline;
|
||||||
function TryPopItem(out AItem: T): boolean;
|
function TryPopItem(out AItem: T): boolean; inline;
|
||||||
|
protected
|
||||||
|
function TryPushItemUnprotected(const AItem: T): boolean;
|
||||||
|
function TryPopItemUnprotected(out AItem: T): boolean;
|
||||||
|
procedure Lock;
|
||||||
|
procedure Unlock;
|
||||||
public
|
public
|
||||||
constructor create(AQueueDepth: Integer = 10; PushTimeout: cardinal = INFINITE; PopTimeout: cardinal = INFINITE);
|
constructor create(AQueueDepth: Integer = 10; PushTimeout: cardinal = INFINITE; PopTimeout: cardinal = INFINITE);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
@ -149,16 +156,7 @@ function TLazThreadedQueue.TryPushItem(const AItem: T): boolean;
|
|||||||
begin
|
begin
|
||||||
FMonitor.Enter;
|
FMonitor.Enter;
|
||||||
try
|
try
|
||||||
result := FTotalItemsPushed-FTotalItemsPopped<FQueueSize;
|
result := TryPushItemUnprotected(AItem);
|
||||||
if result then
|
|
||||||
begin
|
|
||||||
FList[FTotalItemsPushed mod FQueueSize]:=AItem;
|
|
||||||
inc(FTotalItemsPushed);
|
|
||||||
RTLeventSetEvent(FHasItemEvent);
|
|
||||||
end;
|
|
||||||
RTLeventResetEvent(FHasRoomEvent);
|
|
||||||
if FTotalItemsPushed-FTotalItemsPopped<FQueueSize then
|
|
||||||
RTLeventSetEvent(FHasRoomEvent);
|
|
||||||
finally
|
finally
|
||||||
FMonitor.Leave;
|
FMonitor.Leave;
|
||||||
end;
|
end;
|
||||||
@ -168,21 +166,50 @@ function TLazThreadedQueue.TryPopItem(out AItem: T): boolean;
|
|||||||
begin
|
begin
|
||||||
FMonitor.Enter;
|
FMonitor.Enter;
|
||||||
try
|
try
|
||||||
result := FTotalItemsPushed>FTotalItemsPopped;
|
result := TryPopItemUnprotected(AItem);
|
||||||
if result then
|
|
||||||
begin
|
|
||||||
AItem := FList[FTotalItemsPopped mod FQueueSize];
|
|
||||||
inc(FTotalItemsPopped);
|
|
||||||
RTLeventSetEvent(FHasRoomEvent);
|
|
||||||
end;
|
|
||||||
RTLeventResetEvent(FHasItemEvent);
|
|
||||||
if FTotalItemsPushed > FTotalItemsPopped then
|
|
||||||
RTLeventSetEvent(FHasItemEvent);
|
|
||||||
finally
|
finally
|
||||||
FMonitor.Leave;
|
FMonitor.Leave;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TLazThreadedQueue.TryPushItemUnprotected(const AItem: T): boolean;
|
||||||
|
begin
|
||||||
|
result := FTotalItemsPushed-FTotalItemsPopped<FQueueSize;
|
||||||
|
if result then
|
||||||
|
begin
|
||||||
|
FList[FTotalItemsPushed mod FQueueSize]:=AItem;
|
||||||
|
inc(FTotalItemsPushed);
|
||||||
|
RTLeventSetEvent(FHasItemEvent);
|
||||||
|
end;
|
||||||
|
RTLeventResetEvent(FHasRoomEvent);
|
||||||
|
if FTotalItemsPushed-FTotalItemsPopped<FQueueSize then
|
||||||
|
RTLeventSetEvent(FHasRoomEvent);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLazThreadedQueue.TryPopItemUnprotected(out AItem: T): boolean;
|
||||||
|
begin
|
||||||
|
result := FTotalItemsPushed>FTotalItemsPopped;
|
||||||
|
if result then
|
||||||
|
begin
|
||||||
|
AItem := FList[FTotalItemsPopped mod FQueueSize];
|
||||||
|
inc(FTotalItemsPopped);
|
||||||
|
RTLeventSetEvent(FHasRoomEvent);
|
||||||
|
end;
|
||||||
|
RTLeventResetEvent(FHasItemEvent);
|
||||||
|
if FTotalItemsPushed > FTotalItemsPopped then
|
||||||
|
RTLeventSetEvent(FHasItemEvent);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLazThreadedQueue.Lock;
|
||||||
|
begin
|
||||||
|
FMonitor.Enter;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLazThreadedQueue.Unlock;
|
||||||
|
begin
|
||||||
|
FMonitor.Leave;
|
||||||
|
end;
|
||||||
|
|
||||||
constructor TLazThreadedQueue.create(AQueueDepth: Integer; PushTimeout: cardinal; PopTimeout: cardinal);
|
constructor TLazThreadedQueue.create(AQueueDepth: Integer; PushTimeout: cardinal; PopTimeout: cardinal);
|
||||||
begin
|
begin
|
||||||
FMonitor:=TLazMonitor.create;
|
FMonitor:=TLazMonitor.create;
|
||||||
|
Loading…
Reference in New Issue
Block a user