diff options
| author | ruki <[email protected]> | 2019-08-18 10:48:20 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2019-08-18 10:48:20 +0800 |
| commit | 870440fe4ff1523e142e0eafae0a38cf3cfe4915 (patch) | |
| tree | 4403af893e555d3cfa781b738f44ae8c9df56287 | |
| parent | 2c5d7d443fcda38f50dae1a0050eca5ff6ef531f (diff) | |
rewrite filelock
| -rw-r--r-- | core/src/xmake/io/filelock.h | 113 | ||||
| -rw-r--r-- | core/src/xmake/io/filelock_close.c (renamed from core/src/xmake/io/filelock___tostring.c) | 34 | ||||
| -rw-r--r-- | core/src/xmake/io/filelock_close___gc.c | 96 | ||||
| -rw-r--r-- | core/src/xmake/io/filelock_islocked.c | 53 | ||||
| -rw-r--r-- | core/src/xmake/io/filelock_lock.c | 33 | ||||
| -rw-r--r-- | core/src/xmake/io/filelock_open.c (renamed from core/src/xmake/io/filelock_path.c) | 33 | ||||
| -rw-r--r-- | core/src/xmake/io/filelock_trylock.c | 33 | ||||
| -rw-r--r-- | core/src/xmake/io/filelock_unlock.c | 33 | ||||
| -rw-r--r-- | core/src/xmake/io/openlock.c | 89 | ||||
| -rw-r--r-- | core/src/xmake/machine.c | 33 | ||||
| -rw-r--r-- | core/src/xmake/makefile | 7 | ||||
| -rw-r--r-- | xmake/core/base/io.lua | 122 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/io.lua | 73 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/process.lua | 16 |
14 files changed, 269 insertions, 499 deletions
diff --git a/core/src/xmake/io/filelock.h b/core/src/xmake/io/filelock.h deleted file mode 100644 index 460467d57..000000000 --- a/core/src/xmake/io/filelock.h +++ /dev/null @@ -1,113 +0,0 @@ -/*!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.h - * - */ -#ifndef XM_IO_FILE_LOCK_H -#define XM_IO_FILE_LOCK_H - -/* ////////////////////////////////////////////////////////////////////////////////////// - * includes - */ -#include "prefix.h" - -/* ////////////////////////////////////////////////////////////////////////////////////// - * macros - */ - -// 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 - */ - -// the file lock type -typedef struct __xm_io_filelock_t -{ - // the lock reference - tb_filelock_ref_t lock_ref; - - // is opened? - tb_bool_t is_opened; - - // the locked count - tb_long_t nlocked; - - // the lock name - tb_char_t name[64]; - - // the lock path - tb_char_t const* path; - -} xm_io_filelock_t; - -/* ////////////////////////////////////////////////////////////////////////////////////// - * interfaces - */ -static __tb_inline__ xm_io_filelock_t* xm_io_new_filelock(lua_State* lua) -{ - // check - tb_assert_and_check_return_val(lua, tb_null); - - // new file lock - xm_io_filelock_t* lock = (xm_io_filelock_t*)lua_newuserdata(lua, sizeof(xm_io_filelock_t)); - tb_assert_and_check_return_val(lock, tb_null); - - // init file lock - tb_memset(lock, 0, sizeof(xm_io_filelock_t)); - - // bind io._filelock metatable - luaL_getmetatable(lua, xm_io_filelock_udata); - lua_setmetatable(lua, -2); - return lock; -} - -static __tb_inline__ xm_io_filelock_t* xm_io_get_filelock(lua_State* lua) -{ - // check - tb_assert_and_check_return_val(lua, tb_null); - - // get file lock - xm_io_filelock_t* lock = (xm_io_filelock_t*)luaL_checkudata(lua, 1, xm_io_filelock_udata); - tb_assert(lock); - return lock; -} - -#endif diff --git a/core/src/xmake/io/filelock___tostring.c b/core/src/xmake/io/filelock_close.c index 417484c36..0689a4f50 100644 --- a/core/src/xmake/io/filelock___tostring.c +++ b/core/src/xmake/io/filelock_close.c @@ -15,36 +15,46 @@ * Copyright (C) 2015 - 2019, TBOOX Open Source Group. * * @author ruki - * @file filelock___tostring.c + * @file filelock_close.c * */ /* ////////////////////////////////////////////////////////////////////////////////////// * trace */ -#define TB_TRACE_MODULE_NAME "filelock___tostring" +#define TB_TRACE_MODULE_NAME "filelock_close" #define TB_TRACE_MODULE_DEBUG (0) /* ////////////////////////////////////////////////////////////////////////////////////// * includes */ -#include "filelock.h" +#include "prefix.h" /* ////////////////////////////////////////////////////////////////////////////////////// - * implementation + * interfaces */ -/* - * tostring(lock) - */ -tb_int_t xm_io_filelock___tostring(lua_State* lua) +// io.filelock_close(lock) +tb_int_t xm_io_filelock_close(lua_State* lua) { // check tb_assert_and_check_return_val(lua, 0); - // get lock name as string - xm_io_filelock_t* lock = xm_io_get_filelock(lua); - lua_pushstring(lua, lock->name); - xm_io_filelock_return_success(); + // is user data? + if (!lua_isuserdata(lua, 1)) + return 0; + + // get lock + tb_filelock_ref_t lock = (tb_filelock_ref_t)lua_touserdata(lua, 1); + tb_check_return_val(lock, 0); + + // exit lock + tb_filelock_exit(lock); + + // save result: ok + lua_pushboolean(lua, tb_true); + + // ok + return 1; } diff --git a/core/src/xmake/io/filelock_close___gc.c b/core/src/xmake/io/filelock_close___gc.c deleted file mode 100644 index c362994ba..000000000 --- a/core/src/xmake/io/filelock_close___gc.c +++ /dev/null @@ -1,96 +0,0 @@ -/*!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_close___gc.c - * - */ - -/* ////////////////////////////////////////////////////////////////////////////////////// - * trace - */ -#define TB_TRACE_MODULE_NAME "filelock_close___gc" -#define TB_TRACE_MODULE_DEBUG (0) - -/* ////////////////////////////////////////////////////////////////////////////////////// - * includes - */ -#include "filelock.h" - -/* ////////////////////////////////////////////////////////////////////////////////////// - * implementation - */ - -static tb_int_t xm_io_filelock_close_impl(lua_State* lua, tb_bool_t allow_closed_lock) -{ - // check - tb_assert_and_check_return_val(lua, 0); - - // close lock - xm_io_filelock_t* lock = xm_io_get_filelock(lua); - if (!lock->is_opened) - { - if (allow_closed_lock) - { - lua_pushboolean(lua, tb_true); - xm_io_filelock_return_success(); - } - else xm_io_filelock_return_error_closed(lua); - } - - // check - tb_assert(lock->lock_ref); - - // close lock - tb_filelock_exit(lock->lock_ref); - lock->lock_ref = tb_null; - lock->is_opened = tb_false; - lock->nlocked = 0; - - // free lock path - if (lock->path) - { - tb_free(lock->path); - lock->path = tb_null; - } - - // mark this lock as closed - tb_strlcpy(lock->name, "lock: (closed lock)", tb_arrayn(lock->name)); - - // close ok - lua_pushboolean(lua, tb_true); - xm_io_filelock_return_success(); -} - -/* ////////////////////////////////////////////////////////////////////////////////////// - * interfaces - */ - -/* - * lock:close() - */ -tb_int_t xm_io_filelock_close(lua_State* lua) -{ - return xm_io_filelock_close_impl(lua, tb_false); -} - -/* - * lock:close() - */ -tb_int_t xm_io_filelock___gc(lua_State* lua) -{ - return xm_io_filelock_close_impl(lua, tb_true); -} diff --git a/core/src/xmake/io/filelock_islocked.c b/core/src/xmake/io/filelock_islocked.c deleted file mode 100644 index 633d9b738..000000000 --- a/core/src/xmake/io/filelock_islocked.c +++ /dev/null @@ -1,53 +0,0 @@ -/*!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_islocked.c - * - */ - -/* ////////////////////////////////////////////////////////////////////////////////////// - * trace - */ -#define TB_TRACE_MODULE_NAME "filelock_islocked" -#define TB_TRACE_MODULE_DEBUG (0) - -/* ////////////////////////////////////////////////////////////////////////////////////// - * includes - */ -#include "filelock.h" - -/* ////////////////////////////////////////////////////////////////////////////////////// - * implementation - */ - -/* lock:islocked() - */ -tb_int_t xm_io_filelock_islocked(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 - { - lua_pushboolean(lua, lock->nlocked > 0); - xm_io_filelock_return_success(); - } -} diff --git a/core/src/xmake/io/filelock_lock.c b/core/src/xmake/io/filelock_lock.c index 338afe3c9..2a1337720 100644 --- a/core/src/xmake/io/filelock_lock.c +++ b/core/src/xmake/io/filelock_lock.c @@ -28,7 +28,7 @@ /* ////////////////////////////////////////////////////////////////////////////////////// * includes */ -#include "filelock.h" +#include "prefix.h" /* ////////////////////////////////////////////////////////////////////////////////////// * implementation @@ -36,8 +36,8 @@ /* lock file * - * exclusive lock: filelock:lock("/xxxx/filelock") - * shared lock: filelock:lock("/xxxx/filelock", {shared = true}) + * exclusive lock: io.filelock_lock(lock, "/xxxx/filelock") + * shared lock: io.filelock_lock(lock, "/xxxx/filelock", {shared = true}) */ tb_int_t xm_io_filelock_lock(lua_State* lua) { @@ -55,19 +55,16 @@ tb_int_t xm_io_filelock_lock(lua_State* lua) lua_pop(lua, 1); } - // 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 - { - // lock it - if (lock->nlocked > 0 || tb_filelock_enter(lock->lock_ref, is_shared? TB_FILELOCK_MODE_SH : TB_FILELOCK_MODE_EX)) - { - lock->nlocked++; - lua_pushboolean(lua, tb_true); - xm_io_filelock_return_success(); - } - else xm_io_filelock_return_error(lua, lock, "lock failed!"); - } + // is user data? + if (!lua_isuserdata(lua, 1)) + return 0; + + // get lock + tb_filelock_ref_t lock = (tb_filelock_ref_t)lua_touserdata(lua, 1); + tb_check_return_val(lock, 0); + + // lock it + tb_bool_t ok = tb_filelock_enter(lock, is_shared? TB_FILELOCK_MODE_SH : TB_FILELOCK_MODE_EX); + lua_pushboolean(lua, ok); + return 1; } diff --git a/core/src/xmake/io/filelock_path.c b/core/src/xmake/io/filelock_open.c index 1ab0fe932..9d3f8467a 100644 --- a/core/src/xmake/io/filelock_path.c +++ b/core/src/xmake/io/filelock_open.c @@ -15,40 +15,43 @@ * Copyright (C) 2015 - 2019, TBOOX Open Source Group. * * @author ruki - * @file filelock_path.c + * @file filelock_open.c * */ /* ////////////////////////////////////////////////////////////////////////////////////// * trace */ -#define TB_TRACE_MODULE_NAME "filelock_path" +#define TB_TRACE_MODULE_NAME "filelock_open" #define TB_TRACE_MODULE_DEBUG (0) /* ////////////////////////////////////////////////////////////////////////////////////// * includes */ -#include "filelock.h" +#include "prefix.h" /* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ -/* lock:path() +/* + * io.filelock_open(path) */ -tb_int_t xm_io_filelock_path(lua_State* lua) +tb_int_t xm_io_filelock_open(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 - { - // return lock path - lua_pushstring(lua, lock->path); - xm_io_filelock_return_success(); - } + // get file path + tb_char_t const* path = luaL_checkstring(lua, 1); + tb_assert_and_check_return_val(path, 0); + + // init file lock + tb_long_t tryn = 2; + tb_filelock_ref_t lock = tb_null; + while (!lock && tryn-- > 0) + lock = tb_filelock_init_from_path(path, tb_file_info(path, tb_null)? TB_FILE_MODE_RO : TB_FILE_MODE_RW | TB_FILE_MODE_CREAT); + if (lock) lua_pushlightuserdata(lua, (tb_pointer_t)lock); + else lua_pushnil(lua); + return 1; } diff --git a/core/src/xmake/io/filelock_trylock.c b/core/src/xmake/io/filelock_trylock.c index 9f8a9dfd4..73218d062 100644 --- a/core/src/xmake/io/filelock_trylock.c +++ b/core/src/xmake/io/filelock_trylock.c @@ -28,7 +28,7 @@ /* ////////////////////////////////////////////////////////////////////////////////////// * includes */ -#include "filelock.h" +#include "prefix.h" /* ////////////////////////////////////////////////////////////////////////////////////// * implementation @@ -36,8 +36,8 @@ /* try to lock file * - * exclusive lock: filelock:trylock("/xxxx/filelock") - * shared lock: filelock:trylock("/xxxx/filelock", {shared = true}) + * exclusive lock: io.filelock_trylock("/xxxx/filelock") + * shared lock: io.filelock_trylock("/xxxx/filelock", {shared = true}) */ tb_int_t xm_io_filelock_trylock(lua_State* lua) { @@ -55,19 +55,16 @@ tb_int_t xm_io_filelock_trylock(lua_State* lua) lua_pop(lua, 1); } - // 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 - { - // try to lock it - if (lock->nlocked > 0 || tb_filelock_enter_try(lock->lock_ref, is_shared? TB_FILELOCK_MODE_SH : TB_FILELOCK_MODE_EX)) - { - lock->nlocked++; - lua_pushboolean(lua, tb_true); - xm_io_filelock_return_success(); - } - else xm_io_filelock_return_error(lua, lock, "trylock failed!"); - } + // is user data? + if (!lua_isuserdata(lua, 1)) + return 0; + + // get lock + tb_filelock_ref_t lock = (tb_filelock_ref_t)lua_touserdata(lua, 1); + tb_check_return_val(lock, 0); + + // try to lock it + tb_bool_t ok = tb_filelock_enter_try(lock, is_shared? TB_FILELOCK_MODE_SH : TB_FILELOCK_MODE_EX); + lua_pushboolean(lua, ok); + return 1; } diff --git a/core/src/xmake/io/filelock_unlock.c b/core/src/xmake/io/filelock_unlock.c index 5cec814e9..a1808744a 100644 --- a/core/src/xmake/io/filelock_unlock.c +++ b/core/src/xmake/io/filelock_unlock.c @@ -28,33 +28,28 @@ /* ////////////////////////////////////////////////////////////////////////////////////// * includes */ -#include "filelock.h" +#include "prefix.h" /* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ -// filelock:unlock() +// io.filelock_unlock(lock) 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 (lock->nlocked > 1 || tb_filelock_leave(lock->lock_ref)) - { - if (lock->nlocked > 0) - lock->nlocked--; - else lock->nlocked = 0; - lua_pushboolean(lua, tb_true); - xm_io_filelock_return_success(); - } - else xm_io_filelock_return_error(lua, lock, "unlock failed!"); - } + // is user data? + if (!lua_isuserdata(lua, 1)) + return 0; + + // get lock + tb_filelock_ref_t lock = (tb_filelock_ref_t)lua_touserdata(lua, 1); + tb_check_return_val(lock, 0); + + // unlock it + tb_bool_t ok = tb_filelock_leave(lock); + lua_pushboolean(lua, ok); + return 1; } diff --git a/core/src/xmake/io/openlock.c b/core/src/xmake/io/openlock.c deleted file mode 100644 index 42d905557..000000000 --- a/core/src/xmake/io/openlock.c +++ /dev/null @@ -1,89 +0,0 @@ -/*!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 openlock.c - * - */ - -/* ////////////////////////////////////////////////////////////////////////////////////// - * trace - */ -#define TB_TRACE_MODULE_NAME "openlock" -#define TB_TRACE_MODULE_DEBUG (0) - -/* ////////////////////////////////////////////////////////////////////////////////////// - * includes - */ -#include "filelock.h" - -/* ////////////////////////////////////////////////////////////////////////////////////// - * implementation - */ - -/* - * io.openlock(path) - */ -tb_int_t xm_io_openlock(lua_State* lua) -{ - // check - tb_assert_and_check_return_val(lua, 0); - - // get file path - tb_char_t const* path = luaL_checkstring(lua, 1); - tb_assert_and_check_return_val(path, 0); - - // init file lock - tb_long_t tryn = 2; - tb_filelock_ref_t lock = tb_null; - while (!lock && tryn-- > 0) - lock = tb_filelock_init_from_path(path, tb_file_info(path, tb_null)? TB_FILE_MODE_RO : TB_FILE_MODE_RW | TB_FILE_MODE_CREAT); - if (lock) - { - // init file lock - xm_io_filelock_t* xmlock = xm_io_new_filelock(lua); - xmlock->lock_ref = lock; - xmlock->is_opened = tb_true; - xmlock->nlocked = 0; - - // save lock path - tb_size_t pathlen = tb_strlen(path); - xmlock->path = tb_malloc_cstr(pathlen + 1); - if (xmlock->path) - { - tb_strncpy((tb_char_t*)xmlock->path, path, pathlen); - ((tb_char_t*)xmlock->path)[pathlen] = '\0'; - } - - // save lock name - tb_size_t name_maxn = tb_arrayn(xmlock->name); - tb_strlcpy(xmlock->name, "lock: ", name_maxn); - if (pathlen < name_maxn - tb_arrayn("lock: ")) - tb_strcat(xmlock->name, path); - else - { - tb_strcat(xmlock->name, "..."); - tb_strcat(xmlock->name, path + (pathlen - name_maxn + tb_arrayn("lock: ") + tb_arrayn("..."))); - } - return 1; - } - else - { - lua_pushnil(lua); - lua_pushliteral(lua, "cannot open file lock!"); - return 2; - } -} diff --git a/core/src/xmake/machine.c b/core/src/xmake/machine.c index 0a37ff643..53f781031 100644 --- a/core/src/xmake/machine.c +++ b/core/src/xmake/machine.c @@ -92,7 +92,6 @@ tb_int_t xm_os_getown(lua_State* lua); // the io functions tb_int_t xm_io_std(lua_State* lua); tb_int_t xm_io_open(lua_State* lua); -tb_int_t xm_io_openlock(lua_State* lua); // the io/file functions tb_int_t xm_io_file_read(lua_State* lua); @@ -107,14 +106,11 @@ tb_int_t xm_io_file___tostring(lua_State* lua); tb_int_t xm_io_file___gc(lua_State* lua); // the io/filelock functions -tb_int_t xm_io_filelock_path(lua_State* lua); +tb_int_t xm_io_filelock_open(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_islocked(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); // the path functions tb_int_t xm_path_relative(lua_State* lua); @@ -232,9 +228,13 @@ static luaL_Reg const g_winos_functions[] = // the io functions static luaL_Reg const g_io_functions[] = { - { "open", xm_io_open } -, { "openlock", xm_io_openlock } -, { tb_null, tb_null } + { "open", xm_io_open } +, { "filelock_open", xm_io_filelock_open } +, { "filelock_lock", xm_io_filelock_lock } +, { "filelock_trylock", xm_io_filelock_trylock } +, { "filelock_unlock", xm_io_filelock_unlock } +, { "filelock_close", xm_io_filelock_close } +, { tb_null, tb_null } }; // the io/file functions @@ -253,20 +253,6 @@ static luaL_Reg const g_io_file_functions[] = , { tb_null, tb_null } }; -// the io/filelock functions -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 } -, { "islocked", xm_io_filelock_islocked } -, { "__gc", xm_io_filelock___gc } -, { "__tostring", xm_io_filelock___tostring } -, { tb_null, tb_null } -}; - // the path functions static luaL_Reg const g_path_functions[] = { @@ -631,9 +617,6 @@ xm_machine_ref_t xm_machine_init() // bind io._file (metatable) 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", "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 7f8e5e4c5..1568a8b45 100644 --- a/core/src/xmake/makefile +++ b/core/src/xmake/makefile @@ -53,15 +53,12 @@ xmake_C_FILES += \ io/file_read \ io/file_seek \ io/file_write \ - io/filelock_path \ + io/filelock_open \ io/filelock_lock \ io/filelock_unlock \ io/filelock_trylock \ - io/filelock_islocked \ - io/filelock___tostring \ - io/filelock_close___gc \ + io/filelock_close \ io/open \ - io/openlock \ io/std \ path/relative \ path/absolute \ diff --git a/xmake/core/base/io.lua b/xmake/core/base/io.lua index d234d52b3..cbb2a409b 100644 --- a/xmake/core/base/io.lua +++ b/xmake/core/base/io.lua @@ -19,8 +19,9 @@ -- -- define module -local io = io or {} -local _file = _file or io._file or {} +local io = io or {} +local _file = _file or io._file or {} +local _filelock = _filelock or {} -- load modules local path = require("base/path") @@ -29,7 +30,7 @@ local string = require("base/string") -- save original apis io._open = io._open or io.open -io._openlock = io._openlock or io.openlock +io._filelock = _filelock _file._read = _file._read or _file.read -- read data from file @@ -83,6 +84,112 @@ function _file:load() end end +-- new an filelock +function _filelock.new(lockpath, lock) + local filelock = table.inherit(_filelock) + filelock._NAME = path.filename(lockpath) + filelock._PATH = lockpath + filelock._LOCK = lock + filelock._LOCKED_NUM = 0 + setmetatable(filelock, _filelock) + return filelock +end + +-- get the filelock name +function _filelock:name() + return self._NAME +end + +-- get the filelock path +function _filelock:path() + return self._PATH +end + +-- is locked? +function _filelock:islocked() + return self._LOCKED_NUM > 0 +end + +-- lock file +-- +-- @param opt the argument option, {shared = true} +-- +-- @return ok, errors +-- +function _filelock:lock(opt) + if not self._LOCK then + return false, string.format("filelock(%s) has been closed!", self:name()) + end + if self._LOCKED_NUM > 0 or io.filelock_lock(self._LOCK, opt) then + self._LOCKED_NUM = self._LOCKED_NUM + 1 + return true + else + return false, string.format("filelock(%s): lock %s failed!", self:name(), self:path()) + end +end + +-- try to lock file +-- +-- @param opt the argument option, {shared = true} +-- +-- @return ok, errors +-- +function _filelock:trylock(opt) + if not self._LOCK then + return false, string.format("filelock(%s) has been closed!", self:name()) + end + if self._LOCKED_NUM > 0 or io.filelock_trylock(self._LOCK, opt) then + self._LOCKED_NUM = self._LOCKED_NUM + 1 + return true + else + return false, string.format("filelock(%s): trylock %s failed!", self:name(), self:path()) + end +end + +-- unlock file +function _filelock:unlock(opt) + if not self._LOCK then + return false, string.format("filelock(%s) has been closed!", self:name()) + end + if self._LOCKED_NUM > 1 or (self._LOCKED_NUM > 0 and io.filelock_unlock(self._LOCK)) then + if self._LOCKED_NUM > 0 then + self._LOCKED_NUM = self._LOCKED_NUM - 1 + else + self._LOCKED_NUM = 0 + end + return true + else + return false, string.format("filelock(%s): unlock %s failed!", self:name(), self:path()) + end +end + +-- close filelock +function _filelock:close() + if not self._LOCK then + return false, string.format("filelock(%s) has been closed!", self:name()) + end + local ok = io.filelock_close(self._LOCK) + if ok then + self._LOCK = nil + self._LOCKED_NUM = 0 + end + return ok +end + +-- tostring(filelock) +function _filelock:__tostring() + return "filelock: " .. self:name() +end + +-- gc(filelock) +function _filelock:__gc() + local ok = self._LOCK and io.filelock_close(self._LOCK) or false + if ok then + self._LOCK = nil + self._LOCKED_NUM = 0 + end +end + -- read all lines from file function io.lines(filepath, opt) @@ -190,18 +297,19 @@ function io.open(filepath, mode, opt) return file end --- replace the original openlock interface +-- open a filelock function io.openlock(filepath) -- check assert(filepath) -- open it - local lock = io._openlock(filepath) - if not lock then + local lock = io.filelock_open(filepath) + if lock then + return _filelock.new(filepath, lock) + else return nil, string.format("failed to open lock: %s", filepath) end - return lock end -- close file diff --git a/xmake/core/sandbox/modules/io.lua b/xmake/core/sandbox/modules/io.lua index e9206bbaa..54f374a14 100644 --- a/xmake/core/sandbox/modules/io.lua +++ b/xmake/core/sandbox/modules/io.lua @@ -28,9 +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 {} +local sandbox_io_filelock = sandbox_io_filelock or {} sandbox_io._file = sandbox_io_file -sandbox_io._filelock = sandbox_io_filelock +sandbox_io._filelock = sandbox_io._filelock or io._filelock -- inherit some builtin interfaces sandbox_io.lines = io.lines @@ -59,26 +59,6 @@ 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. @@ -100,6 +80,38 @@ function sandbox_io_file:writef(...) return self:write(string.format(...)) end +-- lock filelock +function sandbox_io_filelock.lock(lock, opt) + local ok, errors = lock:_lock(opt) + if not ok then + raise(errors) + end +end + +-- try to lock filelock +function sandbox_io_filelock.trylock(lock, opt) + local ok, errors = lock:_trylock(opt) + if not ok then + raise(errors) + end +end + +-- unlock filelock +function sandbox_io_filelock.unlock(lock) + local ok, errors = lock:_unlock() + if not ok then + raise(errors) + end +end + +-- close filelock +function sandbox_io_filelock.close(lock) + local ok, errors = lock:_close() + if not ok then + raise(errors) + end +end + -- gsub the given file and return replaced data function sandbox_io.gsub(filepath, pattern, replace, opt) @@ -155,9 +167,20 @@ function sandbox_io.openlock(filepath) raise(errors) end - -- bind metatable - lock = { _LOCK = lock } - setmetatable(lock, sandbox_io_filelock); + -- hook filelock interfaces + local hooked = {} + for name, func in pairs(lock) do + if not name:startswith("_") and type(func) == "function" then + local newfunc = sandbox_io_filelock[name] + if newfunc ~= nil then + hooked["_" .. name] = lock["_" .. name] or func + hooked[name] = newfunc + end + end + end + for name, func in pairs(hooked) do + lock[name] = func + end return lock end diff --git a/xmake/core/sandbox/modules/process.lua b/xmake/core/sandbox/modules/process.lua index 24872e8c1..7bfb8ef5d 100644 --- a/xmake/core/sandbox/modules/process.lua +++ b/xmake/core/sandbox/modules/process.lua @@ -66,15 +66,19 @@ function sandbox_process.open(command, opt) end -- hook subprocess interfaces + local hooked = {} for name, func in pairs(proc) do if not name:startswith("_") and type(func) == "function" then local newfunc = sandbox_process_subprocess[name] if newfunc ~= nil then - proc["_" .. name] = proc["_" .. name] or func - proc[name] = newfunc + hooked["_" .. name] = proc["_" .. name] or func + hooked[name] = newfunc end end end + for name, func in pairs(hooked) do + proc[name] = func + end return proc end @@ -99,15 +103,19 @@ function sandbox_process.openv(filename, argv, opt) end -- hook subprocess interfaces + local hooked = {} for name, func in pairs(proc) do if not name:startswith("_") and type(func) == "function" then local newfunc = sandbox_process_subprocess[name] if newfunc ~= nil then - proc["_" .. name] = proc["_" .. name] or func - proc[name] = newfunc + hooked["_" .. name] = proc["_" .. name] or func + hooked[name] = newfunc end end end + for name, func in pairs(hooked) do + proc[name] = func + end return proc end |
