Contains classes used to implement thread-safe collections.

lazCollections.pas contains classes used to implement thread-safe collections.

This file is part of the LazUtils package.

Pointer to a PRTLEvent type.

For Windows, the pointer is to a THandle type. For other platforms, the pointer is to a record type. Used to implement TWaitableSection.

PRTLEvent
Protects a section of code in multi-threaded applications.

TWaitableSection is an advanced record type used to serialize access to a section of code in a multi-threaded application. It uses a pointer to a RTL event, accessible to all interested threads, to protect its resources. When the event is set by an acquiring thread, other threads must wait until the event is reset.

TWaitableSection is used in the implementation of the Dwarf debugger for the Lazarus IDE.

PRTLEvent
Gets or creates the RTL event for the synchronization object.
RTLEventCreate InterlockedExchange
Pointer to the RTL event acquired or created in the method.
Cached event acquired or updated in the method.
Caches or Frees the RTL event for the synchronization object.
RTLEventDestroy InterlockedExchange
Cache where the RTL event is stored.
RTL event cached or destroyed in the method.
Enters the protected section, or waits until it is available.
InterlockedCompareExchange RTLEventSetEvent RTLEventWaitFor
True if the protected section has not been entered.
Cached RTL event set and monitored in the method.
Leaves the protected section.
InterlockedExchange RTLEventSetEvent
Implements a synchronization construct which provides thread-safe access to resources.

TLazMonitor is a TCriticalSection descendant which implements a synchronization construct that provides thread-safe access to resources. TLazMonitor extends the ancestor class to use a fixed number of spinlock (or busy waiting) attempts in its Acquire method. Acquire also yields CPU cycles to allow other threads to execute when fixed yield and/or sleep threshold(s) have been reached.

TLazMonitor is used in the implementation of the TLazThreadedQueue class, and in the fppkg package.

TCriticalSection
Gets the value for the DefaultSpinCount class property.
Value for the class property.
Sets the value for the DefaultSpinCount property.
New value for the property.
Gets the value for the SpinCount property.
Value for the property.
Sets the value for the SpinCount property.
New value for the property.
Constructor for the class instance.

Create is the constructor for the class instance, and sets the value in the SpinCount property to the DefaultSpinCount used in instances of the class. Create calls the inherited constructor prior to exiting from the method.

TCriticalSection.Create
Limits thread access to the calling thread.

Acquire is an overridden procedure used to limit threaded access to resources to the current calling thread. Acquire extends the inherited method to use a spinlock (or busy waiting loop) to get mutually exclusive access to resources shared between threads.

The SpinLock processing loop waits for successful completion of the Enter/Acquire method, but yields CPU cycles by calling sleep() to allow other threads to execute periodically. The internal yield/sleep thresholds are artificially low (10ms - 20ms) to avoid process scheduler/context switching conflicts for executing threads.

The inherited Acquire method is called when the method has successfully blocked access to other threads by entering the critical section.

Use the SpinCount property to determine the maximum number of iterations for the spinlock processing cycle. Use DefaultSpinCount to determine the default value used for the SpinCount property in new instances of the class.

TCriticalSection.Enter
Number of busy waiting iterations used in the monitor.

SpinCount is an Integer property which indicates the number of busy waiting iterations used in the monitor. The default value for the property is set in the Create constructor to the value in the DefaultSpinCount class property.

Set the value in SpinCount to increase or decrease the number of spinlock iterations performed in the Acquire method. The value should be kept as small as possible to avoid the overhead of process scheduler/context switching conflicts for executing threads.

Default number of busy waiting iterations used in instances of the class.

DefaultSpinCount is an Integer class property which identifies the default number of busy waiting iterations used in instances of the class. DefaultSpinCount provides the default value for the SpinCount property in new instances of the class.

Implements a First-In-First-Out queue for entries using a generic item type.

TLazFifoQueue implements a FIFO queue using a generic type for the items in the queue. A FIFO queue processes the oldest (first) entry, or head of the queue, before any subsequent items added to the buffer.

