public static async Task <ONIContextDisposable> ReserveContextAsync(ONIHardwareSlot slot, bool releaseWaiting = false, CancellationToken ct = default) { #if DEBUG Console.WriteLine("Context async slot " + slot + " reserved by " + (new System.Diagnostics.StackTrace()).GetFrame(1).GetMethod().DeclaringType); #endif return(await Task.Run(() => ReserveContext(slot, releaseWaiting), ct)); }
/// <summary> /// Reserve an ONI Context after it has already been opened by the appropriate call to /// <see cref="ReserveContext(ONIHardwareSlot, bool)"/> /// </summary> /// <param name="slot">Hardware slot to reserve.</param> /// <returns>Returns a <see cref="ONIContextDisposable"/> asynchronously after it has already been opened.</returns> public static async Task <ONIContextDisposable> ReserveOpenContextAsync(ONIHardwareSlot slot) { #if DEBUG Console.WriteLine("Open context async slot " + slot + " reserved by " + (new System.Diagnostics.StackTrace()).GetFrame(1).GetMethod().DeclaringType); #endif lock (openContextLock) { if (!contextWaitHandles.TryGetValue(slot.MakeKey(), out EventWaitHandle waitHandle)) { contextWaitHandles.Add(slot.MakeKey(), new EventWaitHandle(false, EventResetMode.ManualReset)); } } return(await Task.Run(() => { contextWaitHandles[slot.MakeKey()].WaitOne(); return ReserveContext(slot); })); }
public static ONIContextDisposable ReserveContext(ONIHardwareSlot slot, bool releaseWaiting = false, bool resetRunning = false) { var contextCounted = default(Tuple <ONIContextTask, RefCountDisposable>); lock (openContextLock) { if (string.IsNullOrEmpty(slot.Driver)) { contextCounted = openContexts.Count == 1 ? openContexts.Values.Single() : throw new ArgumentException("An ONI hardware slot must be specified.", nameof(slot)); } if (!openContexts.TryGetValue(slot.MakeKey(), out contextCounted)) { var configuration = LoadConfiguration(); if (configuration.Contains(slot.MakeKey())) { slot = configuration[slot.MakeKey()]; } var ctx = new ONIContextTask(slot.Driver, slot.Index); var dispose = Disposable.Create(() => { ctx.Dispose(); contextWaitHandles[slot.MakeKey()].Reset(); // Context and wait handles are removed from dictionaries together openContexts.Remove(slot.MakeKey()); contextWaitHandles.Remove(slot.MakeKey()); }); if (!contextWaitHandles.TryGetValue(slot.MakeKey(), out EventWaitHandle waitHandle)) { contextWaitHandles.Add(slot.MakeKey(), new EventWaitHandle(false, EventResetMode.ManualReset)); } if (releaseWaiting) { contextWaitHandles[slot.MakeKey()].Set(); } var referenenceCount = new RefCountDisposable(dispose); contextCounted = Tuple.Create(ctx, referenenceCount); openContexts.Add(slot.MakeKey(), contextCounted); return(new ONIContextDisposable(ctx, referenenceCount, openContextLock)); } if (resetRunning) { contextCounted.Item1.Reset(); } if (releaseWaiting) { // Will already be created if we in this portion of code. contextWaitHandles[slot.MakeKey()].Set(); } #if DEBUG Console.WriteLine("Context slot " + slot + " reserved by " + new System.Diagnostics.StackTrace().GetFrame(1).GetMethod().DeclaringType); #endif return(new ONIContextDisposable(contextCounted.Item1, contextCounted.Item2.GetDisposable(), openContextLock)); } }