Skip to content

jaws: separate initial attribute callbacks from getter locking - #268

Merged
linkdata merged 2 commits into
mainfrom
fix/issue-264-jsvar-initial-attr-lock
Aug 9, 2026
Merged

jaws: separate initial attribute callbacks from getter locking#268
linkdata merged 2 commits into
mainfrom
fix/issue-264-jsvar-initial-attr-lock

Conversation

@linkdata

@linkdata linkdata commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • define a framework-wide unlocked callback boundary for InitialHTMLAttrHandler; the widget audit found JsVar was the only standard renderer violating it
  • split Element.ApplyGetter into tag/event application and a separate Element.ApplyInitialHTMLAttr phase, then migrate HTML, image, input, container, and JsVar renderers
  • keep JsVar tag resolution and JSON marshaling in one uninterrupted write-locked snapshot while running initial attributes after unlock
  • preserve bound-handler ordering and panic-safe lock release; document that initial attributes need not share the later getter/provider state snapshot
  • exercise real callback lock re-entry with both sync.RWMutex and the sync.Mutex bind.AsRWLocker adapter path
  • retain bind.Binder synchronization: widgets enter it unlocked, and Binder acquires its own read lock before invoking InitialHTMLAttrHook

Breaking API change

Custom renderers change from:

tagValue, attrs := elem.ApplyGetter(getter)

to:

tagValue := elem.ApplyGetter(getter)
attrs := elem.ApplyInitialHTMLAttr(getter)

The initial-attribute phase must run without an externally held lock on the getter or its source. Tag registration now completes before that explicit phase.

Verification

  • go generate ./...
  • go vet ./...
  • gofmt -l .
  • staticcheck ./...
  • golangci-lint run
  • gosec ./...
  • JAWS_REQUIRE_NODE=1 go test -race -coverprofile=coverage.out ./...
  • JAWS_REQUIRE_NODE=1 go test ./...
  • go build ./...

The Linux-only 386 leg runs in CI; macOS does not support darwin/386.

Fixes #264

@linkdata
linkdata force-pushed the fix/issue-264-jsvar-initial-attr-lock branch from 681a820 to 3854a35 Compare August 9, 2026 20:30
@linkdata linkdata changed the title ui: run JsVar initial attrs outside the binding lock jaws: separate initial attribute callbacks from getter locking Aug 9, 2026
Element.ApplyGetter now returns only the applied tag. Renderers call Element.ApplyInitialHTMLAttr as a separate unlocked phase, while JsVar retains its locked tag and JSON snapshot.
@linkdata
linkdata force-pushed the fix/issue-264-jsvar-initial-attr-lock branch from 3854a35 to b951f56 Compare August 9, 2026 20:41
@linkdata
linkdata merged commit c8a1842 into main Aug 9, 2026
7 checks passed
@linkdata
linkdata deleted the fix/issue-264-jsvar-initial-attr-lock branch August 9, 2026 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ui: JsVar rendering deadlocks in JawsInitialHTMLAttr callbacks

1 participant