[AI Task] Preserve stack traces in Tizen sync context Send and deduplicate Send/Post dispatch - #7809
[AI Task] Preserve stack traces in Tizen sync context Send and deduplicate Send/Post dispatch#7809JoonghyunCho wants to merge 2 commits into
Conversation
…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>
|
|
| }, useTizenGlibContext); | ||
| } | ||
|
|
||
| public static void Send(SendOrPostCallback d, object state, bool useTizenGlibContext) |
There was a problem hiding this comment.
🤖 [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;
}There was a problem hiding this comment.
🤖 [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
Summary
TizenSynchronizationContext.SendandTizenUISynchronizationContext.Sendcaptured exceptions thrown by the callback on the main-loop thread and rethrew them on the calling thread withthrow err;, which destroys the original stack trace — debugging showed only theSendcall site instead of the real failure point inside the dispatched callback. This PR rethrows viaExceptionDispatchInfo.Capture(ex).Throw()(the standard BCL technique for cross-thread exception marshaling), switches the per-call rendezvous from the kernel-objectManualResetEventtoManualResetEventSlim, and unifies the two classes' duplicatedSend/Postimplementations — which differed only by the GLib context flag — into one internal helper.Changes
src/Tizen.Applications.Common/Tizen.Applications/TizenSynchronizationContext.cs—Post/Sendnow delegate to a new internalSynchronizationContextDispatcherclass (co-located in this file, following theGSourceManager.csconvention), which holds the single shared implementation:ExceptionDispatchInfo-based rethrow,ManualResetEventSlimrendezvous, and auseTizenGlibContextparameter.src/Tizen.Applications.Common/Tizen.Applications/TizenUISynchronizationContext.cs—Post/Senddelegate to the same helper withuseTizenGlibContext: true; removed the duplicated implementation and unused usings, and restored the missing trailing newline.Mode
Refactoring
Verification
dotnet buildon Tizen.Applications.Common — 0 errors)Public API signatures are unchanged (
Send/Postoverrides intact, helper is internal). The same exception object is thrown as before — only the original stack trace is now preserved.Fixes #7737