connection: Leave fd open in wl_connection_destroy

Calling close() on the same file descriptor that a previous call to
close() already closed is wrong, and racy if another thread received
that same file descriptor as a eg. new socket or actual file.

There are two situations where wl_connection_destroy() would close its
file descriptor and then another function up in the call chain would
close the same file descriptor:

  * When wl_client_create() fails after calling wl_connection_create(),
    it will call wl_connection_destroy() before returning. However, its
    caller will always close the file descriptor if wl_client_create()
    fails.

  * wl_display_disconnect() unconditionally closes the display file
    descriptor and also calls wl_connection_destroy().

So these two seem to expect wl_connection_destroy() to leave the file
descriptor open. The other caller of wl_connection_destroy(),
wl_client_destroy(), does however expect wl_connection_destroy() to
close its file descriptor, alas.

This patch changes wl_connection_destroy() to indulge this majority of
two callers by simply not closing the file descriptor. For the benefit
of wl_client_destroy(), wl_connection_destroy() then returns the
unclosed file descriptor so that wl_client_destroy() can close it
itself.

Since wl_connection_destroy() is a private function called from few
places, changing its semantics seemed like the more expedient way to
address the double-close() problem than shuffling around the logic in
wl_client_create() to somehow enable it to always avoid calling
wl_connection_destroy().

Signed-off-by: Benjamin Herr <ben@0x539.de>
Reviewed-by: Marek Chalupa <mchqwerty@gmail.com>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
This commit is contained in:
Benjamin Herr 2014-09-30 14:43:03 +02:00 committed by Pekka Paalanen
parent 4a661c5b0c
commit 391820b0d6
4 changed files with 13 additions and 6 deletions

View file

@ -57,6 +57,7 @@ TEST(connection_create)
connection = setup(s);
wl_connection_destroy(connection);
close(s[0]);
close(s[1]);
}
@ -74,6 +75,7 @@ TEST(connection_write)
assert(memcmp(message, buffer, sizeof message) == 0);
wl_connection_destroy(connection);
close(s[0]);
close(s[1]);
}
@ -92,6 +94,7 @@ TEST(connection_data)
wl_connection_consume(connection, sizeof message);
wl_connection_destroy(connection);
close(s[0]);
close(s[1]);
}
@ -117,6 +120,7 @@ TEST(connection_queue)
assert(memcmp(message, buffer + sizeof message, sizeof message) == 0);
wl_connection_destroy(connection);
close(s[0]);
close(s[1]);
}
@ -147,8 +151,8 @@ setup_marshal_data(struct marshal_data *data)
static void
release_marshal_data(struct marshal_data *data)
{
wl_connection_destroy(data->read_connection);
wl_connection_destroy(data->write_connection);
close(wl_connection_destroy(data->read_connection));
close(wl_connection_destroy(data->write_connection));
}
static void