Skip to content

Instantly share code, notes, and snippets.


Stephen Cleary StephenCleary

View GitHub Profile
StephenCleary / DynamicTaskWhenAll.cs
Created March 25, 2023 21:36
Dynamic Task.WhenAll
View DynamicTaskWhenAll.cs
// Developed as part of but wasn't necessary for that project.
/// <summary>
/// Similar to <see cref="Task.WhenAll{TResult}(Task{TResult}[])"/>, but allowing any number of tasks to be added, even after waiting has begun.
/// At least one task must be added, or else the <see cref="Task"/> will never complete.
/// </summary>
/// <typeparam name="TResult">The type of the result of the tasks.</typeparam>
public sealed class DynamicTaskWhenAll<TResult>
private readonly TaskCompletionSource<IReadOnlyList<TResult>> _taskCompletionSource = new();
StephenCleary /
Last active March 30, 2023 01:20
TaskGroup: Structured Concurrency for C#
StephenCleary / TaskDictionary.cs
Last active January 14, 2023 19:09
A concurrent dictionary of tasks that can be resolved by key.
View TaskDictionary.cs
public sealed class TaskDictionary<TRequest, TResult>
where TRequest : notnull
public TaskDictionary(IEqualityComparer<TRequest>? comparer = null)
_dictionary = new(comparer);
public Task<TResult> GetOrAdd(TRequest request)
StephenCleary / CancellationTokenSourceCache.cs
Last active September 6, 2022 02:29
Cache for reusing CTS instances.
View CancellationTokenSourceCache.cs
using System.Collections.Concurrent;
using System.Diagnostics;
using Nito.Disposables;
/// <summary>
/// A cache of uncanceled <see cref="CancellationTokenSource"/> instances.
/// </summary>
public sealed class CancellationTokenSourceCache
private readonly ConcurrentBag<CancellationTokenSource> _sources = new();
StephenCleary / AlignedMemoryManager.cs
Created September 3, 2022 14:45
IMemoryOwner for aligned memory
View AlignedMemoryManager.cs
public abstract class AlignedMemoryManager : MemoryManager<byte>
// Note: No finalizer; this will deliberately leak memory if never disposed.
private IntPtr _pointer;
protected static unsafe IntPtr Allocate(nuint byteCount, nuint alignment) => (IntPtr)NativeMemory.AlignedAlloc(byteCount, alignment);
public override unsafe Span<byte> GetSpan() => new((void*)_pointer, ByteCount);
StephenCleary / ProducerConsumerStream.cs
Created August 24, 2022 21:11
Producer/Consumer Stream
View ProducerConsumerStream.cs
public sealed class ProducerConsumerStream
public static Stream Create(Func<Stream, Task> producer, PipeOptions? options = null)
var pipe = new Pipe(options ?? PipeOptions.Default);
var readStream = pipe.Reader.AsStream();
var writeStream = pipe.Writer.AsStream();
return readStream;
StephenCleary / JsonExtensions.cs
Last active July 29, 2022 13:25
Simple descendant axis support for System.Text.Json. Optionally calculates the relative path of each element, producing RFC (draft 5)-compatible simple JSON paths.
View JsonExtensions.cs
public static class JsonExtensions
public static IEnumerable<JsonElement> SelfAndDescendants(this JsonElement element)
if (element.ValueKind == JsonValueKind.Undefined)
yield break;
yield return element;
if (element.ValueKind == JsonValueKind.Object)
StephenCleary / MemoryOwnerSliceExtensions.cs
Created March 31, 2022 16:54
Buffer sequence helpers
View MemoryOwnerSliceExtensions.cs
public static class MemoryOwnerSliceExtensions
public static IMemoryOwner<T> Slice<T>(this IMemoryOwner<T> owner, int start, int length)
if (start == 0 && length == owner.Memory.Length)
return owner;
return new SliceOwner<T>(owner, start, length);
StephenCleary / chat.lua
Last active March 7, 2022 14:16
Starting point for a custom TCP Wireshark dissector in Lua
View chat.lua
-- authors: Hadriel Kaplan <>, Stephen Cleary
-- Copyright (c) 2015-2022, Hadriel Kaplan, Stephen Cleary
-- This code is in the Public Domain, or the BSD (3 clause) license if Public Domain does not apply in your country.
-- Thanks to Hadriel Kaplan, who wrote the original FPM Lua script.
-- This is a starting point for defining a dissector for a custom TCP protocol.
-- This approach assumes that each message has a header that indicates the message length.
-- The code in this example uses a 4-byte header which is just a 4-byte big-endian message length,
-- and this length does not include the length of the header.
-- Modify the sections marked TODO to adjust these assumptions.
StephenCleary / FindLocalMtu.cs
Last active February 17, 2022 14:46
Find the local MTU for a hostname/IPv4/IPv6 address
View FindLocalMtu.cs
// LINQPad script
async Task Main()
byte[] LogicalAnd(byte[] x, byte[] y)
var result = new byte[x.Length];
for (int i = 0; i != x.Length; ++i)
result[i] = (byte) (x[i] & y[i]);
return result;