#' Test and set file locking for HDF5
#'
#' HDF5 1.10 uses file locking by default. On some file systems this is not
#' available, and the HDF5 library will throw an error if the user attempts to
#' create or access a file located on such a file system. These functions help
#' identify if file locking is available without throwing an error, and allow
#' the locking to be disabled for the duration of the R session if needed.
#'
#' \code{h5testFileLocking} will create a temporary file and then attempt to
#' apply a file lock using the appropriate function within the HDF5 library.
#' The success or failure of the locking is then recorded and the temporary
#' file removed. Even relatively low level functions such as
#' \code{\link{H5Fcreate}} will fail inelegantly if file locking fails.
#'
#' \code{h5disableFileLocking} will set the environment variable
#' \code{RHDF5_USE_FILE_LOCKING=FALSE}, which is the recommended was to disable
#' this behaviour if file locking is not supported. This will only persist
#' within the current R session. You can set the environment variable outside
#' of R if this is a more general issue on your system.
#'
#' \code{h5enableFileLocking} will unset the \code{RHDF5_USE_FILE_LOCKING}
#' environment variable.
#'
#' More discussion of HDF5's use of file locking can be found online e.g.
#' https://forum.hdfgroup.org/t/hdf5-1-10-0-and-flock/3761/4 or
#' https://forum.hdfgroup.org/t/hdf5-files-on-nfs/3985/5
#'
#' @aliases h5testFileLocking h5enableFileLocking h5disableFileLocking
#' @param location The name of a directory or file to test. If an existing
#' directory is provided a temporary file will be created in this folder. If
#' non-existant location is provided a file with the name will be created,
#' tested for file locking, and then removed. Providing an existing file will
#' result in an error.
#' @return \code{h5testFileLocking} returns \code{TRUE} if a file can be
#' successfully locked at the specified location, or \code{FALSE} otherwise.
#'
#' \code{h5disableFileLocking} and \code{h5enableFileLocking} set are called
#' for the side effect of setting or unsetting the environment variable
#' \code{HDF5_USE_FILE_LOCKING} and do not return anything.
#'
#' @author Mike Smith
#' @keywords IO file
#' @examples
#'
#' ## either a file name or directory can be tested
#' file <- tempfile()
#' dir <- tempdir()
#'
#' h5testFileLocking(dir)
#' h5testFileLocking(file)
#'
#' ## we can check for file locking, and disable if needed
#' if( !h5testFileLocking(dir) ) {
#' h5disableFileLocking()
#' }
#'
#' @name h5_FileLocking
#' @importFrom utils file_test
#' @export h5testFileLocking
h5testFileLocking <- function(location) {
if(missing(location)) {
stop("You must provide a location to test.")
}
## stop if existing file passed
if(file_test("-f", location)) {
stop('Testing file locking will remove ', location,
'\nPlease provide a directory or the name of a temporary file to be created.')
}
## passed an existing directory
if(file_test("-d", location)) {
file <- tempfile(tmpdir = location)
} else { ## location doesn't exist, we will create it
file <- location
}
lock_status <- .Call("_h5fileLock", file, PACKAGE = "rhdf5")
file.remove(file)
return(lock_status >= 0)
}
#' @rdname h5_FileLocking
#' @export
h5disableFileLocking <- function() {
Sys.setenv(HDF5_USE_FILE_LOCKING = "FALSE")
}
#' @rdname h5_FileLocking
#' @export
h5enableFileLocking <- function() {
Sys.unsetenv("HDF5_USE_FILE_LOCKING")
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.