mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-09-13 04:03:30 +00:00
37 lines
3.2 KiB
Markdown
37 lines
3.2 KiB
Markdown
# POSIX flock behavior
|
|
|
|
`tryLockExclusive(fd)` returns a promise for one `flock(fd, LOCK_EX | LOCK_NB)` attempt. The syscall runs off the JavaScript thread. The caller keeps the descriptor open through completion; the binding does not open, duplicate, or close it. It exposes neither a blocking-wait API nor a shared-lock API.
|
|
|
|
## Behavior tests
|
|
|
|
The [native tests](../test/flock.test.js) exercise real descriptors and independent processes. The [C oracle](../test/fixtures/flock-oracle.c) calls the operating system directly, independently of `system.node`.
|
|
|
|
| Condition | Required observation |
|
|
|---|---|
|
|
| No conflicting lock | Acquisition resolves to void |
|
|
| Same open file description acquires again | Acquisition succeeds without a second ownership record |
|
|
| Separate opens of the same file | Exactly one exclusive holder; the contender rejects with EAGAIN/EWOULDBLOCK |
|
|
| Different files | Both can be locked |
|
|
| Independent C flock holder | The addon cannot acquire, and the C oracle cannot acquire while the addon holds the lock |
|
|
| A shared flock holder | The addon's exclusive attempt conflicts |
|
|
| Holder remains live | A nonblocking attempt reports contention before the holder unlocks |
|
|
| Ordinary read/write by another process | Access is allowed: flock is advisory, not an I/O permission mechanism |
|
|
| One unrelated descriptor closes | The actual holder keeps its lock |
|
|
| A descriptor inherited by a child remains open | Closing the parent's descriptor does not release the shared open file description's lock |
|
|
| Last owning descriptor closes | An already-open contender can acquire |
|
|
| Holder process exits or is killed | Acquisition succeeds after process exit, without a stale-lock timeout |
|
|
| Invalid descriptor | The promise rejects with EBADF and positive errno |
|
|
| Native argument validation fails | The JavaScript entry returns a rejected promise without throwing synchronously |
|
|
| Native completion callback | It receives zero or the request's positive errno asynchronously |
|
|
| Native completion callback throws | The exception reaches Node's uncaught-exception handler |
|
|
| Concurrent success/failure calls | Each completion receives its own syscall errno |
|
|
| Worker environment terminates before or during its callback | Native work and cleanup reach completion without taking ownership of the caller's descriptor |
|
|
|
|
Tests synchronize through IPC or flushed line protocols and await process exit before asserting crash recovery. They do not use fixed sleeps or a millisecond performance threshold to prove nonblocking behavior. The syscall oracle is built only for tests and never included in a published platform package.
|
|
|
|
## Limits
|
|
|
|
Locks belong to open file descriptions and follow the host filesystem's flock semantics. Removing or replacing a pathname does not transfer a lock to the replacement inode; the JSONL backend separately checks inode identity. Network filesystems can have different or unsupported lock semantics. Windows does not use this API and retains its existing semaphore implementation.
|
|
|
|
Node-API compatibility tests reuse the same platform addon under different Node versions. They complement these syscall tests; loading a binary alone does not prove correct locking behavior.
|