Skip to content
Snippets Groups Projects
Commit 88aa7def authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Change closing logic to accomodate Julias lack of finalizer order

parent b7076b2a
Branches
Tags v0.9
No related merge requests found
...@@ -4,16 +4,17 @@ mutable struct AnalogInChannel ...@@ -4,16 +4,17 @@ mutable struct AnalogInChannel
end end
mutable struct AnalogIn mutable struct AnalogIn
moberg::Moberg moberg::Ptr{Nothing}
index::UInt32 index::UInt32
channel::AnalogInChannel channel::AnalogInChannel
function AnalogIn(moberg::Moberg, index::Unsigned) function AnalogIn(moberg::Moberg, index::Unsigned)
channel = AnalogInChannel(0,0) channel = AnalogInChannel(0,0)
moberg_handle = moberg.handle
checkOK(ccall((:moberg_analog_in_open, "libmoberg"), checkOK(ccall((:moberg_analog_in_open, "libmoberg"),
Status, Status,
(Moberg, Cint, Ref{AnalogInChannel}), (Ptr{Nothing}, Cint, Ref{AnalogInChannel}),
moberg, index, channel)) moberg_handle, index, channel))
self = new(moberg, index, channel) self = new(moberg_handle, index, channel)
finalizer(close, self) finalizer(close, self)
self self
end end
...@@ -23,7 +24,7 @@ function close(ain::AnalogIn) ...@@ -23,7 +24,7 @@ function close(ain::AnalogIn)
DEBUG && println("closing $(ain)") DEBUG && println("closing $(ain)")
checkOK(ccall((:moberg_analog_in_close, "libmoberg"), checkOK(ccall((:moberg_analog_in_close, "libmoberg"),
Status, Status,
(Moberg, Cint, AnalogInChannel), (Ptr{Nothing}, Cint, AnalogInChannel),
ain.moberg, ain.index, ain.channel)) ain.moberg, ain.index, ain.channel))
end end
......
...@@ -4,16 +4,17 @@ mutable struct AnalogOutChannel ...@@ -4,16 +4,17 @@ mutable struct AnalogOutChannel
end end
mutable struct AnalogOut mutable struct AnalogOut
moberg::Moberg moberg::Ptr{Nothing}
index::UInt32 index::UInt32
channel::AnalogOutChannel channel::AnalogOutChannel
function AnalogOut(moberg::Moberg, index::Unsigned) function AnalogOut(moberg::Moberg, index::Unsigned)
channel = AnalogOutChannel(0,0) channel = AnalogOutChannel(0,0)
moberg_handle = moberg.handle
checkOK(ccall((:moberg_analog_out_open, "libmoberg"), checkOK(ccall((:moberg_analog_out_open, "libmoberg"),
Status, Status,
(Moberg, Cint, Ref{AnalogOutChannel}), (Ptr{Nothing}, Cint, Ref{AnalogOutChannel}),
moberg, index, channel)); moberg_handle, index, channel));
self = new(moberg, index, channel) self = new(moberg_handle, index, channel)
finalizer(close, self) finalizer(close, self)
self self
end end
...@@ -23,7 +24,7 @@ function close(aout::AnalogOut) ...@@ -23,7 +24,7 @@ function close(aout::AnalogOut)
DEBUG && println("closing $(aout)") DEBUG && println("closing $(aout)")
checkOK(ccall((:moberg_analog_out_close, "libmoberg"), checkOK(ccall((:moberg_analog_out_close, "libmoberg"),
Status, Status,
(Moberg, Cint, AnalogOutChannel), (Ptr{Nothing}, Cint, AnalogOutChannel),
aout.moberg, aout.index, aout.channel)) aout.moberg, aout.index, aout.channel))
end end
......
...@@ -4,16 +4,17 @@ mutable struct DigitalInChannel ...@@ -4,16 +4,17 @@ mutable struct DigitalInChannel
end end
mutable struct DigitalIn mutable struct DigitalIn
moberg::Moberg moberg::Ptr{Nothing}
index::UInt32 index::UInt32
channel::DigitalInChannel channel::DigitalInChannel
function DigitalIn(moberg::Moberg, index::Unsigned) function DigitalIn(moberg::Moberg, index::Unsigned)
channel = DigitalInChannel(0,0) channel = DigitalInChannel(0,0)
moberg_handle = moberg.handle
checkOK(ccall((:moberg_digital_in_open, "libmoberg"), checkOK(ccall((:moberg_digital_in_open, "libmoberg"),
Status, Status,
(Moberg, Cint, Ref{DigitalInChannel}), (Ptr{Nothing}, Cint, Ref{DigitalInChannel}),
moberg, index, channel)); moberg_handle, index, channel));
self = new(moberg, index, channel) self = new(moberg_handle, index, channel)
finalizer(close, self) finalizer(close, self)
self self
end end
...@@ -23,7 +24,7 @@ function close(din::DigitalIn) ...@@ -23,7 +24,7 @@ function close(din::DigitalIn)
DEBUG && println("closing $(din)") DEBUG && println("closing $(din)")
checkOK(ccall((:moberg_digital_in_close, "libmoberg"), checkOK(ccall((:moberg_digital_in_close, "libmoberg"),
Status, Status,
(Moberg, Cint, DigitalInChannel), (Ptr{Nothing}, Cint, DigitalInChannel),
din.moberg, din.index, din.channel)) din.moberg, din.index, din.channel))
end end
......
...@@ -4,16 +4,17 @@ mutable struct DigitalOutChannel ...@@ -4,16 +4,17 @@ mutable struct DigitalOutChannel
end end
mutable struct DigitalOut mutable struct DigitalOut
moberg::Moberg moberg::Ptr{Nothing}
index::UInt32 index::UInt32
channel::DigitalOutChannel channel::DigitalOutChannel
function DigitalOut(moberg::Moberg, index::Unsigned) function DigitalOut(moberg::Moberg, index::Unsigned)
channel = DigitalOutChannel(0,0) channel = DigitalOutChannel(0,0)
moberg_handle = moberg.handle
checkOK(ccall((:moberg_digital_out_open, "libmoberg"), checkOK(ccall((:moberg_digital_out_open, "libmoberg"),
Status, Status,
(Moberg, Cint, Ref{DigitalOutChannel}), (Ptr{Nothing}, Cint, Ref{DigitalOutChannel}),
moberg, index, channel)) moberg_handle, index, channel))
self = new(moberg, index, channel) self = new(moberg_handle, index, channel)
finalizer(close, self) finalizer(close, self)
self self
end end
...@@ -23,7 +24,7 @@ function close(dout::DigitalOut) ...@@ -23,7 +24,7 @@ function close(dout::DigitalOut)
DEBUG && println("closing $(dout)") DEBUG && println("closing $(dout)")
checkOK(ccall((:moberg_digital_out_close, "libmoberg"), checkOK(ccall((:moberg_digital_out_close, "libmoberg"),
Status, Status,
(Moberg, Cint, DigitalOutChannel), (Ptr{Nothing}, Cint, DigitalOutChannel),
dout.moberg, dout.index, dout.channel)) dout.moberg, dout.index, dout.channel))
end end
......
...@@ -4,16 +4,17 @@ mutable struct EncoderInChannel ...@@ -4,16 +4,17 @@ mutable struct EncoderInChannel
end end
mutable struct EncoderIn mutable struct EncoderIn
moberg::Moberg moberg::Ptr{Nothing}
index::UInt32 index::UInt32
channel::EncoderInChannel channel::EncoderInChannel
function EncoderIn(moberg::Moberg, index::Unsigned) function EncoderIn(moberg::Moberg, index::Unsigned)
channel = EncoderInChannel(0,0) channel = EncoderInChannel(0,0)
moberg_handle = moberg.handle
checkOK(ccall((:moberg_encoder_in_open, "libmoberg"), checkOK(ccall((:moberg_encoder_in_open, "libmoberg"),
Status, Status,
(Moberg, Cint, Ref{EncoderInChannel}), (Ptr{Nothing}, Cint, Ref{EncoderInChannel}),
moberg, index, channel)) moberg_handle, index, channel))
self = new(moberg, index, channel) self = new(moberg_handle, index, channel)
finalizer(close, self) finalizer(close, self)
self self
end end
...@@ -23,7 +24,7 @@ function close(ein::EncoderIn) ...@@ -23,7 +24,7 @@ function close(ein::EncoderIn)
DEBUG && println("closing $(ein)") DEBUG && println("closing $(ein)")
checkOK(ccall((:moberg_encoder_in_close, "libmoberg"), checkOK(ccall((:moberg_encoder_in_close, "libmoberg"),
Status, Status,
(Moberg, Cint, EncoderInChannel), (Ptr{Nothing}, Cint, EncoderInChannel),
ein.moberg, ein.index, ein.channel)) ein.moberg, ein.index, ein.channel))
end end
......
...@@ -26,6 +26,7 @@ end ...@@ -26,6 +26,7 @@ end
function close(h::Moberg) function close(h::Moberg)
DEBUG && println("Destroy $(h)") DEBUG && println("Destroy $(h)")
ccall((:moberg_free, "libmoberg"), Nothing, (Moberg,), h) ccall((:moberg_free, "libmoberg"), Nothing, (Moberg,), h)
h.handle = Ptr{Nothing}(0)
end end
include("AnalogIn.jl") include("AnalogIn.jl")
......
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
#include <moberg_parser.h> #include <moberg_parser.h>
struct moberg { struct moberg {
int should_free;
int open_channels;
struct moberg_config *config; struct moberg_config *config;
struct channel_list { struct channel_list {
int capacity; int capacity;
...@@ -255,18 +257,7 @@ struct moberg *moberg_new() ...@@ -255,18 +257,7 @@ struct moberg *moberg_new()
fprintf(stderr, "Failed to allocate moberg struct\n"); fprintf(stderr, "Failed to allocate moberg struct\n");
goto err; goto err;
} }
result->analog_in.capacity = 0; memset(result, 0, sizeof(*result));
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;
/* Parse default configuration(s) */ /* Parse default configuration(s) */
const char * const *config_paths = xdgSearchableConfigDirectories(NULL); const char * const *config_paths = xdgSearchableConfigDirectories(NULL);
...@@ -295,9 +286,9 @@ err: ...@@ -295,9 +286,9 @@ err:
return result; 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); moberg_config_free(moberg->config);
channel_list_free(&moberg->analog_in); channel_list_free(&moberg->analog_in);
channel_list_free(&moberg->analog_out); channel_list_free(&moberg->analog_out);
...@@ -309,6 +300,15 @@ void moberg_free(struct moberg *moberg) ...@@ -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 */ /* Input/output */
struct moberg_status moberg_analog_in_open( struct moberg_status moberg_analog_in_open(
...@@ -328,6 +328,7 @@ struct moberg_status moberg_analog_in_open( ...@@ -328,6 +328,7 @@ struct moberg_status moberg_analog_in_open(
if (! OK(result)) { if (! OK(result)) {
return result; return result;
} }
moberg->open_channels++;
*analog_in = channel->action.analog_in; *analog_in = channel->action.analog_in;
return MOBERG_OK; return MOBERG_OK;
} }
...@@ -346,6 +347,8 @@ struct moberg_status moberg_analog_in_close( ...@@ -346,6 +347,8 @@ struct moberg_status moberg_analog_in_close(
return MOBERG_ERRNO(EINVAL); return MOBERG_ERRNO(EINVAL);
} }
struct moberg_status result = channel->close(channel); struct moberg_status result = channel->close(channel);
moberg->open_channels--;
free_if_unused(moberg);
if (! OK(result)) { if (! OK(result)) {
return result; return result;
} }
...@@ -369,6 +372,7 @@ struct moberg_status moberg_analog_out_open( ...@@ -369,6 +372,7 @@ struct moberg_status moberg_analog_out_open(
if (! OK(result)) { if (! OK(result)) {
return result; return result;
} }
moberg->open_channels++;
*analog_out = channel->action.analog_out; *analog_out = channel->action.analog_out;
return MOBERG_OK; return MOBERG_OK;
} }
...@@ -387,6 +391,8 @@ struct moberg_status moberg_analog_out_close( ...@@ -387,6 +391,8 @@ struct moberg_status moberg_analog_out_close(
return MOBERG_ERRNO(EINVAL); return MOBERG_ERRNO(EINVAL);
} }
struct moberg_status result = channel->close(channel); struct moberg_status result = channel->close(channel);
moberg->open_channels--;
free_if_unused(moberg);
if (! OK(result)) { if (! OK(result)) {
return result; return result;
} }
...@@ -410,6 +416,7 @@ struct moberg_status moberg_digital_in_open( ...@@ -410,6 +416,7 @@ struct moberg_status moberg_digital_in_open(
if (! OK(result)) { if (! OK(result)) {
return result; return result;
} }
moberg->open_channels++;
*digital_in = channel->action.digital_in; *digital_in = channel->action.digital_in;
return MOBERG_OK; return MOBERG_OK;
} }
...@@ -428,6 +435,8 @@ struct moberg_status moberg_digital_in_close( ...@@ -428,6 +435,8 @@ struct moberg_status moberg_digital_in_close(
return MOBERG_ERRNO(EINVAL); return MOBERG_ERRNO(EINVAL);
} }
struct moberg_status result = channel->close(channel); struct moberg_status result = channel->close(channel);
moberg->open_channels--;
free_if_unused(moberg);
if (! OK(result)) { if (! OK(result)) {
return result; return result;
} }
...@@ -451,6 +460,7 @@ struct moberg_status moberg_digital_out_open( ...@@ -451,6 +460,7 @@ struct moberg_status moberg_digital_out_open(
if (! OK(result)) { if (! OK(result)) {
return result; return result;
} }
moberg->open_channels++;
*digital_out = channel->action.digital_out; *digital_out = channel->action.digital_out;
return MOBERG_OK; return MOBERG_OK;
} }
...@@ -469,6 +479,8 @@ struct moberg_status moberg_digital_out_close( ...@@ -469,6 +479,8 @@ struct moberg_status moberg_digital_out_close(
return MOBERG_ERRNO(EINVAL); return MOBERG_ERRNO(EINVAL);
} }
struct moberg_status result = channel->close(channel); struct moberg_status result = channel->close(channel);
moberg->open_channels--;
free_if_unused(moberg);
if (! OK(result)) { if (! OK(result)) {
return result; return result;
} }
...@@ -492,6 +504,7 @@ struct moberg_status moberg_encoder_in_open( ...@@ -492,6 +504,7 @@ struct moberg_status moberg_encoder_in_open(
if (! OK(result)) { if (! OK(result)) {
return result; return result;
} }
moberg->open_channels++;
*encoder_in = channel->action.encoder_in; *encoder_in = channel->action.encoder_in;
return MOBERG_OK; return MOBERG_OK;
} }
...@@ -510,6 +523,8 @@ struct moberg_status moberg_encoder_in_close( ...@@ -510,6 +523,8 @@ struct moberg_status moberg_encoder_in_close(
return MOBERG_ERRNO(EINVAL); return MOBERG_ERRNO(EINVAL);
} }
struct moberg_status result = channel->close(channel); struct moberg_status result = channel->close(channel);
moberg->open_channels--;
free_if_unused(moberg);
if (! OK(result)) { if (! OK(result)) {
return result; return result;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment