Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions v3/UNRELEASED_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ After processing, the content will be moved to the main changelog and this file
**Fixed:**
- Fix memory leak in event system during window close operations (#5678)
- Fix crash when using context menus on Linux with Wayland
- Fix deadlock EventIPCTransport.DispatchWailsEvent holding RLock during InvokeSync (#5106)

**Security:**
- Update dependencies to address CVE-2024-12345 in third-party library
17 changes: 14 additions & 3 deletions v3/pkg/application/transport_event_ipc.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,21 @@ type EventIPCTransport struct {
}

func (t *EventIPCTransport) DispatchWailsEvent(event *CustomEvent) {
// Snapshot windows under RLock
// Snapshot the window list under the lock, then release before dispatching.
// DispatchWailsEvent calls ExecJS → InvokeSync which blocks until the main
// thread executes the JS. Holding windowsLock.RLock during InvokeSync causes
// a deadlock when the main thread (or any other goroutine) needs windowsLock
// for write operations (NewWithOptions, Remove) — the pending writer blocks
// new readers, and the existing readers can't complete because InvokeSync
// needs the main thread which is waiting for the write lock.
t.app.windowsLock.RLock()
defer t.app.windowsLock.RUnlock()
for _, window := range t.app.windows {
windows := make([]Window, 0, len(t.app.windows))
for _, w := range t.app.windows {
windows = append(windows, w)
}
t.app.windowsLock.RUnlock()

for _, window := range windows {
if event.IsCancelled() {
return
}
Expand Down