/// <summary> /// If this Msg is of MsgType.Pool and is marked as Shared, then - subtract the given amount number from the reference-counter /// and, if that reaches zero - return the data to the shared-data pool. /// If this is not both a Pool Msg and also marked as Shared, this simply Closes this Msg. /// </summary> /// <param name="amount">the number to subtract from the internal reference-counter</param> public void RemoveReferences(int amount) { if (amount == 0) return; if (MsgType != MsgType.Pool || !IsShared) { Close(); return; } if (m_refCount.Decrement(amount) == 0) { m_refCount = null; BufferPool.Return(Data); // TODO shouldn't we set the type to uninitialised, or call clear, here? the object has a null refCount, but other methods may try to use it } }
/// <summary> /// Initialise this Msg to be of MsgType.Pool, with a data-buffer of the given number of bytes. /// </summary> /// <param name="size">the number of bytes to allocate in the data-buffer</param> public void InitPool(int size) { MsgType = MsgType.Pool; Flags = MsgFlags.None; Data = BufferPool.Take(size); Size = size; m_refCount = new AtomicCounter(); }
/// <summary> /// Initialise this Msg to be of MsgType.GC with the given data-buffer value. /// </summary> /// <param name="data">the byte-array of data to assign to the Msg's Data property</param> /// <param name="size">the number of bytes that are in the data byte-array</param> public void InitGC([NotNull] byte[] data, int size) { MsgType = MsgType.GC; Flags = MsgFlags.None; Data = data; Size = size; m_refCount = null; }
/// <summary> /// Clear this Msg to empty - ie, set MsgFlags to None, MsgType to Empty, and clear the Data. /// </summary> public void InitEmpty() { MsgType = MsgType.Empty; Flags = MsgFlags.None; Size = 0; Data = null; m_refCount = null; }
/// <summary> /// Clear the <see cref="Data"/> and set the MsgType to Invalid. /// If this is not a shared-data Msg (MsgFlags.Shared is not set), or it is shared but the reference-counter has dropped to zero, /// then return the data back to the BufferPool. /// </summary> /// <exception cref="FaultException">The object is not initialised.</exception> public void Close() { if (!IsInitialised) throw new FaultException("Cannot close an uninitialised Msg."); if (MsgType == MsgType.Pool) { // if not shared or reference counter drop to zero if (!IsShared || m_refCount.Decrement() == 0) BufferPool.Return(Data); m_refCount = null; } // Uninitialise the frame Data = null; MsgType = MsgType.Uninitialised; }
/// <summary> /// Initialise this Msg to be of MsgType.GC with the given data-buffer value. /// </summary> /// <param name="data">the byte-array of data to assign to the Msg's Data property</param> /// <param name="offset">first byte in the data array</param> /// <param name="size">the number of bytes that are in the data byte-array</param> public void InitGC( byte[] data, int offset, int size) { MsgType = MsgType.GC; Flags = MsgFlags.None; Data = data; Size = size; Offset = offset; m_refCount = null; }