Orginize
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Cooperative advisory **`fcntl`** lock slot + **`F_SETLKW`** waiter drain (**FIFO** per path).
|
||||
* Used by **`packages/bare-os-booter/index.js`** **`bareOsSyscall('fcntl')`**.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {{ readers: Set<string>; writer: string | null }} slot
|
||||
* @param {string} owner
|
||||
* @param {boolean} wantWrite
|
||||
*/
|
||||
export function bareOsTryAcquireCooperativeLock(slot, owner, wantWrite) {
|
||||
if (wantWrite) {
|
||||
if (slot.writer && slot.writer !== owner) return false
|
||||
if (
|
||||
slot.readers.size > 0 &&
|
||||
[...slot.readers].some((sid) => sid !== owner)
|
||||
) {
|
||||
return false
|
||||
}
|
||||
slot.readers.clear()
|
||||
slot.writer = owner
|
||||
return true
|
||||
}
|
||||
if (slot.writer && slot.writer !== owner) return false
|
||||
slot.readers.add(owner)
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown>} c
|
||||
* @param {string} lockPath
|
||||
* @param {{ resolve: (v: unknown) => void, timer: ReturnType<typeof setTimeout> | null, owner: string, wantWrite: boolean }} entry
|
||||
*/
|
||||
export function bareOsRemoveFcntlWaiter(c, lockPath, entry) {
|
||||
const m = /** @type {Record<string, unknown>} */ (c)
|
||||
const qm = m.bareOsFcntlLockWaitQueues
|
||||
if (!qm || typeof qm !== 'object') return
|
||||
const q = /** @type {unknown[]} */ (qm[lockPath])
|
||||
if (!Array.isArray(q)) return
|
||||
const i = q.indexOf(entry)
|
||||
if (i >= 0) q.splice(i, 1)
|
||||
if (q.length === 0) delete qm[lockPath]
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown>} c
|
||||
* @param {string} lockPath
|
||||
*/
|
||||
export function bareOsDrainFcntlLockWaiters(c, lockPath) {
|
||||
const locks = /** @type {Record<string, { readers: Set<string>; writer: string | null }>} */ (
|
||||
c.bareOsCooperativeLocks
|
||||
)
|
||||
const slot = locks?.[lockPath]
|
||||
if (!slot) return
|
||||
const m = /** @type {Record<string, unknown>} */ (c)
|
||||
const qm = m.bareOsFcntlLockWaitQueues
|
||||
const q = qm?.[lockPath]
|
||||
if (!Array.isArray(q) || q.length === 0) return
|
||||
while (q.length > 0) {
|
||||
const w = /** @type {{ resolve: (v: unknown) => void, timer: ReturnType<typeof setTimeout> | null, owner: string, wantWrite: boolean }} */ (
|
||||
q[0]
|
||||
)
|
||||
if (!bareOsTryAcquireCooperativeLock(slot, w.owner, w.wantWrite)) break
|
||||
q.shift()
|
||||
if (w.timer) clearTimeout(w.timer)
|
||||
w.resolve({
|
||||
ok: true,
|
||||
op: 'fcntl',
|
||||
cmd: 'F_SETLKW',
|
||||
path: lockPath,
|
||||
cooperative: true,
|
||||
locked: w.wantWrite ? 'write' : 'read',
|
||||
blockedWait: true
|
||||
})
|
||||
}
|
||||
if (q.length === 0 && qm && typeof qm === 'object') delete qm[lockPath]
|
||||
}
|
||||
Reference in New Issue
Block a user