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
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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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")
......
......@@ -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,18 +257,7 @@ 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);
......@@ -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;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment