Skip to content

Fix browser shared executor cleanup deadlock#3310

Closed
neubig wants to merge 2 commits into
mainfrom
openhands/fix-browser-executor-deadlock
Closed

Fix browser shared executor cleanup deadlock#3310
neubig wants to merge 2 commits into
mainfrom
openhands/fix-browser-executor-deadlock

Conversation

@neubig
Copy link
Copy Markdown
Member

@neubig neubig commented May 20, 2026

  • A human has tested these changes.

Why

Fixes #3309. Browser executor finalizers could contend on the shared executor singleton lock even when the executor being cleaned up was not the shared singleton. On Windows, that could deadlock if cleanup happened while BrowserToolSet.create() held the non-reentrant shared lock during executor construction.

Summary

  • Construct new browser shared executors outside _shared_executor_lock and only publish them under the lock.
  • Avoid acquiring _shared_executor_lock during BrowserToolExecutor.close() unless the executor is currently the shared singleton.
  • Add regression coverage for constructing outside the shared lock and non-shared cleanup skipping the shared lock.

Issue Number

Fixes #3309

How to Test

Ran targeted browser toolset tests:

uv run pytest tests/tools/browser_use/test_browser_toolset.py -q
# 14 passed, 5 warnings in 0.09s

Ran pre-commit on changed files:

uv run pre-commit run --files openhands-tools/openhands/tools/browser_use/definition.py openhands-tools/openhands/tools/browser_use/impl.py tests/tools/browser_use/test_browser_toolset.py
# Ruff format: Passed
# Ruff lint: Passed
# PEP8 style check (pycodestyle): Passed
# Type check with pyright: Passed
# Check import dependency rules: Passed
# Check Tool subclass registration: Passed

I did not reproduce the original 30-minute Windows CI timeout locally because it is timing-sensitive and platform-specific. The new regression tests exercise the lock-ordering conditions that made the deadlock possible before this fix.

Video/Screenshots

N/A — backend test/tooling change only.

Type

  • Bug fix
  • Feature
  • Refactor
  • Breaking change
  • Docs / chore

Notes

This PR was created by an AI agent (OpenHands) on behalf of the user.


Agent Server images for this PR

GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server

Variants & Base Images

Variant Architectures Base Image Docs / Tags
java amd64, arm64 eclipse-temurin:17-jdk Link
python amd64, arm64 nikolaik/python-nodejs:python3.13-nodejs22-slim Link
golang amd64, arm64 golang:1.21-bookworm Link

Pull (multi-arch manifest)

# Each variant is a multi-arch manifest supporting both amd64 and arm64
docker pull ghcr.io/openhands/agent-server:6cebeee-python

Run

docker run -it --rm \
  -p 8000:8000 \
  --name agent-server-6cebeee-python \
  ghcr.io/openhands/agent-server:6cebeee-python

All tags pushed for this build

ghcr.io/openhands/agent-server:6cebeee-golang-amd64
ghcr.io/openhands/agent-server:6cebeee74ecec51ec0380c9bb6daa778f0e0db16-golang-amd64
ghcr.io/openhands/agent-server:openhands-fix-browser-executor-deadlock-golang-amd64
ghcr.io/openhands/agent-server:6cebeee-golang_tag_1.21-bookworm-amd64
ghcr.io/openhands/agent-server:6cebeee-golang-arm64
ghcr.io/openhands/agent-server:6cebeee74ecec51ec0380c9bb6daa778f0e0db16-golang-arm64
ghcr.io/openhands/agent-server:openhands-fix-browser-executor-deadlock-golang-arm64
ghcr.io/openhands/agent-server:6cebeee-golang_tag_1.21-bookworm-arm64
ghcr.io/openhands/agent-server:6cebeee-java-amd64
ghcr.io/openhands/agent-server:6cebeee74ecec51ec0380c9bb6daa778f0e0db16-java-amd64
ghcr.io/openhands/agent-server:openhands-fix-browser-executor-deadlock-java-amd64
ghcr.io/openhands/agent-server:6cebeee-eclipse-temurin_tag_17-jdk-amd64
ghcr.io/openhands/agent-server:6cebeee-java-arm64
ghcr.io/openhands/agent-server:6cebeee74ecec51ec0380c9bb6daa778f0e0db16-java-arm64
ghcr.io/openhands/agent-server:openhands-fix-browser-executor-deadlock-java-arm64
ghcr.io/openhands/agent-server:6cebeee-eclipse-temurin_tag_17-jdk-arm64
ghcr.io/openhands/agent-server:6cebeee-python-amd64
ghcr.io/openhands/agent-server:6cebeee74ecec51ec0380c9bb6daa778f0e0db16-python-amd64
ghcr.io/openhands/agent-server:openhands-fix-browser-executor-deadlock-python-amd64
ghcr.io/openhands/agent-server:6cebeee-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-amd64
ghcr.io/openhands/agent-server:6cebeee-python-arm64
ghcr.io/openhands/agent-server:6cebeee74ecec51ec0380c9bb6daa778f0e0db16-python-arm64
ghcr.io/openhands/agent-server:openhands-fix-browser-executor-deadlock-python-arm64
ghcr.io/openhands/agent-server:6cebeee-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-arm64
ghcr.io/openhands/agent-server:6cebeee-golang
ghcr.io/openhands/agent-server:6cebeee74ecec51ec0380c9bb6daa778f0e0db16-golang
ghcr.io/openhands/agent-server:openhands-fix-browser-executor-deadlock-golang
ghcr.io/openhands/agent-server:6cebeee-golang_tag_1.21-bookworm
ghcr.io/openhands/agent-server:6cebeee-java
ghcr.io/openhands/agent-server:6cebeee74ecec51ec0380c9bb6daa778f0e0db16-java
ghcr.io/openhands/agent-server:openhands-fix-browser-executor-deadlock-java
ghcr.io/openhands/agent-server:6cebeee-eclipse-temurin_tag_17-jdk
ghcr.io/openhands/agent-server:6cebeee-python
ghcr.io/openhands/agent-server:6cebeee74ecec51ec0380c9bb6daa778f0e0db16-python
ghcr.io/openhands/agent-server:openhands-fix-browser-executor-deadlock-python
ghcr.io/openhands/agent-server:6cebeee-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim

About Multi-Architecture Support

  • Each variant tag (e.g., 6cebeee-python) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., 6cebeee-python-amd64) are also available if needed

Co-authored-by: openhands <openhands@all-hands.dev>
@github-actions github-actions Bot added the release-note-required PR requires explicit release-note coverage for behavioral or default changes label May 20, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 20, 2026

Python API breakage checks — ✅ PASSED

Result:PASSED

Action log

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 20, 2026

REST API breakage checks (OpenAPI) — ✅ PASSED

Result:PASSED

Action log

@github-actions
Copy link
Copy Markdown
Contributor

Coverage

Coverage Report •
FileStmtsMissCoverMissing
openhands-tools/openhands/tools/browser_use
   definition.py1977362%54–57, 72–74, 76–79, 82–84, 86–88, 90–92, 96, 99–100, 103–105, 116–117, 120–121, 124–125, 130–131, 133, 180, 230, 277, 321, 368, 412, 450, 488, 531, 573, 614, 662, 712, 758, 799–801, 815–818, 820–821, 823, 827–831, 833–836, 838, 841–842, 858–859
   impl.py32120137%58–62, 64–65, 67, 69, 71–74, 76–77, 79, 81, 88, 108, 113, 119–125, 131, 137, 150–158, 165–167, 187–188, 192–193, 200–202, 214–217, 223–224, 229, 231–233, 235–236, 244–246, 248–252, 257, 296–302, 305–307, 309, 322, 359–360, 364, 375, 390–391, 396, 413, 419–420, 425, 430, 436–437, 441–442, 448–449, 457–460, 465–467, 474, 482, 500–501, 503–516, 519–532, 534–535, 541, 546–549, 557, 559, 562–563, 569–570, 575–576, 582–583, 587–588, 592–593, 597, 599–600, 602–605, 608–609, 615, 617, 619, 627–628, 632–633, 638–639, 643–644, 648–649, 654–655, 667–668, 679–680, 684–688, 702–704, 709, 714–715, 724–726
TOTAL272041364349% 

…-executor-deadlock

# Conflicts:
#	openhands-tools/openhands/tools/browser_use/definition.py
#	openhands-tools/openhands/tools/browser_use/impl.py
#	tests/tools/browser_use/test_browser_toolset.py
@github-actions github-actions Bot removed the release-note-required PR requires explicit release-note coverage for behavioral or default changes label May 24, 2026
@neubig neubig added the review-this This label triggers a PR review by OpenHands label May 25, 2026
Copy link
Copy Markdown
Collaborator

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

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

🟡 Acceptable, but this PR currently has no effective diff: GitHub reports 0 changed files, and git diff 701a8dbc...6cebeee7 is empty. If the browser cleanup fix is already on main, this PR should likely be closed as a no-op; otherwise please rebase/reapply the intended changes so they are actually reviewable.

[RISK ASSESSMENT]

  • [Overall PR] ⚠️ Risk Assessment: 🟢 LOW — merging the current head would not change code, but it also would not deliver the described fix.

VERDICT:
Needs rework: the PR needs either a real diff or closure as already superseded.


Was this automated review useful? React with 👍 or 👎 to this review to help us measure review quality.
Workflow run: https://github.com/OpenHands/software-agent-sdk/actions/runs/26411135225

Copy link
Copy Markdown
Member Author

neubig commented May 27, 2026

Closing this draft as a no-op: the PR now has 0 changed files against main, and the original fix changes are already present on the current branch/base. This was checked with gh pr diff 3310 --name-only returning no files.\n\n_This comment was created by an AI agent (OpenHands) on behalf of the user._

@neubig neubig closed this May 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review-this This label triggers a PR review by OpenHands

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows browser toolset test can deadlock around shared executor cleanup

3 participants