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

Remove global nlopt_exception #230

Merged
merged 2 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 15 additions & 18 deletions src/NLopt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,10 @@ mutable struct Opt
# Opt so that they aren't garbage-collected. cb[1] is the objective.
cb::Vector{Callback_Data}

exception::Any

function Opt(p::Ptr{Cvoid})
opt = new(p, Array{Callback_Data}(undef, 1))
opt = new(p, Array{Callback_Data}(undef, 1), nothing)
finalizer(destroy, opt)
return opt
end
Expand Down Expand Up @@ -205,9 +207,6 @@ end

struct ForcedStop <: Exception end

# cache current exception for forced stop
global nlopt_exception = nothing

function errmsg(o::Opt)
msg = nlopt_get_errmsg(o)
return msg == C_NULL ? nothing : unsafe_string(msg)
Expand All @@ -232,11 +231,10 @@ function chk(o::Opt, result::Result)
elseif result == OUT_OF_MEMORY
throw(OutOfMemoryError())
elseif result == FORCED_STOP
global nlopt_exception
e = nlopt_exception
nlopt_exception = nothing
if e !== nothing && !isa(e, ForcedStop)
throw(e)
exception = getfield(o, :exception)
setfield!(o, :exception, nothing)
if exception !== nothing && !isa(exception, ForcedStop)
throw(exception)
end
else
error("nlopt failure $result", _errmsg(o))
Expand Down Expand Up @@ -441,9 +439,9 @@ function nlopt_callback_wrapper(
return d.f(x, p_grad == C_NULL ? Cdouble[] : grad)
catch e
if e isa ForcedStop
global nlopt_exception = e
setfield!(d.o, :exception, e)
else
global nlopt_exception = CapturedException(e, catch_backtrace())
setfield!(d.o, :exception, CapturedException(e, catch_backtrace()))
end
force_stop!(d.o::Opt)
return NaN
Expand Down Expand Up @@ -525,9 +523,9 @@ function nlopt_vcallback_wrapper(
d.f(res, x, grad)
catch e
if e isa ForcedStop
global nlopt_exception = e
d.o.exception = e
else
global nlopt_exception = CapturedException(e, catch_backtrace())
d.o.exception = CapturedException(e, catch_backtrace())
end
force_stop!(d.o::Opt)
end
Expand Down Expand Up @@ -764,11 +762,10 @@ function optimize!(o::Opt, x::Vector{Cdouble})
# We do not need to check the value of `ret`, except if it is a FORCED_STOP
# with a Julia-related exception from a callback
if ret == FORCED_STOP
global nlopt_exception
e = nlopt_exception
nlopt_exception = nothing
if e !== nothing && !(e isa ForcedStop)
throw(e)
exception = getfield(o, :exception)
setfield!(o, :exception, nothing)
if exception !== nothing && !(exception isa ForcedStop)
throw(exception)
end
end
return opt_f[], x, Symbol(ret)
Expand Down
6 changes: 3 additions & 3 deletions test/C_API.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ function test_issue_156_CapturedException()
opt = Opt(:LN_SBPLX, 1)
opt.min_objective = f
@test_throws CapturedException optimize(opt, [0.1234])
@test NLopt.nlopt_exception === nothing
@test getfield(opt, :exception) === nothing
try
optimize(opt, [0.1234])
catch e
Expand All @@ -60,7 +60,7 @@ function test_issue_156_ForcedStop()
opt.min_objective = f
fmin, xmin, ret = optimize(opt, [0.1234])
@test ret == :FORCED_STOP
@test NLopt.nlopt_exception === nothing
@test getfield(opt, :exception) === nothing
return
end

Expand All @@ -70,7 +70,7 @@ function test_issue_156_no_error()
opt.min_objective = f
fmin, xmin, ret = optimize(opt, [0.1234])
@test ret ∈ (:SUCCESS, :FTOL_REACHED, :XTOL_REACHED)
@test NLopt.nlopt_exception === nothing
@test getfield(opt, :exception) === nothing
return
end

Expand Down
Loading