TLazFifoQueue uses an internal array to store the queue items with the type used in the specialization. The queue size (or depth) can be specified when the class instance is created, and adjusted using the Grow method.

Use the PushItem and PopItem methods to add or remove entries in the queue.

Elements in the internal array are reused when the entry is popped off of the head of the queue. The head is moved to the next element in the internal array.

Member with the total number of items removed from the FIFO queue.
Member with the total number of items stored on the FIFO queue.
Gets the value for the IsEmpty property.
True if the number of items pushed onto and popped off of the queue are the same.
Gets the value for the IsFull property.
True when the number of items remaining in the queue is the same as the QueueSize.
Constructor for the class instance.
Create
is the constructor for the class instance, and calls Grow using the value in AQueueDepth as an argument. This sets the initial size for the internal queue storage to the specified number of entries.
Number of items allocated in the internal storage for the queue.
Resizes the internal storage for the queue by the specified Delta value.

Grow is a method used to resize the internal storage for the queue by the specified Delta value.

When ADelta is a position Integer value, the size for the internal array is enlarged by the value specified number of entries. When ADelta is a negative Integer value, the internal storage is shrunk by the specified number of entries.

Grow reallocates the internal array used to store the item types for the specialization. Exisitng items in the queue are moved to the new array, and the internal storage is updated.

The value in the QueueSize property is set to the new length for the internal array.

Number of entries to add to (or remove from) the queue size.
Pushes an item of the specified type onto the tail of the queue.

Pushitem is a Boolean function used to add the value in AItem to the tail of the queue. The return value is True if the queue was not full when the method was called. No actions are performed in the method when a slot is not available in the internal storage for the queue.

PushItem stores the value in AItem at the next element in the internal array, and increments the value in the TotalItemsPushed property.

Use PopItem to remove the item at the head of the queue.

True if the specified item was added to the queue, or False when the queue is full.
Item added to the tail of the queue.
Pops an item of the specified type off of the head of the queue.

PopItem is a Boolean function used to get the value in AItem from the head of the queue. The return value is True if the queue was not empty when the method was called. No actions are performed in the method when items have not been stored in the internal storage for the queue.

PopItem retrieves the value in AItem from the storage slot at TotalItemsPopped mod QueueSize, and increments the value in the TotalItemsPopped property.

Use PushItem to add an item to the tail of the queue.

True if the item was retrieved from the queue storage, False if the queue is empty.
Item retrieved from the head of the queue.
Size (or depth) for the queue.

Indicates the number of storage slots available in the internal storage for the queue.

Use TotalItemsPushed and TotalItemsPopped to determine the utilization level for the queue. Use IsFull or IsEmpty to determine if all or none of the storage slots have been filled in the queue. Use Grow to increase (or decrease) the queue depth.

Total number of entries that have been popped off of the queue.

Used with QueueSize to determine the next position (head) for the queue. (TotalItemsPopped mod QueueSize). Used with TotalItemsPushed to determine if the queue is empty or full. The value for the property is incremented in the PopItem method after the item at the head of the queue has been retrieved from the internal storage.

Total number of entries that have been pushed onto the queue.

Used with QueueSize to determine the last position (tail) for the queue. (TotalItemsPushed mod QueueSize). Used with TotalItemsPopped to determine if the queue is empty or full. The value for the property is incremented in the PushItem method after the item has been stored in the internal storage at the tail for the queue.

Indicates if none of the internal storage slots have been used in the queue storage.

IsEmpty is a read-only Boolean property which indicates if none of the storage slots are used in the internal storage for the queue. The value is True when TotalItemsPushed and TotalItemsPopped have the same value.

Use IsFull to determine if all available storage slots are in use in the internal storage for the queue.

Indicates if all of the internal storage slots have been used in the queue storage.

IsFull is a read-only Boolean property which indicates if all of the storage slots are used in the internal storage for the queue. The value is True when TotalItemsPushed - TotalItemsPopped = QueueSize.

