Skip to content

Atomic shutdown hook unlocks even when the lock was never acquired #101

@kreinba

Description

@kreinba

In src/main/java/co/stateful/Atomic.java, call() registers a JVM shutdown hook on line 132, before acquiring the lock. The hook on lines 123-131 unconditionally invokes this.lock.unlock(this.label) and ignores the this.locked flag, which is only set to true on line 160 after the acquisition loop succeeds.

If the JVM terminates while the acquisition loop on lines 135-159 is still waiting — DEFAULT_MAX allows up to five minutes there — the hook issues an unlock for a lock this code never held; with the default empty label set by the two-argument constructor on line 90, the server may match the unlock against another holder's empty label and release that holder's lock. Similarly, if this.lock.lock(this.label) or TimeUnit.MILLISECONDS.sleep(delay) throws before line 160, the exception bypasses the try/finally on lines 161-175, so removeShutdownHook(hook) is never called and the hook stays installed for the rest of the JVM's life, then fires a spurious unlock at shutdown.

Guard the hook body with a check on this.locked.get() before calling unlock, or register the hook only after this.locked.set(true) and remove it in a finally that wraps the acquisition loop as well.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions