Skip to content

Commit

Permalink
Protocol: add MethodContext.RequestAborted. (#273)
Browse files Browse the repository at this point in the history
  • Loading branch information
tmds authored Mar 16, 2024
1 parent 070ee4d commit 1efa047
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 3 deletions.
6 changes: 5 additions & 1 deletion src/Tmds.DBus.Protocol/DBusConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ public void Invoke(Exception? exception, Message message)
private Observer? _currentObserver;
private SynchronizationContext? _currentSynchronizationContext;
private TaskCompletionSource<Exception?>? _disconnectedTcs;
private CancellationTokenSource _abortedCts;
private bool _isMonitor;
private Action<Exception?, DisposableMessage>? _monitorHandler;

Expand All @@ -140,6 +141,7 @@ public DBusConnection(Connection parent, string machineId)
_matchedObservers = new();
_pathNodes = new();
_machineId = machineId;
_abortedCts = new();
}

// For tests.
Expand Down Expand Up @@ -319,7 +321,7 @@ private async void HandleMessages(Exception? exception, Message message)

if (isMethodCall)
{
methodContext = new MethodContext(_parentConnection, message); // TODO: pool.
methodContext = new MethodContext(_parentConnection, message, _abortedCts.Token); // TODO: pool.

if (message.PathIsSet)
{
Expand Down Expand Up @@ -519,6 +521,8 @@ public void Dispose()

_messageStream?.Close(disconnectReason);

_abortedCts.Cancel();

if (_pendingCalls is not null)
{
foreach (var pendingCall in _pendingCalls.Values)
Expand Down
4 changes: 3 additions & 1 deletion src/Tmds.DBus.Protocol/MethodContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ namespace Tmds.DBus.Protocol;

public class MethodContext
{
internal MethodContext(Connection connection, Message request)
internal MethodContext(Connection connection, Message request, CancellationToken requestAborted)
{
Connection = connection;
Request = request;
RequestAborted = requestAborted;
}

public Message Request { get; }
public Connection Connection { get; }
public CancellationToken RequestAborted { get; }

public bool ReplySent { get; private set; }

Expand Down
58 changes: 58 additions & 0 deletions test/Tmds.DBus.Protocol.Tests/ConnectionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,35 @@ public async Task DisconnectedException()
await Assert.ThrowsAsync<DisconnectedException>(() => proxy.ConcatAsync("hello ", "world"));
}

[Fact]
public async Task DisposeTriggersRequestAborted()
{
var connections = PairedConnection.CreatePair();
using var conn1 = connections.Item1;
using var conn2 = connections.Item2;

var handler = new WaitForCancellationHandler();
conn2.AddMethodHandler(handler);

Task pendingCall = conn1.CallMethodAsync(CreateMessage());

conn2.Dispose();

await Assert.ThrowsAsync<DisconnectedException>(() => pendingCall);

await handler.WaitForCancelledAsync().WaitAsync(new CancellationTokenSource(TimeSpan.FromSeconds(30)).Token);

MessageBuffer CreateMessage()
{
using var writer = conn1.GetMessageWriter();
writer.WriteMethodCallHeader(
path: handler.Path,
@interface: "org.any",
member: "Any");
return writer.CreateMessage();
}
}

[Theory]
[InlineData(true)]
[InlineData(false)]
Expand Down Expand Up @@ -386,6 +415,35 @@ MessageBuffer CreateAddMessage()
}
}

class WaitForCancellationHandler : IMethodHandler
{
public string Path => "/";

private readonly TaskCompletionSource _cancelled = new();

public async ValueTask HandleMethodAsync(MethodContext context)
{
try
{
while (true)
{
await Task.Delay(int.MaxValue, context.RequestAborted);
}
}
catch (OperationCanceledException)
{
_cancelled.SetResult();

throw;
}
}

public Task WaitForCancelledAsync() => _cancelled.Task;

public bool RunMethodHandlerSynchronously(Message message)
=> true;
}

class StringOperations : IMethodHandler
{
public string Path => "/tmds/dbus/tests/stringoperations";
Expand Down
2 changes: 1 addition & 1 deletion test/Tmds.DBus.Protocol.Tests/PathNodeDictionaryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ public void RemoveHandlersDoesntRemovePreExistingParentNodes()

private void AssertChildNames(string[] expectedChildNames, PathNode node)
{
var methodContext = new MethodContext(null!, null!);
var methodContext = new MethodContext(null!, null!, default);
node.CopyChildNamesTo(methodContext);
if (methodContext.IntrospectChildNameList == null)
{
Expand Down

0 comments on commit 1efa047

Please sign in to comment.