diff --git a/adaptors/julia/AnalogIn.jl b/adaptors/julia/AnalogIn.jl index 1a2736ef79001aac42d8fcd48c8aa7f8cc00df57..d3a577f2154edb05f3e05662452b7e2403c03b31 100644 --- a/adaptors/julia/AnalogIn.jl +++ b/adaptors/julia/AnalogIn.jl @@ -4,16 +4,17 @@ mutable struct AnalogInChannel end mutable struct AnalogIn - moberg::Moberg + moberg::Ptr{Nothing} index::UInt32 channel::AnalogInChannel function AnalogIn(moberg::Moberg, index::Unsigned) channel = AnalogInChannel(0,0) + moberg_handle = moberg.handle checkOK(ccall((:moberg_analog_in_open, "libmoberg"), Status, - (Moberg, Cint, Ref{AnalogInChannel}), - moberg, index, channel)) - self = new(moberg, index, channel) + (Ptr{Nothing}, Cint, Ref{AnalogInChannel}), + moberg_handle, index, channel)) + self = new(moberg_handle, index, channel) finalizer(close, self) self end @@ -23,7 +24,7 @@ function close(ain::AnalogIn) DEBUG && println("closing $(ain)") checkOK(ccall((:moberg_analog_in_close, "libmoberg"), Status, - (Moberg, Cint, AnalogInChannel), + (Ptr{Nothing}, Cint, AnalogInChannel), ain.moberg, ain.index, ain.channel)) end diff --git a/adaptors/julia/AnalogOut.jl b/adaptors/julia/AnalogOut.jl index 938a562a9a453bb9be86b7713b056c9407c6a032..a911d103c57c7521c8476953e64e08414052cc39 100644 --- a/adaptors/julia/AnalogOut.jl +++ b/adaptors/julia/AnalogOut.jl @@ -4,16 +4,17 @@ mutable struct AnalogOutChannel end mutable struct AnalogOut - moberg::Moberg + moberg::Ptr{Nothing} index::UInt32 channel::AnalogOutChannel function AnalogOut(moberg::Moberg, index::Unsigned) channel = AnalogOutChannel(0,0) + moberg_handle = moberg.handle checkOK(ccall((:moberg_analog_out_open, "libmoberg"), Status, - (Moberg, Cint, Ref{AnalogOutChannel}), - moberg, index, channel)); - self = new(moberg, index, channel) + (Ptr{Nothing}, Cint, Ref{AnalogOutChannel}), + moberg_handle, index, channel)); + self = new(moberg_handle, index, channel) finalizer(close, self) self end @@ -23,7 +24,7 @@ function close(aout::AnalogOut) DEBUG && println("closing $(aout)") checkOK(ccall((:moberg_analog_out_close, "libmoberg"), Status, - (Moberg, Cint, AnalogOutChannel), + (Ptr{Nothing}, Cint, AnalogOutChannel), aout.moberg, aout.index, aout.channel)) end diff --git a/adaptors/julia/DigitalIn.jl b/adaptors/julia/DigitalIn.jl index db662308cc317d1089f94364cddf6ee863f5e0f6..ba3f150db28cc1ffcc7d77782a64821f607f15e7 100644 --- a/adaptors/julia/DigitalIn.jl +++ b/adaptors/julia/DigitalIn.jl @@ -4,16 +4,17 @@ mutable struct DigitalInChannel end mutable struct DigitalIn - moberg::Moberg + moberg::Ptr{Nothing} index::UInt32 channel::DigitalInChannel function DigitalIn(moberg::Moberg, index::Unsigned) channel = DigitalInChannel(0,0) + moberg_handle = moberg.handle checkOK(ccall((:moberg_digital_in_open, "libmoberg"), Status, - (Moberg, Cint, Ref{DigitalInChannel}), - moberg, index, channel)); - self = new(moberg, index, channel) + (Ptr{Nothing}, Cint, Ref{DigitalInChannel}), + moberg_handle, index, channel)); + self = new(moberg_handle, index, channel) finalizer(close, self) self end @@ -23,7 +24,7 @@ function close(din::DigitalIn) DEBUG && println("closing $(din)") checkOK(ccall((:moberg_digital_in_close, "libmoberg"), Status, - (Moberg, Cint, DigitalInChannel), + (Ptr{Nothing}, Cint, DigitalInChannel), din.moberg, din.index, din.channel)) end diff --git a/adaptors/julia/DigitalOut.jl b/adaptors/julia/DigitalOut.jl index b76ffb796787763f94c4c7fada5fba8be4ddfaf6..3c978fbbcb4d9650daf35e503370618ff7cce76a 100644 --- a/adaptors/julia/DigitalOut.jl +++ b/adaptors/julia/DigitalOut.jl @@ -4,16 +4,17 @@ mutable struct DigitalOutChannel end mutable struct DigitalOut - moberg::Moberg + moberg::Ptr{Nothing} index::UInt32 channel::DigitalOutChannel function DigitalOut(moberg::Moberg, index::Unsigned) channel = DigitalOutChannel(0,0) + moberg_handle = moberg.handle checkOK(ccall((:moberg_digital_out_open, "libmoberg"), Status, - (Moberg, Cint, Ref{DigitalOutChannel}), - moberg, index, channel)) - self = new(moberg, index, channel) + (Ptr{Nothing}, Cint, Ref{DigitalOutChannel}), + moberg_handle, index, channel)) + self = new(moberg_handle, index, channel) finalizer(close, self) self end @@ -23,7 +24,7 @@ function close(dout::DigitalOut) DEBUG && println("closing $(dout)") checkOK(ccall((:moberg_digital_out_close, "libmoberg"), Status, - (Moberg, Cint, DigitalOutChannel), + (Ptr{Nothing}, Cint, DigitalOutChannel), dout.moberg, dout.index, dout.channel)) end diff --git a/adaptors/julia/EncoderIn.jl b/adaptors/julia/EncoderIn.jl index 2b05def7860ee0f821d65ed40d6272a496a48fea..58273f65a98d646805cc5bb266149d5f1f90a697 100644 --- a/adaptors/julia/EncoderIn.jl +++ b/adaptors/julia/EncoderIn.jl @@ -4,16 +4,17 @@ mutable struct EncoderInChannel end mutable struct EncoderIn - moberg::Moberg + moberg::Ptr{Nothing} index::UInt32 channel::EncoderInChannel function EncoderIn(moberg::Moberg, index::Unsigned) channel = EncoderInChannel(0,0) + moberg_handle = moberg.handle checkOK(ccall((:moberg_encoder_in_open, "libmoberg"), Status, - (Moberg, Cint, Ref{EncoderInChannel}), - moberg, index, channel)) - self = new(moberg, index, channel) + (Ptr{Nothing}, Cint, Ref{EncoderInChannel}), + moberg_handle, index, channel)) + self = new(moberg_handle, index, channel) finalizer(close, self) self end @@ -23,7 +24,7 @@ function close(ein::EncoderIn) DEBUG && println("closing $(ein)") checkOK(ccall((:moberg_encoder_in_close, "libmoberg"), Status, - (Moberg, Cint, EncoderInChannel), + (Ptr{Nothing}, Cint, EncoderInChannel), ein.moberg, ein.index, ein.channel)) end diff --git a/adaptors/julia/MobergIO.jl b/adaptors/julia/MobergIO.jl index bd65678a91a2a037412f7a734c5d3a12e7b88c82..7c917b8ffae880a03daf27da0c70282fe91f3fe2 100644 --- a/adaptors/julia/MobergIO.jl +++ b/adaptors/julia/MobergIO.jl @@ -26,6 +26,7 @@ end function close(h::Moberg) DEBUG && println("Destroy $(h)") ccall((:moberg_free, "libmoberg"), Nothing, (Moberg,), h) + h.handle = Ptr{Nothing}(0) end include("AnalogIn.jl") diff --git a/moberg.c b/moberg.c index 61d4be5749360aa997c945098e1c1f672e747d9c..72fca0858879516e501f3941df2ab5dde4e81b8e 100644 --- a/moberg.c +++ b/moberg.c @@ -38,6 +38,8 @@ #include <moberg_parser.h> struct moberg { + int should_free; + int open_channels; struct moberg_config *config; struct channel_list { int capacity; @@ -255,19 +257,8 @@ struct moberg *moberg_new() fprintf(stderr, "Failed to allocate moberg struct\n"); goto err; } - result->analog_in.capacity = 0; - result->analog_in.value = NULL; - result->analog_out.capacity = 0; - result->analog_out.value = NULL; - result->digital_in.capacity = 0; - result->digital_in.value = NULL; - result->digital_out.capacity = 0; - result->digital_out.value = NULL; - result->encoder_in.capacity = 0; - result->encoder_in.value = NULL; - result->deferred_action = NULL; - result->config = NULL; - + memset(result, 0, sizeof(*result)); + /* Parse default configuration(s) */ const char * const *config_paths = xdgSearchableConfigDirectories(NULL); const char * const *path; @@ -295,9 +286,9 @@ err: return result; } -void moberg_free(struct moberg *moberg) +static void free_if_unused(struct moberg *moberg) { - if (moberg) { + if (moberg->should_free && moberg->open_channels == 0) { moberg_config_free(moberg->config); channel_list_free(&moberg->analog_in); channel_list_free(&moberg->analog_out); @@ -309,6 +300,15 @@ void moberg_free(struct moberg *moberg) } } +void moberg_free(struct moberg *moberg) +{ + if (moberg) { + moberg->should_free = 1; + free_if_unused(moberg); + } +} + + /* Input/output */ struct moberg_status moberg_analog_in_open( @@ -328,6 +328,7 @@ struct moberg_status moberg_analog_in_open( if (! OK(result)) { return result; } + moberg->open_channels++; *analog_in = channel->action.analog_in; return MOBERG_OK; } @@ -346,6 +347,8 @@ struct moberg_status moberg_analog_in_close( return MOBERG_ERRNO(EINVAL); } struct moberg_status result = channel->close(channel); + moberg->open_channels--; + free_if_unused(moberg); if (! OK(result)) { return result; } @@ -369,6 +372,7 @@ struct moberg_status moberg_analog_out_open( if (! OK(result)) { return result; } + moberg->open_channels++; *analog_out = channel->action.analog_out; return MOBERG_OK; } @@ -387,6 +391,8 @@ struct moberg_status moberg_analog_out_close( return MOBERG_ERRNO(EINVAL); } struct moberg_status result = channel->close(channel); + moberg->open_channels--; + free_if_unused(moberg); if (! OK(result)) { return result; } @@ -410,6 +416,7 @@ struct moberg_status moberg_digital_in_open( if (! OK(result)) { return result; } + moberg->open_channels++; *digital_in = channel->action.digital_in; return MOBERG_OK; } @@ -428,6 +435,8 @@ struct moberg_status moberg_digital_in_close( return MOBERG_ERRNO(EINVAL); } struct moberg_status result = channel->close(channel); + moberg->open_channels--; + free_if_unused(moberg); if (! OK(result)) { return result; } @@ -451,6 +460,7 @@ struct moberg_status moberg_digital_out_open( if (! OK(result)) { return result; } + moberg->open_channels++; *digital_out = channel->action.digital_out; return MOBERG_OK; } @@ -469,6 +479,8 @@ struct moberg_status moberg_digital_out_close( return MOBERG_ERRNO(EINVAL); } struct moberg_status result = channel->close(channel); + moberg->open_channels--; + free_if_unused(moberg); if (! OK(result)) { return result; } @@ -492,6 +504,7 @@ struct moberg_status moberg_encoder_in_open( if (! OK(result)) { return result; } + moberg->open_channels++; *encoder_in = channel->action.encoder_in; return MOBERG_OK; } @@ -510,6 +523,8 @@ struct moberg_status moberg_encoder_in_close( return MOBERG_ERRNO(EINVAL); } struct moberg_status result = channel->close(channel); + moberg->open_channels--; + free_if_unused(moberg); if (! OK(result)) { return result; }