diff options
author | Rob Kendrick (monotony) <rjek@rjek.com> | 2012-08-11 17:19:01 +0100 |
---|---|---|
committer | Rob Kendrick (monotony) <rjek@rjek.com> | 2012-08-11 17:19:01 +0100 |
commit | 9f2f8c34f17d60ef943bf78edc8e26a95afa3fea (patch) | |
tree | a1a0efc5780cfb5bb707a8311c92942f70924456 | |
parent | 9e9e75d685aa265e16ec12a1bad7b8f5c15a1a35 (diff) | |
download | luxio-9f2f8c34f17d60ef943bf78edc8e26a95afa3fea.tar.gz |
sio: advisory locks
-rw-r--r-- | luxio/simple.lua | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/luxio/simple.lua b/luxio/simple.lua index 81c5b11..8040e6b 100644 --- a/luxio/simple.lua +++ b/luxio/simple.lua @@ -70,6 +70,19 @@ -- myfile:nogc() -- do not close the descriptor on garbage collect -- +-- myfile:lock(mode, whence, start, len, wait) +-- Manipulates advisory locks on file regions. +-- mode is one of "r", "w", or "", for read lock, write lock, or +-- unset lock. whence, like seek, one of "cur", "set", "end". +-- start and len describe the region. If wait is set, it will +-- wait until the lock is available before claiming it and +-- returning. +-- +-- myfile:locktest(mode, whence, start, len) +-- As above, but it does not claim the lock, just checks if it +-- is available. Returns true if the lock would work, or false +-- and a pid of the holder if the lock is already taken. +-- -- myfile = sio.wrap_fd(fd[, nogc][, name]) -- wrap an fd aquired elsewhere with functions here -- fd: number of file descriptor @@ -588,6 +601,48 @@ local function seek(o, whence, offset) return r end +local function lock(o, rw, whence, offset, len, wait, test) + sio_check_mt(o) + assert(rw == "r" or rw == "w" or rw == "") + assert(seek_modes[whence]) + assert(type(offset) == "number") + assert(type(len) == "number" and len >= 0) + + local flock = { + l_whence = seek_modes[whence], + l_start = offset, + l_len = len + } + + local cmd = wait and l.F_SETLKW or l.F_SETLK + if test then cmd = l.F_GETLK end + + if rw == "r" then flock.l_type = l.F_RDLCK + elseif rw == "w" then flock.l_type = l.F_WRLCK + else flock.l_type = l.F_UNLCK + end + + local r, errno = l_fcntl(o.fd, cmd, flock) + + if r < 0 then + return err("fcntl", errno) + end + + if not test then + return true + else + if flock.l_type == l.F_UNLCK then + return true + else + return false, flock.l_pid + end + end +end + +local function locktest(o, type, whence, offset, len) + return lock(o, type, whence, offset, len, false, true) +end + local function chmod(file, mode) local mode = sio_mode_flags(mode) local r, errno = l_chmod(file, mode) @@ -916,6 +971,8 @@ descriptor_mt = { fchmod = fchmod, stat = fstat, fstat = stat, + lock = lock, + locktest = locktest, accept = accept, setsockopt = msetsockopt, |