summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2019-07-25 00:45:28 +0800
committerruki <[email protected]>2019-07-24 22:32:48 +0800
commit6634524cfdccf13e50a6fdbf55678832c530f908 (patch)
treeadc9f642278243eef51b008855184b16dbe34f19
parent493817cfeca5b40401e99ee857a96b3defa81421 (diff)
add file lock and unlock
-rw-r--r--core/src/xmake/io/file.h12
-rw-r--r--core/src/xmake/io/file_path.c31
-rw-r--r--core/src/xmake/io/filelock.h25
-rw-r--r--core/src/xmake/io/filelock___tostring.c2
-rw-r--r--core/src/xmake/io/filelock_close___gc.c11
-rw-r--r--core/src/xmake/io/filelock_lock.c72
-rw-r--r--core/src/xmake/io/filelock_path.c27
-rw-r--r--core/src/xmake/io/filelock_trylock.c72
-rw-r--r--core/src/xmake/io/filelock_unlock.c57
-rw-r--r--core/src/xmake/machine.c12
-rw-r--r--core/src/xmake/makefile3
-rw-r--r--xmake/core/sandbox/modules/io.lua27
12 files changed, 300 insertions, 51 deletions
diff --git a/core/src/xmake/io/file.h b/core/src/xmake/io/file.h
index 28ecc77ae..69555b393 100644
--- a/core/src/xmake/io/file.h
+++ b/core/src/xmake/io/file.h
@@ -38,14 +38,13 @@
#define xm_io_file_is_tty(file) (!!((file)->type & XM_IO_FILE_FLAG_TTY))
#define xm_io_file_is_closed(file) (xm_io_file_is_closed_file(file) || xm_io_file_is_closed_std(file))
-#define xm_io_file_udata "XM_IO_FILE*"
+// the file udata type
+#define xm_io_file_udata "io._file*"
-#define xm_io_file_return_success() \
- do \
- { \
- return 1; \
- } while (0)
+// return file success
+#define xm_io_file_return_success() do { return 1; } while (0)
+// return file error with reason
#define xm_io_file_return_error(lua, file, reason) \
do \
{ \
@@ -54,6 +53,7 @@
return 2; \
} while (0)
+// return file closed error
#define xm_io_file_return_error_closed(lua) \
do \
{ \
diff --git a/core/src/xmake/io/file_path.c b/core/src/xmake/io/file_path.c
index 1fcdb752a..fab2b156b 100644
--- a/core/src/xmake/io/file_path.c
+++ b/core/src/xmake/io/file_path.c
@@ -14,45 +14,42 @@
*
* Copyright (C) 2015 - 2019, TBOOX Open Source Group.
*
- * @author ruki
- * @file filelock_path.c
+ * @author OpportunityLiu
+ * @file file_path.c
*
*/
/* //////////////////////////////////////////////////////////////////////////////////////
* trace
*/
-#define TB_TRACE_MODULE_NAME "filelock_path"
+#define TB_TRACE_MODULE_NAME "file_path"
#define TB_TRACE_MODULE_DEBUG (0)
/* //////////////////////////////////////////////////////////////////////////////////////
* includes
*/
-#include "filelock.h"
+#include "file.h"
+#include "prefix.h"
/* //////////////////////////////////////////////////////////////////////////////////////
* implementation
*/
-/* filelock:path()
+/* file:path()
*/
-tb_int_t xm_io_filelock_path(lua_State* lua)
+tb_int_t xm_io_file_path(lua_State* lua)
{
// check
tb_assert_and_check_return_val(lua, 0);
- // this lock has been closed?
- xm_io_filelock_t* lock = xm_io_get_filelock(lua);
- if (!lock->is_opened)
- {
- lua_pushnil(lua);
- lua_pushliteral(lua, "file lock has been closed!");
- return 2;
- }
+ // this file has been closed?
+ xm_io_file_t* file = xm_io_getfile(lua);
+ if (xm_io_file_is_closed(file))
+ xm_io_file_return_error_closed(lua);
else
{
- // return lock path
- lua_pushstring(lua, lock->path);
- return 1;
+ // return file path
+ lua_pushstring(lua, file->path);
+ xm_io_file_return_success();
}
}
diff --git a/core/src/xmake/io/filelock.h b/core/src/xmake/io/filelock.h
index e7e3536e8..f3c2a8f43 100644
--- a/core/src/xmake/io/filelock.h
+++ b/core/src/xmake/io/filelock.h
@@ -29,7 +29,30 @@
/* //////////////////////////////////////////////////////////////////////////////////////
* macros
*/
-#define xm_io_filelock_udata "XM_IO_FILE_LOCK*"
+
+// the file lock udata type
+#define xm_io_filelock_udata "io._filelock*"
+
+// return lock success
+#define xm_io_filelock_return_success() do { return 1; } while (0)
+
+// return lock error with reason
+#define xm_io_filelock_return_error(lua, lock, reason) \
+ do \
+ { \
+ lua_pushnil(lua); \
+ lua_pushfstring(lua, "error: %s (%s)", reason, lock->name); \
+ return 2; \
+ } while (0)
+
+// return closed error
+#define xm_io_filelock_return_error_closed(lua) \
+ do \
+ { \
+ lua_pushnil(lua); \
+ lua_pushliteral(lua, "error: file lock has been closed"); \
+ return 2; \
+ } while (0)
/* //////////////////////////////////////////////////////////////////////////////////////
* types
diff --git a/core/src/xmake/io/filelock___tostring.c b/core/src/xmake/io/filelock___tostring.c
index 8002b9eb3..417484c36 100644
--- a/core/src/xmake/io/filelock___tostring.c
+++ b/core/src/xmake/io/filelock___tostring.c
@@ -45,6 +45,6 @@ tb_int_t xm_io_filelock___tostring(lua_State* lua)
// get lock name as string
xm_io_filelock_t* lock = xm_io_get_filelock(lua);
lua_pushstring(lua, lock->name);
- return 1;
+ xm_io_filelock_return_success();
}
diff --git a/core/src/xmake/io/filelock_close___gc.c b/core/src/xmake/io/filelock_close___gc.c
index cadc02299..a2f263100 100644
--- a/core/src/xmake/io/filelock_close___gc.c
+++ b/core/src/xmake/io/filelock_close___gc.c
@@ -46,14 +46,9 @@ static tb_int_t xm_io_filelock_close_impl(lua_State* lua, tb_bool_t allow_closed
if (allow_closed_lock)
{
lua_pushboolean(lua, tb_true);
- return 1;
- }
- else
- {
- lua_pushnil(lua);
- lua_pushliteral(lua, "file lock has been closed");
- return 2;
+ xm_io_filelock_return_success();
}
+ else xm_io_filelock_return_error_closed(lua);
}
// check
@@ -76,7 +71,7 @@ static tb_int_t xm_io_filelock_close_impl(lua_State* lua, tb_bool_t allow_closed
// close ok
lua_pushboolean(lua, tb_true);
- return 1;
+ xm_io_filelock_return_success();
}
/* //////////////////////////////////////////////////////////////////////////////////////
diff --git a/core/src/xmake/io/filelock_lock.c b/core/src/xmake/io/filelock_lock.c
new file mode 100644
index 000000000..638cdd4fb
--- /dev/null
+++ b/core/src/xmake/io/filelock_lock.c
@@ -0,0 +1,72 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file filelock_lock.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "filelock_lock"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "filelock.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+
+/* lock file
+ *
+ * exclusive lock: filelock:lock("/xxxx/filelock")
+ * exclusive lock: filelock:lock("/xxxx/filelock", "ex")
+ * shared lock: filelock:lock("/xxxx/filelock", "sh")
+ */
+tb_int_t xm_io_filelock_lock(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // get lock mode
+ tb_char_t const* modestr = luaL_optstring(lua, 2, "ex");
+ tb_assert_and_check_return_val(modestr, 0);
+
+ // this lock has been closed?
+ xm_io_filelock_t* lock = xm_io_get_filelock(lua);
+ if (!lock->is_opened)
+ xm_io_filelock_return_error_closed(lua);
+ else
+ {
+ // is exclusive mode?
+ tb_bool_t is_exclusive = tb_true;
+ if (!tb_strcmp(modestr, "sh")) is_exclusive = tb_false;
+ else if (tb_strcmp(modestr, "ex"))
+ xm_io_filelock_return_error(lua, lock, "invalid lock mode!");
+
+ // lock it
+ if (tb_filelock_enter(lock->lock_ref, is_exclusive? TB_FILELOCK_MODE_EX : TB_FILELOCK_MODE_SH))
+ {
+ lua_pushboolean(lua, tb_true);
+ xm_io_filelock_return_success();
+ }
+ else xm_io_filelock_return_error(lua, lock, "lock failed!");
+ }
+}
diff --git a/core/src/xmake/io/filelock_path.c b/core/src/xmake/io/filelock_path.c
index e4221b6b9..1ab0fe932 100644
--- a/core/src/xmake/io/filelock_path.c
+++ b/core/src/xmake/io/filelock_path.c
@@ -14,42 +14,41 @@
*
* Copyright (C) 2015 - 2019, TBOOX Open Source Group.
*
- * @author OpportunityLiu
- * @file file_path.c
+ * @author ruki
+ * @file filelock_path.c
*
*/
/* //////////////////////////////////////////////////////////////////////////////////////
* trace
*/
-#define TB_TRACE_MODULE_NAME "file_path"
+#define TB_TRACE_MODULE_NAME "filelock_path"
#define TB_TRACE_MODULE_DEBUG (0)
/* //////////////////////////////////////////////////////////////////////////////////////
* includes
*/
-#include "file.h"
-#include "prefix.h"
+#include "filelock.h"
/* //////////////////////////////////////////////////////////////////////////////////////
* implementation
*/
-/* file:path()
+/* lock:path()
*/
-tb_int_t xm_io_file_path(lua_State* lua)
+tb_int_t xm_io_filelock_path(lua_State* lua)
{
// check
tb_assert_and_check_return_val(lua, 0);
- // this file has been closed?
- xm_io_file_t* file = xm_io_getfile(lua);
- if (xm_io_file_is_closed(file))
- xm_io_file_return_error_closed(lua);
+ // this lock has been closed?
+ xm_io_filelock_t* lock = xm_io_get_filelock(lua);
+ if (!lock->is_opened)
+ xm_io_filelock_return_error_closed(lua);
else
{
- // return file path
- lua_pushstring(lua, file->path);
- return 1;
+ // return lock path
+ lua_pushstring(lua, lock->path);
+ xm_io_filelock_return_success();
}
}
diff --git a/core/src/xmake/io/filelock_trylock.c b/core/src/xmake/io/filelock_trylock.c
new file mode 100644
index 000000000..4195b2312
--- /dev/null
+++ b/core/src/xmake/io/filelock_trylock.c
@@ -0,0 +1,72 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file filelock_trylock.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "filelock_trylock"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "filelock.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+
+/* try to lock file
+ *
+ * exclusive lock: filelock:trylock("/xxxx/filelock")
+ * exclusive lock: filelock:trylock("/xxxx/filelock", "ex")
+ * shared lock: filelock:trylock("/xxxx/filelock", "sh")
+ */
+tb_int_t xm_io_filelock_trylock(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // get lock mode
+ tb_char_t const* modestr = luaL_optstring(lua, 2, "ex");
+ tb_assert_and_check_return_val(modestr, 0);
+
+ // this lock has been closed?
+ xm_io_filelock_t* lock = xm_io_get_filelock(lua);
+ if (!lock->is_opened)
+ xm_io_filelock_return_error_closed(lua);
+ else
+ {
+ // is exclusive mode?
+ tb_bool_t is_exclusive = tb_true;
+ if (!tb_strcmp(modestr, "sh")) is_exclusive = tb_false;
+ else if (tb_strcmp(modestr, "ex"))
+ xm_io_filelock_return_error(lua, lock, "invalid lock mode!");
+
+ // try to lock it
+ if (tb_filelock_enter_try(lock->lock_ref, is_exclusive? TB_FILELOCK_MODE_EX : TB_FILELOCK_MODE_SH))
+ {
+ lua_pushboolean(lua, tb_true);
+ xm_io_filelock_return_success();
+ }
+ else xm_io_filelock_return_error(lua, lock, "trylock failed!");
+ }
+}
diff --git a/core/src/xmake/io/filelock_unlock.c b/core/src/xmake/io/filelock_unlock.c
new file mode 100644
index 000000000..266aab205
--- /dev/null
+++ b/core/src/xmake/io/filelock_unlock.c
@@ -0,0 +1,57 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file filelock_unlock.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "filelock_unlock"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "filelock.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+
+// filelock:unlock()
+tb_int_t xm_io_filelock_unlock(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // this lock has been closed?
+ xm_io_filelock_t* lock = xm_io_get_filelock(lua);
+ if (!lock->is_opened)
+ xm_io_filelock_return_error_closed(lua);
+ else
+ {
+ // unlock it
+ if (tb_filelock_leave(lock->lock_ref))
+ {
+ lua_pushboolean(lua, tb_true);
+ xm_io_filelock_return_success();
+ }
+ else xm_io_filelock_return_error(lua, lock, "unlock failed!");
+ }
+}
diff --git a/core/src/xmake/machine.c b/core/src/xmake/machine.c
index 66bf45c8b..78bddbc2b 100644
--- a/core/src/xmake/machine.c
+++ b/core/src/xmake/machine.c
@@ -108,6 +108,9 @@ tb_int_t xm_io_file___gc(lua_State* lua);
// the filelock functions
tb_int_t xm_io_filelock_path(lua_State* lua);
+tb_int_t xm_io_filelock_lock(lua_State* lua);
+tb_int_t xm_io_filelock_unlock(lua_State* lua);
+tb_int_t xm_io_filelock_trylock(lua_State* lua);
tb_int_t xm_io_filelock_close(lua_State* lua);
tb_int_t xm_io_filelock___gc(lua_State* lua);
tb_int_t xm_io_filelock___tostring(lua_State* lua);
@@ -254,6 +257,9 @@ static luaL_Reg const g_io_filelock_functions[] =
{
{ "path", xm_io_filelock_path }
, { "close", xm_io_filelock_close }
+, { "lock", xm_io_filelock_lock }
+, { "unlock", xm_io_filelock_unlock }
+, { "trylock", xm_io_filelock_trylock }
, { "__gc", xm_io_filelock___gc }
, { "__tostring", xm_io_filelock___tostring }
, { tb_null, tb_null }
@@ -575,7 +581,7 @@ static tb_void_t xm_machine_register_metatable(xm_machine_t* machine, tb_char_t
*
* metatype module.metaname = metatable {__index = metatable, funcs ...}
*
- * e.g. XM_IO_FILE* io.file = metatable {__index = metatable, funcs ...}
+ * e.g. io._file* io._file = metatable {__index = metatable, funcs ...}
*/
luaL_newmetatable(machine->lua, metatype);
// stack: {metatable}, {metatable}
@@ -621,10 +627,10 @@ xm_machine_ref_t xm_machine_init()
luaL_register(machine->lua, "io", g_io_functions);
// bind io.file (metatable) functions
- xm_machine_register_metatable(machine, "io", "_file", "XM_IO_FILE*", g_io_file_functions);
+ xm_machine_register_metatable(machine, "io", "_file", "io._file*", g_io_file_functions);
// bind io.filelock (metatable) functions
- xm_machine_register_metatable(machine, "io", "_filelock", "XM_IO_FILE_LOCK*", g_io_filelock_functions);
+ xm_machine_register_metatable(machine, "io", "_filelock", "io._filelock*", g_io_filelock_functions);
// add stdin, stdout, stderr to io
xm_io_std(machine->lua);
diff --git a/core/src/xmake/makefile b/core/src/xmake/makefile
index ad3ddaad2..89500e727 100644
--- a/core/src/xmake/makefile
+++ b/core/src/xmake/makefile
@@ -54,6 +54,9 @@ xmake_C_FILES += \
io/file_seek \
io/file_write \
io/filelock_path \
+ io/filelock_lock \
+ io/filelock_unlock \
+ io/filelock_trylock \
io/filelock___tostring \
io/filelock_close___gc \
io/open \
diff --git a/xmake/core/sandbox/modules/io.lua b/xmake/core/sandbox/modules/io.lua
index 87354c459..c4c1a63c8 100644
--- a/xmake/core/sandbox/modules/io.lua
+++ b/xmake/core/sandbox/modules/io.lua
@@ -28,8 +28,9 @@ local vformat = require("sandbox/modules/vformat")
-- define module
local sandbox_io = sandbox_io or {}
local sandbox_io_file = sandbox_io._file or {}
+local sandbox_io_filelock = sandbox_io._filelock or {}
sandbox_io._file = sandbox_io_file
-sandbox_io._filelock = io._filelock
+sandbox_io._filelock = sandbox_io_filelock
-- inherit some builtin interfaces
sandbox_io.lines = io.lines
@@ -58,6 +59,26 @@ if sandbox_io_file.__index ~= sandbox_io_file then
sandbox_io_file.lines = io._file.lines
end
+-- inherit matatable of file lock
+if sandbox_io_filelock.__index ~= sandbox_io_filelock then
+ sandbox_io_filelock.__index = sandbox_io_filelock
+ for k, v in pairs(io._filelock) do
+ if type(v) == "function" then
+ sandbox_io_filelock[k] = function(s, ...)
+ local result, err = v(s._LOCK, ...)
+ if result == nil and err ~= nil then
+ raise(err)
+ end
+ -- wrap to sandbox_filelock again
+ if result == s._LOCK then
+ result = s
+ end
+ return result
+ end
+ end
+ end
+end
+
-- get file size
function sandbox_io_file:size()
-- __len on tables is scheduled to be supported in 5.2.
@@ -133,6 +154,10 @@ function sandbox_io.openlock(filepath)
if not lock then
raise(errors)
end
+
+ -- bind metatable
+ lock = { _LOCK = lock }
+ setmetatable(lock, sandbox_io_filelock);
return lock
end