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
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;
}
......
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