summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Chalupa <mchqwerty@gmail.com>2014-12-19 14:53:03 +0100
committerDaniel Stone <daniels@collabora.com>2015-01-28 17:17:13 +0000
commit2e20270280756cbf7387d5e4269e5c9c7c8a0e5b (patch)
treee22188ceec5df040ec388d481331ec870217e01f
parentd1855797d33f0153ccf2c775d62b731f25b2625f (diff)
downloadwayland-2e20270280756cbf7387d5e4269e5c9c7c8a0e5b.tar.gz
connection-test: add tests for closure leaks
When we destroy closure, we are leaking memory sometimes. Signed-off-by: Marek Chalupa <mchqwerty@gmail.com> Reviewed-by: Daniel Stone <daniels@collabora.com>
-rw-r--r--tests/connection-test.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/tests/connection-test.c b/tests/connection-test.c
index 4497128..d34e9a5 100644
--- a/tests/connection-test.c
+++ b/tests/connection-test.c
@@ -31,9 +31,11 @@
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <poll.h>
#include "wayland-private.h"
#include "test-runner.h"
+#include "test-compositor.h"
static const char message[] = "Hello, world";
@@ -571,3 +573,80 @@ TEST(invoke_closure)
{
marshal_helper("suu", suu_handler, "foo", 500, 404040);
}
+
+static void
+leak_closure(void)
+{
+ struct wl_callback *cb;
+ struct pollfd pfd;
+ struct client *c = client_connect();
+
+ cb = wl_display_sync(c->wl_display);
+ assert(cb);
+ assert(wl_display_flush(c->wl_display) > 0);
+
+ /* we don't need it, it is referenced */
+ wl_callback_destroy(cb);
+
+ pfd.fd = wl_display_get_fd(c->wl_display);
+ pfd.events = POLLIN;
+
+ test_set_timeout(2);
+ assert(poll(&pfd, 1, -1) == 1);
+
+ /* read events, but do not dispatch them */
+ assert(wl_display_prepare_read(c->wl_display) == 0);
+ assert(wl_display_read_events(c->wl_display) == 0);
+
+ /*
+ * now we have wl_callback.done and wl_display.delete_id queued;
+ * if we now release the queue (in wl_display_disconnect())
+ * we should not leak memory
+ */
+
+ client_disconnect(c);
+}
+
+TEST(closure_leaks)
+{
+ struct display *d = display_create();
+
+ client_create(d, leak_closure);
+ display_run(d);
+
+ display_destroy(d);
+}
+
+static void
+leak_after_error(void)
+{
+ struct client *c = client_connect();
+
+ /* this should return -1, because we'll send error
+ * from server. */
+ assert(stop_display(c, 1) == -1);
+ assert(wl_display_dispatch_pending(c->wl_display) == -1);
+ assert(wl_display_get_error(c->wl_display) == ENOMEM);
+
+ /* after we got error, we have display_resume event
+ * in the queue. It should be freed in wl_display_disconnect().
+ * Let's see! */
+
+ wl_proxy_destroy((struct wl_proxy *) c->tc);
+ wl_display_disconnect(c->wl_display);
+ free(c);
+}
+
+TEST(closure_leaks_after_error)
+{
+ struct display *d = display_create();
+ struct client_info *cl;
+
+ cl = client_create(d, leak_after_error);
+ display_run(d);
+
+ wl_client_post_no_memory(cl->wl_client);
+ display_resume(d);
+
+ display_destroy(d);
+}