From 67160b2dea4002a29f98f68f8650307bce48da60 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Thu, 2 Feb 2023 21:56:37 -0500 Subject: [PATCH 1/3] Implement try_close_finalizer, do not wait for liblock, fix #1048 --- src/HDF5.jl | 2 ++ src/api/api.jl | 3 +-- src/api/lock.jl | 16 ++++++++++++++++ src/properties.jl | 2 +- src/types.jl | 15 ++++++++------- 5 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 src/api/lock.jl diff --git a/src/HDF5.jl b/src/HDF5.jl index fb95abfa1..b515f6a05 100644 --- a/src/HDF5.jl +++ b/src/HDF5.jl @@ -62,6 +62,8 @@ export @read, # H5DataStore, Attribute, File, Group, Dataset, Datatype, Opaque, # Dataspace, Object, Properties, VLen, ChunkStorage, Reference + + h5doc(name) = "[`$name`](https://portal.hdfgroup.org/display/HDF5/$(name))" include("api/api.jl") diff --git a/src/api/api.jl b/src/api/api.jl index dda13d7cb..93131f4bd 100644 --- a/src/api/api.jl +++ b/src/api/api.jl @@ -13,8 +13,7 @@ else ) end -const liblock = ReentrantLock() - +include("lock.jl") include("types.jl") include("error.jl") include("functions.jl") # core API ccall wrappers diff --git a/src/api/lock.jl b/src/api/lock.jl new file mode 100644 index 000000000..889c04995 --- /dev/null +++ b/src/api/lock.jl @@ -0,0 +1,16 @@ +const liblock = ReentrantLock() + +# Try to acquire the lock (test-test-set) and close if successful +# Otherwise, defer finalization +# https://github.com/JuliaIO/HDF5.jl/issues/1048 +function try_close_finalizer(x) + if !islocked(liblock) && + trylock(liblock) do + close(x) + true + end + else + finalizer(try_close_finalizer, x) + end +end + diff --git a/src/properties.jl b/src/properties.jl index 1ca0033fa..fa06724e2 100644 --- a/src/properties.jl +++ b/src/properties.jl @@ -104,7 +104,7 @@ macro propertyclass(name, classid) id::API.hid_t function $name(id::API.hid_t) obj = new(id) - finalizer(close, obj) + finalizer(API.try_close_finalizer, obj) obj end end diff --git a/src/types.jl b/src/types.jl index eea17a9b3..405d5afb9 100644 --- a/src/types.jl +++ b/src/types.jl @@ -5,6 +5,7 @@ # Supertype of HDF5.File, HDF5.Group, JldFile, JldGroup, Matlabv5File, and MatlabHDF5File. abstract type H5DataStore end + # Read a list of variables, read(parent, "A", "B", "x", ...) function Base.read(parent::H5DataStore, name::AbstractString...) tuple((read(parent, x) for x in name)...) @@ -41,7 +42,7 @@ mutable struct File <: H5DataStore function File(id, filename, toclose::Bool=true) f = new(id, filename) if toclose - finalizer(close, f) + finalizer(API.try_close_finalizer, f) end f end @@ -55,7 +56,7 @@ mutable struct Group <: H5DataStore function Group(id, file) g = new(id, file) - finalizer(close, g) + finalizer(API.try_close_finalizer, g) g end end @@ -69,7 +70,7 @@ mutable struct Dataset function Dataset(id, file, xfer=DatasetTransferProperties()) dset = new(id, file, xfer) - finalizer(close, dset) + finalizer(API.try_close_finalizer, dset) dset end end @@ -84,14 +85,14 @@ mutable struct Datatype function Datatype(id, toclose::Bool=true) nt = new(id, toclose) if toclose - finalizer(close, nt) + finalizer(API.try_close_finalizer, nt) end nt end function Datatype(id, file::File, toclose::Bool=true) nt = new(id, toclose, file) if toclose - finalizer(close, nt) + finalizer(API.try_close_finalizer, nt) end nt end @@ -106,7 +107,7 @@ mutable struct Dataspace function Dataspace(id) dspace = new(id) - finalizer(close, dspace) + finalizer(API.try_close_finalizer, dspace) dspace end end @@ -119,7 +120,7 @@ mutable struct Attribute function Attribute(id, file) dset = new(id, file) - finalizer(close, dset) + finalizer(API.try_close_finalizer, dset) dset end end From fc010075fdcd9f66baf3aa590a0005c8deb61a09 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Thu, 2 Feb 2023 22:23:59 -0500 Subject: [PATCH 2/3] Fix formatting --- src/HDF5.jl | 2 -- src/api/lock.jl | 10 ++++------ src/types.jl | 1 - 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/HDF5.jl b/src/HDF5.jl index b515f6a05..fb95abfa1 100644 --- a/src/HDF5.jl +++ b/src/HDF5.jl @@ -62,8 +62,6 @@ export @read, # H5DataStore, Attribute, File, Group, Dataset, Datatype, Opaque, # Dataspace, Object, Properties, VLen, ChunkStorage, Reference - - h5doc(name) = "[`$name`](https://portal.hdfgroup.org/display/HDF5/$(name))" include("api/api.jl") diff --git a/src/api/lock.jl b/src/api/lock.jl index 889c04995..6614b70ed 100644 --- a/src/api/lock.jl +++ b/src/api/lock.jl @@ -4,13 +4,11 @@ const liblock = ReentrantLock() # Otherwise, defer finalization # https://github.com/JuliaIO/HDF5.jl/issues/1048 function try_close_finalizer(x) - if !islocked(liblock) && - trylock(liblock) do - close(x) - true - end + if !islocked(liblock) && trylock(liblock) do + close(x) + true + end else finalizer(try_close_finalizer, x) end end - diff --git a/src/types.jl b/src/types.jl index 405d5afb9..84a0204b5 100644 --- a/src/types.jl +++ b/src/types.jl @@ -5,7 +5,6 @@ # Supertype of HDF5.File, HDF5.Group, JldFile, JldGroup, Matlabv5File, and MatlabHDF5File. abstract type H5DataStore end - # Read a list of variables, read(parent, "A", "B", "x", ...) function Base.read(parent::H5DataStore, name::AbstractString...) tuple((read(parent, x) for x in name)...) From 819d4de7676cfd27d5651befc5cbbb0272e779e7 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Fri, 3 Feb 2023 17:24:31 -0500 Subject: [PATCH 3/3] try_close_finalizer always returns nothing --- src/api/lock.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/api/lock.jl b/src/api/lock.jl index 6614b70ed..c164c6c1a 100644 --- a/src/api/lock.jl +++ b/src/api/lock.jl @@ -11,4 +11,5 @@ function try_close_finalizer(x) else finalizer(try_close_finalizer, x) end + return nothing end