Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API Lock Preferences #1022

Closed
wants to merge 14 commits into from
Closed

Conversation

mkitti
Copy link
Member

@mkitti mkitti commented Nov 1, 2022

This builds on the sb/lock branch by using Preferences.jl to configure the lock usage at compile time.

The preference, use_api_lock can be set to either true or false.

The preference is set via the API.set_use_lock_pref! function and can be quered by API.get_use_lock_pref().

This mainly meant to help assess the sb/lock branch.

Other features such as the RawAPI module have been withdrawn.

@mkitti mkitti requested a review from simonbyrne November 1, 2022 05:42
@simonbyrne
Copy link
Collaborator

simonbyrne commented Nov 8, 2022

This adds a bunch of complexity, and 2 additional runtime lookups at each call. Personally i don't think it's worth it (especially since I haven't been able to see any noticeable overhead with the locking).

I think if you want to make it optional, just make it an all-or-nothing: use_api_lock is true/false with

const use_api_lock = @load_preference("use_api_lock", true)

and make the API function wrappers:

    use_api_lock && lock(liblock)
    var"#status#" = try
            # ccall
        finally
            use_api_lock && unlock(liblock)
        end
    var"#status#" < 0 && @h5error ...
    return nothing

@mkitti
Copy link
Member Author

mkitti commented Nov 8, 2022

After testing, I am getting this error. I suspect this is because the finalizer is trying to run after we call h5_close().

HDF5.API.h5_close()

error in running finalizer: HDF5.API.H5Error(msg="Error closing file", id=1008806316530991104)
macro expansion at /home/mkitti/.julia/dev/HDF5/src/api/error.jl:18 [inlined]
h5f_close at /home/mkitti/.julia/dev/HDF5/src/api/functions.jl:1054
close at /home/mkitti/.julia/dev/HDF5/src/file.jl:120 [inlined]
lock_and_close at /home/mkitti/.julia/dev/HDF5/src/api/lock.jl:58
unknown function (ip: 0x7f8eb5b0b122)
_jl_invoke at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2367 [inlined]
ijl_apply_generic at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gf.c:2549
jl_apply at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/julia.h:1838 [inlined]
run_finalizer at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gc.c:280
jl_gc_run_finalizers_in_list at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gc.c:367
run_finalizers at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/gc.c:410
ijl_atexit_hook at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/init.c:236
jl_repl_entrypoint at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/src/jlapi.c:720
main at /cache/build/default-amdci5-0/julialang/julia-release-1-dot-8/cli/loader_exe.c:59
unknown function (ip: 0x7f8f0cec8d8f)
__libc_start_main at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x401098)

@simonbyrne
Copy link
Collaborator

Is there a reason why the tests call HDF5.API.h5_close()?

@@ -5,36 +5,36 @@ using Test, HDF5

filename = joinpath(dirname, "main.hdf5")

f = h5open(filename, "w")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue was here. We forgot to close this handle explicitly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably best to pull this into a different PR

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can pull this into a different pull request, but this needs to be here as well since CI will error otherwise.

@mkitti
Copy link
Member Author

mkitti commented Nov 8, 2022

@simonbyrne I simplified this along the lines of your #1022 (comment) . I think this will allow us to more easily diagnose any potential issues or regressions that might emerge from this.

I also removed the RawAPI module. Something I would like to pay particular attention to is the use of the iterate functions where the C library is calling back into Julia code. Do we have sufficient guarantees on what thread the calls back will be run on?

src/api/lock.jl Outdated
the HDF5 C library is not thread-safe. Concurrent calls to the HDF5 library
from multiple threads will likely fail.
"""
const use_api_lock = Preferences.@load_preference("use_api_lock", default = true)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const use_api_lock = Preferences.@load_preference("use_api_lock", default = true)
const use_api_lock::Bool = Preferences.@load_preference("use_api_lock", default = true)

then the error below is not necessary

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking here is that the error I wrote would be more descriptive than the following since this potentially faces an end user. I suppose I could try catch the MethodError though.

ERROR: MethodError: Cannot `convert` an object of type String to an object of type Bool
Closest candidates are:
  convert(::Type{T}, ::Ptr) where T<:Integer at pointer.jl:23
  convert(::Type{T}, ::T) where T<:Number at number.jl:6
  convert(::Type{T}, ::Number) where T<:Number at number.jl:7

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess? Seems like a bit of a weird error case to be worried about though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems a bit too easy for someone to edit their LocalPreferences.jl and accidentally quote true. Maybe we need to add a tryparse.

julia> convert(Bool, "true")
ERROR: MethodError: Cannot `convert` an object of type String to an object of type Bool
Closest candidates are:
  convert(::Type{T}, ::Ptr) where T<:Integer at pointer.jl:23
  convert(::Type{T}, ::T) where T<:Number at number.jl:6
  convert(::Type{T}, ::Number) where T<:Number at number.jl:7
  ...
Stacktrace:
 [1] top-level scope
   @ REPL[65]:1

julia> tryparse(Bool, "true")
true

Copy link
Member Author

@mkitti mkitti Nov 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually the type assertion a global const will not work with Julia 1.6, and I think we're still trying to maintain compat with Julia 1.3

src/api/lock.jl Outdated
Comment on lines 14 to 15
const use_lock_and_close =
Preferences.@load_preference("use_lock_and_close", default = true) && !use_api_lock
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use_lock_on_close?

src/api/lock.jl Outdated
Comment on lines 45 to 46
@info "Please restart Julia for the use_api_lock preference to take effect"
Preferences.@set_preferences!("use_api_lock" => use_api_lock)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe only print the message if it has changed?

@mkitti
Copy link
Member Author

mkitti commented Nov 9, 2022

Is there a reason why the tests call HDF5.API.h5_close()?

I don't know, but it sure does help catch unclosed handles.

@mkitti
Copy link
Member Author

mkitti commented Nov 18, 2022

Closing and resubmitting PR directly to master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants