Skip to content

Commit 5cd8349

Browse files
committed
Preserve OVPhysX 0.5.11 cleanup semantics
1 parent cd4899d commit 5cd8349

2 files changed

Lines changed: 60 additions & 15 deletions

File tree

source/isaaclab_ov/isaaclab_ov/physics/ovphysx_manager.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,10 @@ def _release_physx(cls) -> None:
638638
cls._destroy_ovstage()
639639
return
640640

641-
destroyed = False
641+
# Preserve the legacy 0.5.11 behavior: release both owners even when
642+
# cleanup raises. Only OVPhysX 0.6 destroy failures can remain retryable.
643+
destroy_entry_point = OVPHYSX_LIFECYCLE_ENTRY_POINTS["destroy"]
644+
release_owners = destroy_entry_point == "release"
642645
try:
643646
try:
644647
cls._close_physx_views(physx)
@@ -649,23 +652,24 @@ def _release_physx(cls) -> None:
649652
try:
650653
cls._destroy_physx(physx)
651654
except Exception:
652-
# Current OVPhysX keeps ``handle`` valid when destroy raises
653-
# before native teardown. Preserve both owners so a later close
654-
# can retry. A RuntimeError from ``handle`` means destruction
655-
# reached its terminal state even though it reported a failure.
656-
try:
657-
physx.handle
658-
except RuntimeError:
659-
destroyed = True
660-
except Exception:
661-
# An unfamiliar handle probe must not replace the
662-
# original destroy error or release either owner.
663-
destroyed = False
655+
if destroy_entry_point == "destroy":
656+
# OVPhysX 0.6 keeps ``handle`` valid when destroy raises
657+
# before native teardown. Preserve both owners so a later
658+
# close can retry. A RuntimeError from ``handle`` means
659+
# destruction reached its terminal state.
660+
try:
661+
physx.handle
662+
except RuntimeError:
663+
release_owners = True
664+
except Exception:
665+
# An unfamiliar handle probe must not replace the
666+
# original destroy error or release either owner.
667+
release_owners = False
664668
raise
665669
else:
666-
destroyed = True
670+
release_owners = True
667671
finally:
668-
if destroyed:
672+
if release_owners:
669673
cls._physx = None
670674
cls._destroy_ovstage()
671675

source/isaaclab_ov/test/physics/test_ovphysx_scene_data_backend.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,47 @@ def test_manager_rejects_missing_destroy_api(monkeypatch):
632632
OvPhysxManager._destroy_physx(SimpleNamespace())
633633

634634

635+
def test_manager_releases_legacy_owners_after_release_error(monkeypatch):
636+
"""The 0.5.11 path preserves its unconditional owner cleanup on failure."""
637+
from isaaclab_ov.physics import OvPhysxManager
638+
from isaaclab_ov.physics import ovphysx_manager as om_mod
639+
640+
events = []
641+
monkeypatch.setattr(om_mod, "OVPHYSX_LIFECYCLE_ENTRY_POINTS", {"warmup": "warmup_gpu", "destroy": "release"})
642+
643+
class FakePhysX:
644+
def reset_stage(self):
645+
events.append("reset")
646+
return 23
647+
648+
def wait_op(self, operation):
649+
events.append(("wait", operation))
650+
651+
def release(self):
652+
events.append("release")
653+
raise RuntimeError("legacy release failed")
654+
655+
class FakeStage:
656+
def destroy(self):
657+
events.append("destroy_stage")
658+
659+
previous_physx = OvPhysxManager._physx
660+
previous_ovstage = OvPhysxManager._ovstage
661+
OvPhysxManager._physx = FakePhysX()
662+
OvPhysxManager._ovstage = FakeStage()
663+
monkeypatch.setattr(OvPhysxManager, "_close_physx_views", staticmethod(lambda value: events.append("close_views")))
664+
try:
665+
with pytest.raises(RuntimeError, match="legacy release failed"):
666+
OvPhysxManager._release_physx()
667+
668+
assert OvPhysxManager._physx is None
669+
assert OvPhysxManager._ovstage is None
670+
assert events == ["close_views", "reset", ("wait", 23), "release", "destroy_stage"]
671+
finally:
672+
OvPhysxManager._physx = previous_physx
673+
OvPhysxManager._ovstage = previous_ovstage
674+
675+
635676
def test_manager_retries_current_destroy_before_releasing_owners(monkeypatch):
636677
"""A pre-teardown destroy failure preserves the runtime and stage for retry."""
637678
from isaaclab_ov.physics import OvPhysxManager

0 commit comments

Comments
 (0)