opened
Aaronontheweb
username_0
```[Step 2/2] System.NullReferenceException: Object reference not set to an instance of an object.
[21:09:38]	[Step 2/2]    at Akka.Actor.HashedWheelTimerScheduler.Run() in D:\BuildAgent\work\d26c9d7f36545acd\src\core\Akka\Actor\Scheduler\HashedWheelTimerScheduler.cs:line 187
[21:09:38]	[Step 2/2]    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
[21:09:38]	[Step 2/2]    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
[21:09:38]	[Step 2/2]    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
[21:09:38]	[Step 2/2]    at System.Threading.ThreadHelper.ThreadStart()
```
Crashed the test run. Need to fix this before we ship 1.1.2.
HashedWheelTimer NRE bug
issue
created
Aaronontheweb
username_0
Figured it out - looks like a race condition that occurs when the `HashedWheelTimerScheduler` attempts to shut down.

```csharp
// return the list of unprocessedRegistrations and signal that we're finished
            _stopped.Value.TrySetResult(_unprocessedRegistrations); // <- NREs
```
comment
created
Aaronontheweb
username_0
Ooooooooooohhh subtle.

```csharp
        private Task<IEnumerable<SchedulerRegistration>> Stop()
        {
            var p = new TaskCompletionSource<IEnumerable<SchedulerRegistration>>();
#pragma warning disable 420
            if (Interlocked.CompareExchange(ref _workerState, WORKER_STATE_SHUTDOWN, WORKER_STATE_STARTED) == WORKER_STATE_STARTED
#pragma warning restore 420
                && _stopped.CompareAndSet(null, p))
            {
                // Let remaining work that is already being processed finished. The termination task will complete afterwards
                return p.Task;
            }
            return Completed;
        }
```

This half of the `if` statement executes first, which is what signals shutdown to the HWT:

```csharp
Interlocked.CompareExchange(ref _workerState, WORKER_STATE_SHUTDOWN, WORKER_STATE_STARTED) == WORKER_STATE_STARTED
```

The second half of the `if` statement may not have a chance to complete its CAS operation before the worker thread reaches the area where it depends on the value:

```csharp
&& _stopped.CompareAndSet(null, p)
```

Switching the order of operations around will fix this, so the value is always set before the loop is allowed to exit.
comment
closed
alexvaluyskiy
username_1
issue