Add a destroy signal to the wl_event_loop object
authorJason Ekstrand <jason@jlekstrand.net>
Sat, 12 Jan 2013 03:01:47 +0000 (21:01 -0600)
committerKristian Høgsberg <krh@bitplanet.net>
Tue, 15 Jan 2013 19:28:29 +0000 (14:28 -0500)
src/event-loop.c
src/wayland-server.h
tests/event-loop-test.c

index 8db9c7c..25e8f9c 100644 (file)
@@ -43,6 +43,8 @@ struct wl_event_loop {
        struct wl_list check_list;
        struct wl_list idle_list;
        struct wl_list destroy_list;
+
+       struct wl_signal destroy_signal;
 };
 
 struct wl_event_source_interface {
@@ -357,12 +359,16 @@ wl_event_loop_create(void)
        wl_list_init(&loop->idle_list);
        wl_list_init(&loop->destroy_list);
 
+       wl_signal_init(&loop->destroy_signal);
+
        return loop;
 }
 
 WL_EXPORT void
 wl_event_loop_destroy(struct wl_event_loop *loop)
 {
+       wl_signal_emit(&loop->destroy_signal, loop);
+
        wl_event_loop_process_destroy_list(loop);
        close(loop->epoll_fd);
        free(loop);
@@ -429,3 +435,18 @@ wl_event_loop_get_fd(struct wl_event_loop *loop)
 {
        return loop->epoll_fd;
 }
+
+WL_EXPORT void
+wl_event_loop_add_destroy_listener(struct wl_event_loop *loop,
+                                  struct wl_listener *listener)
+{
+       wl_signal_add(&loop->destroy_signal, listener);
+}
+
+WL_EXPORT struct wl_listener *
+wl_event_loop_get_destroy_listener(struct wl_event_loop *loop,
+                                  wl_notify_func_t notify)
+{
+       wl_signal_get(&loop->destroy_signal, notify);
+}
+
index 576304f..c7369eb 100644 (file)
@@ -84,6 +84,12 @@ struct wl_touch;
 struct wl_listener;
 typedef void (*wl_notify_func_t)(struct wl_listener *listener, void *data);
 
+void wl_event_loop_add_destroy_listener(struct wl_event_loop *loop,
+                                       struct wl_listener * listener);
+struct wl_listener *wl_event_loop_get_destroy_listener(
+                                       struct wl_event_loop *loop,
+                                       wl_notify_func_t notify);
+
 struct wl_display *wl_display_create(void);
 void wl_display_destroy(struct wl_display *display);
 struct wl_event_loop *wl_display_get_event_loop(struct wl_display *display);
index 2f3dcd4..c46d3b0 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2012 Intel Corporation
+ * Copyright © 2012 Jason Ekstrand
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -25,6 +26,7 @@
 #include <unistd.h>
 #include <signal.h>
 #include "wayland-server.h"
+#include "wayland-private.h"
 #include "test-runner.h"
 
 static int
@@ -190,3 +192,58 @@ TEST(event_loop_timer)
        wl_event_source_remove(source);
        wl_event_loop_destroy(loop);
 }
+
+struct event_loop_destroy_listener {
+       struct wl_listener listener;
+       int done;
+};
+
+static void
+event_loop_destroy_notify(struct wl_listener *l, void *data)
+{
+       struct event_loop_destroy_listener *listener =
+               container_of(l, struct event_loop_destroy_listener, listener);
+
+       listener->done = 1;
+}
+
+TEST(event_loop_destroy)
+{
+       struct wl_event_loop *loop;
+       struct wl_display * display;
+       struct event_loop_destroy_listener a, b;
+
+       loop = wl_event_loop_create();
+       assert(loop);
+
+       a.listener.notify = &event_loop_destroy_notify;
+       a.done = 0;
+       wl_event_loop_add_destroy_listener(loop, &a.listener);
+
+       assert(wl_event_loop_get_destroy_listener(loop,
+              event_loop_destroy_notify) == &a.listener);
+
+       b.listener.notify = &event_loop_destroy_notify;
+       b.done = 0;
+       wl_event_loop_add_destroy_listener(loop, &b.listener);
+
+       wl_list_remove(&a.listener.link);
+       wl_event_loop_destroy(loop);
+
+       assert(!a.done);
+       assert(b.done);
+
+       /* Test to make sure it gets fired on display destruction */
+       display = wl_display_create();
+       assert(display);
+       loop = wl_display_get_event_loop(display);
+       assert(loop);
+
+       a.done = 0;
+       wl_event_loop_add_destroy_listener(loop, &a.listener);
+
+       wl_display_destroy(display);
+
+       assert(a.done);
+}
+