systemd/adapt: fix potential crash invoking sd_event_source callbacks

It is common that the callbacks unref the event source. Hence we must
ensure that the @source stays alive until the callback returns.

(cherry picked from commit 9901047ae3)
This commit is contained in:
Thomas Haller 2015-09-22 12:44:14 +02:00
parent 8c08014f47
commit 55e46923c0

View file

@ -91,6 +91,7 @@ static gboolean
io_ready (GIOChannel *channel, GIOCondition condition, struct sd_event_source *source)
{
int r, revents = 0;
gboolean result;
if (condition & G_IO_IN)
revents |= EPOLLIN;
@ -103,13 +104,18 @@ io_ready (GIOChannel *channel, GIOCondition condition, struct sd_event_source *s
if (condition & G_IO_HUP)
revents |= EPOLLHUP;
r = source->io_cb (source, g_io_channel_unix_get_fd (channel), revents, source->user_data);
if (r < 0) {
source->id = 0;
return G_SOURCE_REMOVE;
}
source->refcount++;
return G_SOURCE_CONTINUE;
r = source->io_cb (source, g_io_channel_unix_get_fd (channel), revents, source->user_data);
if (r < 0 || source->refcount <= 1) {
source->id = 0;
result = G_SOURCE_REMOVE;
} else
result = G_SOURCE_CONTINUE;
sd_event_source_unref (source);
return result;
}
int
@ -151,14 +157,20 @@ static gboolean
time_ready (struct sd_event_source *source)
{
int r;
gboolean result;
source->refcount++;
r = source->time_cb (source, source->usec, source->user_data);
if (r < 0) {
if (r < 0 || source->refcount <= 1) {
source->id = 0;
return G_SOURCE_REMOVE;
}
result = G_SOURCE_REMOVE;
} else
result = G_SOURCE_CONTINUE;
return G_SOURCE_CONTINUE;
sd_event_source_unref (source);
return result;
}
int