// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.Threading; using System.Threading.Channels; namespace EpicGames.Core { /// /// Implements a which signals completion according to a reference count. /// public class ChannelWithRefCount : Channel { int _count = 1; /// /// Called when the channel is completed /// public event Action? OnComplete; /// /// Constructor /// internal ChannelWithRefCount(Channel inner) { Reader = inner.Reader; Writer = inner.Writer; } /// /// Adds a new reference to the channel /// public ChannelWithRefCount AddRef() { Interlocked.Increment(ref _count); return this; } /// /// Releases a reference to the channel /// public void Release() { if (Interlocked.Decrement(ref _count) == 0) { OnComplete?.Invoke(); Writer.Complete(); } } } /// /// Extension methods for /// public static class ChannelExtensions { /// /// Creates a channel whose completion state is controlled by a reference count /// public static ChannelWithRefCount WithRefCount(this Channel channel) => new ChannelWithRefCount(channel); } }