summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2019-08-18 10:48:20 +0800
committerruki <[email protected]>2019-08-18 10:48:20 +0800
commit870440fe4ff1523e142e0eafae0a38cf3cfe4915 (patch)
tree4403af893e555d3cfa781b738f44ae8c9df56287
parent2c5d7d443fcda38f50dae1a0050eca5ff6ef531f (diff)
rewrite filelock
-rw-r--r--core/src/xmake/io/filelock.h113
-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.c96
-rw-r--r--core/src/xmake/io/filelock_islocked.c53
-rw-r--r--core/src/xmake/io/filelock_lock.c33
-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.c33
-rw-r--r--core/src/xmake/io/filelock_unlock.c33
-rw-r--r--core/src/xmake/io/openlock.c89
-rw-r--r--core/src/xmake/machine.c33
-rw-r--r--core/src/xmake/makefile7
-rw-r--r--xmake/core/base/io.lua122
-rw-r--r--xmake/core/sandbox/modules/io.lua73
-rw-r--r--xmake/core/sandbox/modules/process.lua16
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