Skip to content

Commit

Permalink
re-add interrupts as option
Browse files Browse the repository at this point in the history
  • Loading branch information
taylormcd committed Nov 23, 2021
1 parent 1db5078 commit c6f41d2
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 9 deletions.
10 changes: 2 additions & 8 deletions examples/interruptions.m
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
function interruption_test()
function interruptions()

jleval println("Hit Ctrl-C to stop me!")

% this one causes crashes (sometimes?)
jleval 'global x = 0; while(true); global x += 1; if x%10000 == 0; println(x); end; yield(); end'

% this one doesn't cause any problems
% this one requires the ENABLE_INTERRUPTS flag to be set to `true`
% jleval 'global x = 0; while(true); global x += 1; yield(); end'

% this one isn't interruptable, as it never yields
% jleval 'global x = 0; while(true); global x += 1; end'


end
3 changes: 3 additions & 0 deletions src/Mex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ const mex_call_matlab_with_trap = Ref{Ptr{Cvoid}}()
const libut = Ref{Ptr{Cvoid}}()
const ut_is_interrupt_pending = Ref{Ptr{Cvoid}}()

# Flag for turning on/off interrupts
const ENABLE_INTERRUPTS = false

function __init__()

result = Libdl.dlopen(joinpath(MATLAB.matlab_libpath, "libmex"), Libdl.RTLD_GLOBAL; throw_error=false)
Expand Down
10 changes: 10 additions & 0 deletions src/exceptions.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# --- Interrupt Handling --- #

is_interrupt_pending() = ccall(ut_is_interrupt_pending[], Cuchar, ()) != 0

function check_for_interrupt()
if is_interrupt_pending()
throw(InterruptException())
end
end

# --- Exception Handling --- #

# MatlabException is basically identical to MxArray, but is an exception
Expand Down
34 changes: 33 additions & 1 deletion src/matlabtojulia.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,40 @@
# --- Calling Embedded Julia from MATLAB --- #

const catching_interrupts = Ref(false)

# entry point for MATLAB calling Julia
jl_mex(plhs::Vector{Ptr{Cvoid}}, prhs::Vector{Ptr{Cvoid}}) = jl_mex_inner(plhs, prhs)
function jl_mex(plhs::Vector{Ptr{Cvoid}}, prhs::Vector{Ptr{Cvoid}})
if ENABLE_INTERRUPTS && !catching_interrupts[]
try
catching_interrupts[] = true
jl_mex_outer(plhs, prhs)
finally
catching_interrupts[] = false
end
else
jl_mex_inner(plhs, prhs)
end
end

# enables interrupt processing
function jl_mex_outer(plhs::Vector{Ptr{Cvoid}}, prhs::Vector{Ptr{Cvoid}})
# do the desired computation
main_task = @async jl_mex_inner(plhs, prhs)

# check for interrupt
interrupt_handler = @async begin
while !Base.istaskdone(main_task)
if is_interrupt_pending()
Base.throwto(main_task, InterruptException())
end
yield()
end
end

# wait for main task to finish
wait(main_task)
end

# runs julia function with mex function inputs, catching errors if they occur
function jl_mex_inner(plhs::Vector{Ptr{Cvoid}}, prhs::Vector{Ptr{Cvoid}})

Expand Down

0 comments on commit c6f41d2

Please sign in to comment.