diff --git a/src/shared/io-glib.c b/src/shared/io-glib.c
index ea84a69..488b1a2 100644
--- a/src/shared/io-glib.c
+++ b/src/shared/io-glib.c
#include "src/shared/io.h"
struct io {
+ int ref_count;
GIOChannel *channel;
guint read_watch;
io_callback_func_t read_callback;
void *write_data;
};
+static struct io *io_ref(struct io *io)
+{
+ if (!io)
+ return NULL;
+
+ __sync_fetch_and_add(&io->ref_count, 1);
+
+ return io;
+}
+
+static void io_unref(struct io *io)
+{
+ if (!io)
+ return;
+
+ if (__sync_sub_and_fetch(&io->ref_count, 1))
+ return;
+
+ g_free(io);
+}
+
struct io *io_new(int fd)
{
struct io *io;
io->write_destroy = NULL;
io->write_data = NULL;
- return io;
+ return io_ref(io);
}
void io_destroy(struct io *io)
if (!io)
return;
- if (io->read_watch > 0)
+ if (io->read_watch > 0) {
g_source_remove(io->read_watch);
+ io->read_watch = 0;
+ }
- if (io->write_watch > 0)
+ if (io->write_watch > 0) {
g_source_remove(io->write_watch);
+ io->write_watch = 0;
+ }
g_io_channel_unref(io->channel);
+ io->channel = NULL;
- g_free(io);
+ io_unref(io);
}
int io_get_fd(struct io *io)
io->read_callback = NULL;
io->read_destroy = NULL;
io->read_data = NULL;
+
+ io_unref(io);
}
static gboolean read_callback(GIOChannel *channel, GIOCondition cond,
io->read_watch = g_io_add_watch_full(io->channel, G_PRIORITY_DEFAULT,
G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- read_callback, io, read_watch_destroy);
+ read_callback, io_ref(io),
+ read_watch_destroy);
if (io->read_watch == 0)
return false;
io->write_callback = NULL;
io->write_destroy = NULL;
io->write_data = NULL;
+
+ io_unref(io);
}
static gboolean write_callback(GIOChannel *channel, GIOCondition cond,
io->write_watch = g_io_add_watch_full(io->channel, G_PRIORITY_DEFAULT,
G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- write_callback, io, write_watch_destroy);
+ write_callback, io_ref(io),
+ write_watch_destroy);
if (io->write_watch == 0)
return false;