packages/lock: negative timeout should wait forever, adapters treat it as no-wait
Utopia\Lock\Lock::acquire() documents its contract as: 0.0 means do not wait, a negative value means wait forever.
File::acquire() returns $this->tryAcquire() for every $timeout <= 0.0, so a negative timeout is a single non-blocking attempt. Under contention a caller following the documented contract gets an immediate false, or a Contention exception from withLock(), instead of waiting. The Redis Distributed adapter and the non-coroutine Mutex and Semaphore paths have the same shape.
Either the adapters honour negative as unbounded, or the interface doc drops the negative case; pick one and cover it with a unit test on the file lock (contention from a second process or a pre-held handle, negative timeout, assert it blocks until release).
Found by review on #13718 while absorbing the package; left out of that PR because absorption does not change library behaviour. The library now lives at packages/lock, so the fix lands here and releases with bin/monorepo release lock.
Source: appwrite/appwrite