Skip to content

[Bug]: Deadlock using expireAfter #998

@aguahombre

Description

@aguahombre

Describe the bug 🐞

Create two observables that call ToObservableChangeSet with expireAfter and they may end up in deadlock.
The TaskPoolScheduler thread that handles the item expiration can end up with both scheduled expirations nested on the stack holding locks that deadlock the adding threads.

Step to reproduce

Create a console project and add this code to Program.cs

using DynamicData;
using System.Reactive.Linq;

namespace DynamicDataDeadlock;

internal class Program
{
    static void Main(string[] args)
    {
        Observable.Interval(TimeSpan.FromMilliseconds(250))
            .Select(x => new Item(x % 100))
            .ToObservableChangeSet(x => x.Value, expireAfter: _ => TimeSpan.FromSeconds(1))
            .Subscribe(x => Console.WriteLine($"{string.Join(',', x)}"));
        Observable.Interval(TimeSpan.FromMilliseconds(250))
            .Select(x => new Item2(x % 71))
            .ToObservableChangeSet(x => x.Value, expireAfter: _ => TimeSpan.FromSeconds(1))
            .Subscribe(x => Console.WriteLine($"{string.Join(',', x)}"));

        Console.ReadKey();
    }
}

internal class Item
{
    public Item(long x) => Value = x;

    public long Value { get; }
}

internal class Item2
{
    public Item2(long x) => Value = x;

    public long Value { get; }
}

Run the program in the debugger and it will eventually stop outputting lines. Pause the program and inspect the parallel threads to observe the deadlock.

Removing the console debug will reach deadlock faster.

Reproduction repository

https://github.com/aguahombre/DynamicDataDeadlock

Expected behavior

The two subscriptions run independently and never deadlock.

Screenshots 🖼️

Here is the parallel threads window showing threads 27772 and 12496 in deadlock.

Image

IDE

Visual Studio 2022

Operating system

Windows 10, Linux Bookworm

Version

17.13.6

Device

PC, RPI4B

DynamicData Version

9.2.1

Additional information ℹ️

No response

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions