summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2019-07-26 23:16:42 +0800
committerruki <[email protected]>2019-07-26 13:40:14 +0800
commit8f13f68c5b41744f5f420aaf89d282283c33ac5b (patch)
tree74025e7ff2528230c0508ec5b8100d6c31846920
parent638766d05d89c7a447f2b9df0b3310afb08fbfb7 (diff)
add lock for package
-rw-r--r--xmake/actions/require/clean.lua22
-rw-r--r--xmake/actions/require/impl/action/download.lua6
-rw-r--r--xmake/actions/require/impl/action/install.lua6
-rw-r--r--xmake/core/package/package.lua35
4 files changed, 58 insertions, 11 deletions
diff --git a/xmake/actions/require/clean.lua b/xmake/actions/require/clean.lua
index 6918fa76d..7cfadb1e6 100644
--- a/xmake/actions/require/clean.lua
+++ b/xmake/actions/require/clean.lua
@@ -73,17 +73,6 @@ end
function main(package_names)
-- trace
- print("clearing caches ..")
-
- -- clear cache directory
- os.rm(package.cachedir())
-
- -- clear require cache
- local require_cache = cache("local.require")
- require_cache:clear()
- require_cache:flush()
-
- -- trace
print("clearing packages ..")
-- clear all unused packages
@@ -99,5 +88,16 @@ function main(package_names)
_clear_packagedirs(packagedir)
end
end
+
+ -- trace
+ print("clearing caches ..")
+
+ -- clear cache directory
+ os.rm(package.cachedir())
+
+ -- clear require cache
+ local require_cache = cache("local.require")
+ require_cache:clear()
+ require_cache:flush()
end
diff --git a/xmake/actions/require/impl/action/download.lua b/xmake/actions/require/impl/action/download.lua
index 797af48b4..548d25a83 100644
--- a/xmake/actions/require/impl/action/download.lua
+++ b/xmake/actions/require/impl/action/download.lua
@@ -172,6 +172,9 @@ function main(package)
-- enter the working directory
local oldir = os.cd(workdir)
+ -- lock this package
+ package:lock()
+
-- get urls
local urls = _urls(package)
assert(#urls > 0, "cannot get url of package(%s)", package:name())
@@ -234,6 +237,9 @@ function main(package)
if ok then break end
end
+ -- unlock this package
+ package:unlock()
+
-- leave working directory
os.cd(oldir)
return ok
diff --git a/xmake/actions/require/impl/action/install.lua b/xmake/actions/require/impl/action/install.lua
index 8e1a0c658..15114f83d 100644
--- a/xmake/actions/require/impl/action/install.lua
+++ b/xmake/actions/require/impl/action/install.lua
@@ -112,6 +112,9 @@ function main(package)
-- get working directory of this package
local workdir = package:cachedir()
+ -- lock this package
+ package:lock()
+
-- enter the working directory
local oldir = nil
if #package:urls() > 0 then
@@ -268,6 +271,9 @@ function main(package)
os.tryrm(installdir)
end
+ -- unlock this package
+ package:unlock()
+
-- leave source codes directory
os.cd(oldir)
end
diff --git a/xmake/core/package/package.lua b/xmake/core/package/package.lua
index 7d7fe8f67..bfc742087 100644
--- a/xmake/core/package/package.lua
+++ b/xmake/core/package/package.lua
@@ -30,6 +30,7 @@ local utils = require("base/utils")
local table = require("base/table")
local global = require("base/global")
local semver = require("base/semver")
+local option = require("base/option")
local scopeinfo = require("base/scopeinfo")
local interpreter = require("base/interpreter")
local sandbox = require("sandbox/sandbox")
@@ -248,6 +249,40 @@ function _instance:kind()
return self:get("kind")
end
+-- get the filelock of the whole package directory
+function _instance:filelock()
+ local filelock = self._FILELOCK
+ if filelock == nil then
+ filelock = io.openlock(path.join(self:cachedir(), "package.lock"))
+ if not filelock then
+ os.raise("cannot create filelock for package(%s)!", package:name())
+ end
+ self._FILELOCK = filelock
+ end
+ return filelock
+end
+
+-- lock the whole package
+function _instance:lock(opt)
+ if self:filelock():trylock(opt) then
+ return true
+ elseif option.get("diagnosis") then
+ utils.warning("the current package is being accessed by other processes, please waiting!")
+ end
+ local ok, errors = self:filelock():lock(opt)
+ if not ok then
+ os.raise(errors)
+ end
+end
+
+-- unlock the whole package
+function _instance:unlock()
+ local ok, errors = self:filelock():unlock()
+ if not ok then
+ os.raise(errors)
+ end
+end
+
-- get the cached directory of this package
function _instance:cachedir()
local name = self:name():lower():gsub("::", "_")