Use IsEmpty to determine if none of the available storage slots are in use in the internal storage for the queue.

Implements a thread-safe FIFO queue for items of a generic type.

TLazThreadedQueue is generic class which implements a thread-safe FIFO queue using a generic type for its items. The class requires specialization to specify the type stored in the items for the queue. For example:

TLazThreadedQueueString = specialize TLazThreadedQueue<String>; TLazThreadedQueueInt = specialize TLazThreadedQueue<Integer>; TLazThreadedQueueRect = specialize TLazThreadedQueue<TRectangle>;

TLazThreadedQueue uses an internal TLazMonitor member to synchronize access to resources in the queue between executing threads. Methods in the class which require thread-safe access use the monitor to enable/disable resource protection. Items in the queue are maintained using the PushItem, PopItem, and PopItemTimeout methods. Properties are provided to determine the size of the queue, and the number of items added or removed.

TLazThreadedQueue specializations are used in the implementation of the fpdserver component, and its integration into the Lazarus IDE.

TODO: Discuss the RTL events and their usage.

Type used to the specialize the internal TLazFifoQueue instance for the class.
Gets the value for the QueueSize property.
Value for the property.
Gets the value for the TotalItemsPopped property.
Value for the property.
Gets the value for the TotalItemsPushed property.
Value for the property.
Tries to add the specified item to the queue.

TryPushItem is a Boolean function which tries to add the item specified in AItem to the internal storage for the queue. The return value is True if the item was successfully added in the method.

TryPushItem is used in the implementation of the PushItem method. Use PushItem to add an item to the thread-safe queue.

True if the item was added successfully.
Item added to the queue in the method.
Tries to remove the next item in the thread-safe queue.
True if an item was successfully removed from the queue.
Item removed from the queue in the method.
Tries to push an item onto the queue without resource protection.

Sets and resets internal RTL events when the item was successfully pushed, and when queue space is available.

Tries to pop an item off of the queue without resource protection.

Sets and resets internal RTL events when the item was successfully popped, and when queue space is available.

Enters the Monitor used for resource protection.
Leaves the Monitor used for resource protection.
Creates the TLazTypedFifoQueue instance used in the class.
TLazTypedFifoQueue instance used in the class.
Initial setting for the queue depth (or size).
Provides access to the TLazTypedFifoQueue instance used in the class.
Constructor for the class instance.

Create is the constructor for the class instance. Create allocates internal resources used to implement the thread-safe queue, and sets the default values for its properties.

The value in AQueueDepth is passed as an argument to the Grow method to allocate the internal storage for the queue.

PushTimeout and PopTimeout indicate the number of milliseconds (or ticks) to wait for successful completion of enqueue or dequeue requests, and are assigned as the default value for the corresponding internal members in the class instance.

Indicates the maximum number of items that can be stored in the thread-safe queue.
Number of ticks (milliseconds) to wait for successful completion of an enqueue request.
Number of ticks (milliseconds) to wait for successful completion of a dequeue request.
Destructor for the class instance.

Destroy is the destructor for the class instance. Destroy calls the private DoShutDown method to free internal resources allocated in the class instance. Destroy calls the inherited destructor prior to exiting from the method.

TCriticalSection.Destroy
Expands (or shrinks) the allocated storage for the queue by the specified size.

Grow is a method used to resize the internal storage for the queue by the specified Delta value.

When ADelta is a position Integer value, the size for the internal array is enlarged by the value specified number of entries. When ADelta is a negative Integer value, the internal storage is shrunk by the specified number of entries.

Grow reallocates the internal array used to store the item types for the specialization. Exisitng items in the queue are moved to the new array, and the internal storage is updated.

The value in the QueueSize property is set to the new length for the internal array.

Grows uses resource protection when calling the Grow method in the internal TLazFifoQueue instance in the class.

Value used to increase the size of the queue.
Adds the specified item to the queue.

PushItem is a TWaitResult function used to add the item specified in AItem to the thread-safe queue.

