[Type: Refactoring]
[Scope: src/Tizen.Messaging.Push]
[Priority: 🔴 Critical]
[Lens: Coding Guidelines, Performance]
Observation
Both async operations in the Push binding create their TaskCompletionSource<ServerResponse> with the default constructor (no TaskCreationOptions.RunContinuationsAsynchronously), yet complete it from the native push-daemon callback thread:
src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushImpl.cs:140 new TaskCompletionSource<ServerResponse>() // PushServerRegister
src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushImpl.cs:195 new TaskCompletionSource<ServerResponse>() // PushServerUnregister
The completions happen inside the native registerResult / unregisterResult callbacks:
registerResult = (Interop.PushClient.Result regResult, IntPtr msgPtr, IntPtr userData) =>
{
...
if (task.TrySetResult(response) == false) { ... } // runs continuation inline on native thread
};
Interop.PushClient.ServiceRegister(_connection, registerResult, IntPtr.Zero);
These are surfaced by the public APIs PushClient.PushServerRegister() / PushClient.PushServerUnregister() (both Task<ServerResponse>), which apps await.
Problem
Without RunContinuationsAsynchronously, TrySetResult / SetException executes the awaiter's continuation inline on the native push callback thread.
- Hazard (Coding Guidelines). The user continuation — which may call back into the push service or perform other blocking work — then runs on the native daemon's callback thread, risking callback-thread starvation, re-entrancy into the native stack, and deadlock if the continuation blocks on another push call.
- Consistency. This is the exact hazard already addressed repo-wide for WiFi / Bluetooth / NFC / Remoting / IoTConnectivity bindings. Push was never updated.
Proposed Improvement
Create both native-completed TCS instances with TaskCreationOptions.RunContinuationsAsynchronously.
Before
var task = new TaskCompletionSource<ServerResponse>();
After
var task = new TaskCompletionSource<ServerResponse>(TaskCreationOptions.RunContinuationsAsynchronously);
Apply to both sites (PushServerRegister @140, PushServerUnregister @195).
Target Files
src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushImpl.cs
Expected Impact (Quantitative Metrics)
- Inline-continuation hazard windows on the native callback thread per async push op: 1 → 0 (continuations move to the captured context / thread pool).
- 2 creation sites corrected; behavior-preserving; aligns Push with the existing repo-wide pattern.
API Compatibility Check
- Public API signature change: none (
Task<ServerResponse> PushServerRegister() / PushServerUnregister() unchanged).
- Behavior change: none for correct callers — continuations no longer run inline on the native thread; returned
Task result/exception unchanged.
- Tizen API Level floor: maintained (
TaskCreationOptions.RunContinuationsAsynchronously available since .NET Standard 2.0).
Impact Scope
- 2 TCS creation sites, single assembly (internal
PushImpl). Public wrappers in PushClient.cs (1 call site each) are unaffected.
- No cross-assembly signature impact.
Auto-generated by the TizenFX AI refactoring discovery pipeline (scan date 2026-07-12).
[Type: Refactoring]
[Scope: src/Tizen.Messaging.Push]
[Priority: 🔴 Critical]
[Lens: Coding Guidelines, Performance]
Observation
Both async operations in the Push binding create their
TaskCompletionSource<ServerResponse>with the default constructor (noTaskCreationOptions.RunContinuationsAsynchronously), yet complete it from the native push-daemon callback thread:The completions happen inside the native
registerResult/unregisterResultcallbacks:These are surfaced by the public APIs
PushClient.PushServerRegister()/PushClient.PushServerUnregister()(bothTask<ServerResponse>), which appsawait.Problem
Without
RunContinuationsAsynchronously,TrySetResult/SetExceptionexecutes the awaiter's continuation inline on the native push callback thread.Proposed Improvement
Create both native-completed TCS instances with
TaskCreationOptions.RunContinuationsAsynchronously.Before
After
Apply to both sites (
PushServerRegister@140,PushServerUnregister@195).Target Files
src/Tizen.Messaging.Push/Tizen.Messaging.Push/PushImpl.csExpected Impact (Quantitative Metrics)
API Compatibility Check
Task<ServerResponse> PushServerRegister()/PushServerUnregister()unchanged).Taskresult/exception unchanged.TaskCreationOptions.RunContinuationsAsynchronouslyavailable since .NET Standard 2.0).Impact Scope
PushImpl). Public wrappers inPushClient.cs(1 call site each) are unaffected.Auto-generated by the TizenFX AI refactoring discovery pipeline (scan date 2026-07-12).