diff --git a/com.oracle.truffle.r.test.packages/r/install.cache.R b/com.oracle.truffle.r.test.packages/r/install.cache.R index 864e74424d59702461b9c9880c74be0fb47d8c7f..ac80b44babb3da8e8b87cf5f6e10fb1dbf386143 100644 --- a/com.oracle.truffle.r.test.packages/r/install.cache.R +++ b/com.oracle.truffle.r.test.packages/r/install.cache.R @@ -21,6 +21,31 @@ # questions. # +lock.file.name <- ".lock" + +pkg.cache.max.retries <- 3L + +pkg.cache.lock <- function(version.dir) { + tries <- 0L + version.lock.file <- file.path(version.dir, lock.file.name) + while (file.exists(version.lock.file)) { + # wait for 1 second + Sys.sleep(1) + tries <- tries + 1L + + if (tries >= pkg.cache.max.retries) { + return (FALSE) + } + } + log.message("CREATING LOCK FILE", version.lock.file) + tryCatch(file.create(version.lock.file), error=function(e) return (FALSE), warning=function(e) return (FALSE)) +} + +pkg.cache.unlock <- function(version.dir) { + version.lock.file <- file.path(version.dir, lock.file.name) + tryCatch(file.remove(version.lock.file)) +} + is.fastr <- function() { length(grep('FastR', R.Version()$version.string)) } @@ -36,8 +61,6 @@ log.message <- if(!exists("log.message")) { log.message } - - pkg.cache.install <- function(pkg.cache.env, pkgname, pkg.version, lib.install, install.cmd) { pkg <- list(Package=pkgname, Version=pkg.version) is.cached <- pkg.cache.get(pkg.cache.env, pkg, lib.install) @@ -61,6 +84,12 @@ pkg.cache.get <- function(pkg.cache.env, pkg, lib) { return (FALSE) } + # lock version directory + if (!pkg.cache.lock(version.dir)) { + log.message("could not lock version dir ", version.dir, level=1) + return (FALSE) + } + pkgname <- as.character(pkg["Package"]) pkg.version <- as.character(pkg["Version"]) @@ -82,7 +111,7 @@ pkg.cache.get <- function(pkg.cache.env, pkg, lib) { }, error = function(e) { log.message("could not extract cached package from ", fromPath , " to ", toPath, level=1) return (FALSE) - }) + }, finally = pkg.cache.unlock(version.dir) ) } log.message("cache miss for package ", pkgname, level=1) @@ -102,6 +131,16 @@ pkg.cache.insert <- function(pkg.cache.env, pkg, lib) { dir.create(version.dir) } + # lock version directory + if (!pkg.cache.lock(version.dir)) { + log.message("could not insert: version dir ", version.dir, " is locked", level=1) + return (FALSE) + } + }, error = function(e) { + log.message("could not insert package '", pkgname, "' because: ", e$message) + }) + + tryCatch({ pkgname <- as.character(pkg["Package"]) pkg.version <- as.character(pkg["Version"]) fromPath <- file.path(lib, pkgname) @@ -133,7 +172,7 @@ pkg.cache.insert <- function(pkg.cache.env, pkg, lib) { return (TRUE) }, error = function(e) { log.message("could not insert package '", pkgname, "' because: ", e$message) - }) + }, finally = pkg.cache.unlock(version.dir) ) FALSE } @@ -272,7 +311,13 @@ pkg.cache.get.version <- function(cache.dir, cache.version, table.file.name, cac } if (!is.null(updated.version.table)) { version.subdir <- as.character(updated.version.table[updated.version.table$version == cache.version, "dir"]) - write.csv(updated.version.table, version.table.name, row.names=FALSE) + if (!pkg.cache.lock(cache.dir)) { + return (NULL) + } + + try({ + write.csv(updated.version.table, version.table.name, row.names=FALSE) + }, finally=pkg.cache.unlock(cache.dir)) } # return the version directory @@ -376,7 +421,6 @@ pkg.cache.internal.install <- function(pkg.cache.env, pkgname, contriburl, lib.i pkg.list <- as.data.frame(available.packages(contriburl=contriburl), stringAsFactors=FALSE) # query version of the package - #pkg.version <- as.character(pkg.list[pkg.list$Package == pkgname, "Version"]) pkg <- pkg.list[pkgname, c("Package", "Version")] # compute transitive dependencies of the package to install