Commit 88aa7def authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Change closing logic to accomodate Julias lack of finalizer order

parent b7076b2a
...@@ -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,19 +257,8 @@ struct moberg *moberg_new() ...@@ -255,19 +257,8 @@ 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);
const char * const *path; const char * const *path;
...@@ -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;
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment