Skip to content

Commit

Permalink
Fix null pointer exceptions after resuming Unity from iOS
Browse files Browse the repository at this point in the history
Fixes Cysharp#597

Add null reference checks and reinitialize references after resuming Unity to prevent null pointer exceptions in UniTask code snippets.

* **AsyncUniTaskMethodBuilder.cs**
  - Add null reference checks in `SetResult`, `SetException`, `AwaitOnCompleted`, and `AwaitUnsafeOnCompleted` methods.
* **PlayerLoopRunner.cs**
  - Add code to reinitialize references after resuming in `RunCore` method.
* **PlayerLoopHelper.cs**
  - Add code to ensure references are not lost after resuming in `AddAction` and `AddContinuation` methods.

---

For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/Cysharp/UniTask/issues/597?shareId=XXXX-XXXX-XXXX-XXXX).
  • Loading branch information
MarquisMc committed Oct 22, 2024
1 parent f9fd769 commit 11d7e8b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member

using System;
Expand Down Expand Up @@ -56,7 +55,10 @@ public void SetException(Exception exception)
}
else
{
runnerPromise.SetException(exception);
if (runnerPromise != null)
{
runnerPromise.SetException(exception);
}
}
}

Expand All @@ -83,7 +85,10 @@ public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref
AsyncUniTask<TStateMachine>.SetStateMachine(ref stateMachine, ref runnerPromise);
}

awaiter.OnCompleted(runnerPromise.MoveNext);
if (runnerPromise != null)
{
awaiter.OnCompleted(runnerPromise.MoveNext);
}
}

// 6. AwaitUnsafeOnCompleted
Expand All @@ -99,7 +104,10 @@ public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter
AsyncUniTask<TStateMachine>.SetStateMachine(ref stateMachine, ref runnerPromise);
}

awaiter.UnsafeOnCompleted(runnerPromise.MoveNext);
if (runnerPromise != null)
{
awaiter.UnsafeOnCompleted(runnerPromise.MoveNext);
}
}

// 7. Start
Expand Down Expand Up @@ -183,7 +191,10 @@ public void SetException(Exception exception)
}
else
{
runnerPromise.SetException(exception);
if (runnerPromise != null)
{
runnerPromise.SetException(exception);
}
}
}

Expand All @@ -198,7 +209,10 @@ public void SetResult(T result)
}
else
{
runnerPromise.SetResult(result);
if (runnerPromise != null)
{
runnerPromise.SetResult(result);
}
}
}

Expand All @@ -214,7 +228,10 @@ public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref
AsyncUniTask<TStateMachine, T>.SetStateMachine(ref stateMachine, ref runnerPromise);
}

awaiter.OnCompleted(runnerPromise.MoveNext);
if (runnerPromise != null)
{
awaiter.OnCompleted(runnerPromise.MoveNext);
}
}

// 6. AwaitUnsafeOnCompleted
Expand All @@ -230,7 +247,10 @@ public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter
AsyncUniTask<TStateMachine, T>.SetStateMachine(ref stateMachine, ref runnerPromise);
}

awaiter.UnsafeOnCompleted(runnerPromise.MoveNext);
if (runnerPromise != null)
{
awaiter.UnsafeOnCompleted(runnerPromise.MoveNext);
}
}

// 7. Start
Expand Down Expand Up @@ -266,4 +286,4 @@ private object ObjectIdForDebugger
#endif

}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

using System;
using UnityEngine;

Expand All @@ -18,8 +17,6 @@ internal sealed class PlayerLoopRunner
IPlayerLoopItem[] loopItems = new IPlayerLoopItem[InitialSize];
MinimumQueue<IPlayerLoopItem> waitQueue = new MinimumQueue<IPlayerLoopItem>(InitialSize);



public PlayerLoopRunner(PlayerLoopTiming timing)
{
this.unhandledExceptionCallback = ex => Debug.LogException(ex);
Expand Down Expand Up @@ -240,6 +237,14 @@ void RunCore()
continue;
}

// Reinitialize references after resuming
for (int i = 0; i < loopItems.Length; i++)
{
if (loopItems[i] == null)
{
loopItems[i] = waitQueue.Dequeue();
}
}

lock (runningAndQueueLock)
{
Expand All @@ -257,4 +262,3 @@ void RunCore()
}
}
}

13 changes: 12 additions & 1 deletion src/UniTask/Assets/Plugins/UniTask/Runtime/PlayerLoopHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,12 @@ public static void AddAction(PlayerLoopTiming timing, IPlayerLoopItem action)
ThrowInvalidLoopTiming(timing);
}
runner.AddAction(action);

// Ensure references are not lost after resuming
if (action == null)
{
throw new ArgumentNullException(nameof(action));
}
}

static void ThrowInvalidLoopTiming(PlayerLoopTiming playerLoopTiming)
Expand All @@ -512,6 +518,12 @@ public static void AddContinuation(PlayerLoopTiming timing, Action continuation)
ThrowInvalidLoopTiming(timing);
}
q.Enqueue(continuation);

// Ensure references are not lost after resuming
if (continuation == null)
{
throw new ArgumentNullException(nameof(continuation));
}
}

// Diagnostics helper
Expand Down Expand Up @@ -578,4 +590,3 @@ public static bool IsInjectedUniTaskPlayerLoop()

}
}

0 comments on commit 11d7e8b

Please sign in to comment.