PushItem uses the value in the internal PushTimeout member to determine if a timeout is in effect for the enqueue request. When PushTimeout contains INFINITE, a timeout is not used for the operation. Instead, the request waits for an RTL Event that indicates room is available in the internal storage for the queue.

When PushTimeout contains 0, the request will timeout after the first failed attempt to add the specified item to the queue.

When ShutDown contains True, the return value is updated to indicate that the request should be abandoned.

The return value contains a TWaitResult enumeration value that indicates the status for the enqueue request. See TWaitResult for more information about enumeration values and their meanings.

TWaitResult RTLEventWaitFor
Contains the status for the enqueue request.
Item added to the storage for the queue.
Pops the next item from the queue.

PopItem is a TWaitResult function used remove the next item available in the thread-safe queue. PopItem calls the PopItemTimeout method using the value in the PopTimeout property as an argument.

AItem is an output variable that is updated with the item removed from the queue in the method.

The return value contains a TWaitResult enumeration value that indicates the status for the dequeue request. See TWaitResult for more information about enumeration values and their meanings.

TWaitResult
Contains the status for the dequeue request.
Item removed from the queue.
Pops an item off the queue with a timeout value.

PopItemTimeout is a TWaitResult function used to remove the next available item in the queue with a timeout in effect for the dequeue operation.

AItem is an output parameter used to return the item removed from the thread-safe queue.

Timeout specifies the number of ticks (milliseconds) to wait for successful completion of the dequeue request. When Timeout contains the value INFINITE, a timeout is not used in the method. Instead, an internal RTL event is signalled to wait for an available item in the queue. When Timeout contains 0, the request returns immediately after the first failed attempt to dequeue an item.

When ShutDown contains True, the method updates the return value to indicate that the request was abandoned.

The return value contains a TWaitResult enumeration value that indicates the status for the dequeue request. See TWaitResult for more information about enumeration values and their meanings.

TWaitResult
Contains the status for the dequeue request.
Item removed from the queue.
Maximum number of ticks to wait for the item to be removed from the queue.
Performs actions required when the thread-safe queue is freed.

DoShutDown is a procedure used to perform actions required when the instance of the thread-safe queue is freed. DoShutDown sets the value in the ShutDown property to True to signal executing threads that the queue is being freed. In additional, RTL events are set/reset to reflect the state for the internal storage in the queue.

DoShutDown is called prior to freeing resources for the class instance in the Destroy method.

Number of storage slots for items in the queue.

QueueSize is a read-only Integer property that indicates the number of storage slots available in the internal storage for the queue. The initial value for QueueSize is set using an argument passed to the constructor.

Use the Grow method to adjust the number of slots in the internal storage for the queue.

Values in the TotalItemsPushed, TotalItemsPopped, and QueueSize properties determine if storage and/or items are available in the queue.

Total number of items removed from the queue.

TotalItemsPopped is a read-only QWord property that indicates the total number of items removed from the queue. The value in the internal member for the property is incremented each time the PopItem or PopItemTimeout method is completed successfully.

Values in TotalItemsPopped and TotalItemsPushed determine whether items are available in the queue. Use TotalItemsPushed to determine the number of items added to the queue.

Total number of items added to the queue.

TotalItemsPushed is a read-only QWord property that indicates the total number of items added to the queue. The value in the internal member for the property is incremented each time the PushItem method is completed successfully.

Values in TotalItemsPushed and TotalItemsPopped determine whether items are available in the queue. Use TotalItemsPopped to determine the total number of items removed from the queue.

Indicates if the DoShutdown method has been called but not finished.

ShutDown is a read-only Boolean property which indicates if the DoShutDown method has been called, but not yet completed, for the class instance. The value in ShutDown is used in the PushItem and PopItemTimeout methods to determine the status for the respective requests. The value wrAbandoned is returned from these methods when ShutDown contains True.

The value in ShutDown is set to True in the DoShutDown method.

TWaitResult