summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Kendrick (monotony) <rjek@rjek.com>2012-08-11 17:19:01 +0100
committerRob Kendrick (monotony) <rjek@rjek.com>2012-08-11 17:19:01 +0100
commit9f2f8c34f17d60ef943bf78edc8e26a95afa3fea (patch)
treea1a0efc5780cfb5bb707a8311c92942f70924456
parent9e9e75d685aa265e16ec12a1bad7b8f5c15a1a35 (diff)
downloadluxio-9f2f8c34f17d60ef943bf78edc8e26a95afa3fea.tar.gz
sio: advisory locks
-rw-r--r--luxio/simple.lua57
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,