Skip to content

[AI Task] Preserve stack traces in Tizen sync context Send and deduplicate Send/Post dispatch - #7809

Open
JoonghyunCho wants to merge 2 commits into
mainfrom
ai-task/issue-7737
Open

[AI Task] Preserve stack traces in Tizen sync context Send and deduplicate Send/Post dispatch#7809
JoonghyunCho wants to merge 2 commits into
mainfrom
ai-task/issue-7737

Conversation

@JoonghyunCho

Copy link
Copy Markdown
Member

Summary

TizenSynchronizationContext.Send and TizenUISynchronizationContext.Send captured exceptions thrown by the callback on the main-loop thread and rethrew them on the calling thread with throw err;, which destroys the original stack trace — debugging showed only the Send call site instead of the real failure point inside the dispatched callback. This PR rethrows via ExceptionDispatchInfo.Capture(ex).Throw() (the standard BCL technique for cross-thread exception marshaling), switches the per-call rendezvous from the kernel-object ManualResetEvent to ManualResetEventSlim, and unifies the two classes' duplicated Send/Post implementations — which differed only by the GLib context flag — into one internal helper.

Changes

  • src/Tizen.Applications.Common/Tizen.Applications/TizenSynchronizationContext.csPost/Send now delegate to a new internal SynchronizationContextDispatcher class (co-located in this file, following the GSourceManager.cs convention), which holds the single shared implementation: ExceptionDispatchInfo-based rethrow, ManualResetEventSlim rendezvous, and a useTizenGlibContext parameter.
  • src/Tizen.Applications.Common/Tizen.Applications/TizenUISynchronizationContext.csPost/Send delegate to the same helper with useTizenGlibContext: true; removed the duplicated implementation and unused usings, and restored the missing trailing newline.

Mode

Refactoring

Verification

  • Build: passed (dotnet build on Tizen.Applications.Common — 0 errors)
  • Tests: N/A
  • Benchmark: skipped (sdb error: no device attached)

Public API signatures are unchanged (Send/Post overrides intact, helper is internal). The same exception object is thrown as before — only the original stack trace is now preserved.

Fixes #7737

…nd deduplicate Send/Post dispatch (Fixes #7737)

- Rethrow callback exceptions via ExceptionDispatchInfo.Capture(ex).Throw()
  instead of 'throw err', preserving the original stack trace from the
  main-loop execution of the callback.
- Replace kernel-object ManualResetEvent with ManualResetEventSlim for the
  cross-thread rendezvous in Send.
- Unify the duplicated Send/Post implementations of TizenSynchronizationContext
  and TizenUISynchronizationContext into an internal SynchronizationContextDispatcher
  helper parameterized by the GLib context flag.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@JoonghyunCho

Copy link
Copy Markdown
Member Author

⚠️ Benchmark skipped: Encountered an issue with sdb device connection/deployment/execution, so the benchmark could not be run. Manual benchmark verification is required. Error: no sdb device attached (sdb devices returned an empty list).

@github-actions github-actions Bot added the API15 label Aug 16, 2026
}, useTizenGlibContext);
}

public static void Send(SendOrPostCallback d, object state, bool useTizenGlibContext)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 [AI Review]
🟡 Suggestion: Send still deadlocks when called from the main-loop thread itself — the posted callback can never run while mre.Wait() blocks the loop (pre-existing, but now fixable in one place thanks to this centralization). WinForms/WPF contexts invoke the delegate inline in that case; doing the same here needs reliable main-thread identification, e.g. capturing the thread ID when the context is installed:

if (Environment.CurrentManagedThreadId == s_mainThreadId)
{
    d(state); // already on the loop thread; run inline instead of blocking on our own queue
    return;
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 [AI Review]
Addressed in 0d4f958. Each context captures its installing thread's ID (per-instance rather than a single static, since TizenSynchronizationContext and TizenUISynchronizationContext dispatch to different loop threads), and Send now runs the delegate inline when already on that thread.

Run Send inline when already on the target loop thread to avoid deadlocking the loop; each sync context captures its loop thread ID at installation.

Applied-AI-Comments: 3793037331
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

1 participant