docs.unity3d.com
    Show / Hide Table of Contents

    Struct DispatchQueue

    Double buffered thread-safe queue
    Limited by a maximum size that is passed in the constructor. This is an important for performance, to avoid memory reallocation during the work.

    In the usual case the queue works in the asynchronous mode:

    • One buffer is used for write: several threads can add new LogMessage's to it, no one can read from that buffer. That is done via Enqueue(PayloadHandle, Int64, LogLevel) method that does that under the read lock[1].
    • Second buffer is used as a read-only buffer: several sinks can read from it, without modifying anything. This is done via BeginRead() and EndRead() that enters/exits the read lock[1].
    • Second buffer also can be in an exclusive mode: Cleanup system calls BeginReadExclusive() to enter the exclusive lock[2] to make sure only it can access the read buffer at the time to release the memory used by the messages. EndReadExclusiveClearAndFlip() at the end of its work, cleaning the read buffer and flipping write/read ones, so now the write buffer is empty. Exclusive lock is unlocked after this.
    • Unity.Logging.DispatchQueue.Sort of the second (read) buffer is done under an exclusive lock[2], since it modifies the list, so it is not safe to read it.

      Another use case that is much slower - synchronous access. LockAndSortForSyncAccess(out UnsafeList<LogMessage>, out UnsafeList<LogMessage>) will put the queue under the exclusive lock[2] and return both buffers for read-write access.
      When the access is finished EndLockAfterSyncAccess() call will clear both buffers and unlock the data structure.
      This is used in the case when full synchronous flush is needed.

      Lock is used to control the thread-safe access for this data structure:
      [1] Read-lock allows several threads to take it, but only if no exclusive lock is taken. Guarantees that no exclusive lock [2] will be taken during it. Read-lock is used in situations when it is ok for multiple threads to do some kind of access, like: add new elements (see Enqueue(PayloadHandle, Int64, LogLevel)), read simultaneously without modifications (see BeginRead(), EndRead()).
      [2] Exclusive lock is used when only one thread can enter and no read-locks are taken. This lock is used to cleanup the memory of the messages (see BeginReadExclusive()) and then clear the read and swap the read and write buffers (see EndReadExclusiveClearAndFlip()).

      Note: While read buffer is in read-only BeginRead() -- EndRead() mode the write buffer still can be used to Enqueue(PayloadHandle, Int64, LogLevel) from multiple threads

    Inherited Members
    ValueType.Equals(Object)
    ValueType.GetHashCode()
    ValueType.ToString()
    Object.Equals(Object, Object)
    Object.ReferenceEquals(Object, Object)
    Object.GetType()
    Namespace: Unity.Logging
    Syntax
    [BurstCompile]
    public struct DispatchQueue : IDisposable

    Constructors

    DispatchQueue(Int32)

    Constructor for DispatchQueue.

    Declaration
    public DispatchQueue(int size)
    Parameters
    Type Name Description
    Int32 size

    Maximum length of the queue

    Remarks

    Creates two lists with the maximum amount of LogMessage's that it can process before it should be flipped.

    Properties

    IsCreated

    Is true if this struct was initialized.

    Declaration
    public readonly bool IsCreated { get; }
    Property Value
    Type Description
    Boolean

    TotalLength

    Total length of read-only and write buffers. Usually used for testing of internal state of the queue.

    Declaration
    public readonly int TotalLength { get; }
    Property Value
    Type Description
    Int32

    Methods

    BeginRead()

    Puts DispatchQueue into reading lock mode till EndRead() is called to prevent buffer flipping. Several threads can use this at the same time for reading only.

    Declaration
    public UnsafeList<LogMessage>.ParallelReader BeginRead()
    Returns
    Type Description
    UnsafeList.ParallelReader<>

    ParallelReader is returned that can be used to get all the LogMessage's from the read buffer

    BeginReadExclusive()

    Puts DispatchQueue into exclusive lock mode till EndReadExclusiveClearAndFlip() is called to prevent buffer flipping. Only one thread can access the read buffer, usually to modify it (cleanup system can free the memory that is used by messages).

    Declaration
    public UnsafeList<LogMessage>.ParallelReader BeginReadExclusive()
    Returns
    Type Description
    UnsafeList.ParallelReader<>

    ParallelReader is returned that can be used to get all the LogMessage's from read buffer, usually to dispose them

    Dispose()

    Dispose call that will call Dispose for the lists (under lock) if IsCreated is true. IDisposable

    Declaration
    public void Dispose()
    Implements
    IDisposable.Dispose()

    EndLockAfterSyncAccess()

    Unlocks DispatchQueue exclusive lock that was initiated by LockAndSortForSyncAccess(out UnsafeList<LogMessage>, out UnsafeList<LogMessage>) and clears all the buffers.

    Declaration
    public void EndLockAfterSyncAccess()

    EndRead()

    Unlocks DispatchQueue reading lock that was initiated by BeginRead()

    Declaration
    public void EndRead()

    EndReadExclusiveClearAndFlip()

    Unlocks DispatchQueue exclusive lock that was initiated by BeginReadExclusive(), clears the read buffer and swaps the buffers, so now the write buffer is empty.

    Declaration
    public void EndReadExclusiveClearAndFlip()

    Enqueue(PayloadHandle, Int64, LogLevel)

    Adds new message to the write buffer under read lock. Gets the timestamp just before adding the message to the queue.

    Declaration
    public void Enqueue(PayloadHandle payload, long stacktraceId, LogLevel logLevel)
    Parameters
    Type Name Description
    PayloadHandle payload

    PayloadHandle of the log message

    Int64 stacktraceId

    Stacktrace id of the log message or 0 if none

    LogLevel logLevel

    LogLevel of the log message

    LockAndSortForSyncAccess(out UnsafeList<LogMessage>, out UnsafeList<LogMessage>)

    Enters the exclusive lock for DispatchQueue to get the access for both buffers till EndLockAfterSyncAccess() is called.

    Declaration
    public void LockAndSortForSyncAccess(out UnsafeList<LogMessage> olderMessages, out UnsafeList<LogMessage> newerMessages)
    Parameters
    Type Name Description
    UnsafeList<LogMessage> olderMessages

    Returns the buffer with older messages (read buffer)

    UnsafeList<LogMessage> newerMessages

    Returns the buffer with newer messages (write buffer)

    Back to top
    Copyright © 2023 Unity Technologies — Terms of use
    • Legal
    • Privacy Policy
    • Cookies
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)
    "Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
    Generated by DocFX on 18 October 2023