1 /*
2 * Copyright © 2012 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <stdarg.h>
29 #include <string.h>
30 #include <assert.h>
31 #include <sys/socket.h>
32 #include <unistd.h>
33 #include <errno.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36
37 #include "wayland-private.h"
38 #include "wayland-server.h"
39 #include "test-runner.h"
40
41 struct client_destroy_listener {
42 struct wl_listener listener;
43 bool done;
44 struct wl_listener late_listener;
45 bool late_done;
46 struct wl_listener resource_listener;
47 bool resource_done;
48 };
49
50 static void
client_destroy_notify(struct wl_listener * l,void * data)51 client_destroy_notify(struct wl_listener *l, void *data)
52 {
53 struct client_destroy_listener *listener =
54 wl_container_of(l, listener, listener);
55
56 listener->done = true;
57 assert(!listener->resource_done);
58 assert(!listener->late_done);
59 }
60
61 static void
client_resource_destroy_notify(struct wl_listener * l,void * data)62 client_resource_destroy_notify(struct wl_listener *l, void *data)
63 {
64 struct client_destroy_listener *listener =
65 wl_container_of(l, listener, resource_listener);
66
67 assert(listener->done);
68 listener->resource_done = true;
69 assert(!listener->late_done);
70 }
71
72 static void
client_late_destroy_notify(struct wl_listener * l,void * data)73 client_late_destroy_notify(struct wl_listener *l, void *data)
74 {
75 struct client_destroy_listener *listener =
76 wl_container_of(l, listener, late_listener);
77
78 assert(listener->done);
79 assert(listener->resource_done);
80 listener->late_done = true;
81 }
82
TEST(client_destroy_listener)83 TEST(client_destroy_listener)
84 {
85 struct wl_display *display;
86 struct wl_client *client;
87 struct wl_resource *resource;
88 struct client_destroy_listener a, b;
89 int s[2];
90
91 assert(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, s) == 0);
92 display = wl_display_create();
93 assert(display);
94 client = wl_client_create(display, s[0]);
95 assert(client);
96
97 resource = wl_resource_create(client, &wl_callback_interface, 1, 0);
98 assert(resource);
99
100 a.listener.notify = client_destroy_notify;
101 a.done = false;
102 a.resource_listener.notify = client_resource_destroy_notify;
103 a.resource_done = false;
104 a.late_listener.notify = client_late_destroy_notify;
105 a.late_done = false;
106 wl_client_add_destroy_listener(client, &a.listener);
107 wl_resource_add_destroy_listener(resource, &a.resource_listener);
108 wl_client_add_destroy_late_listener(client, &a.late_listener);
109
110 assert(wl_client_get_destroy_listener(client, client_destroy_notify) ==
111 &a.listener);
112 assert(wl_resource_get_destroy_listener(resource, client_resource_destroy_notify) ==
113 &a.resource_listener);
114 assert(wl_client_get_destroy_late_listener(client, client_late_destroy_notify) ==
115 &a.late_listener);
116
117 b.listener.notify = client_destroy_notify;
118 b.done = false;
119 b.resource_listener.notify = client_resource_destroy_notify;
120 b.resource_done = false;
121 b.late_listener.notify = client_late_destroy_notify;
122 b.late_done = false;
123 wl_client_add_destroy_listener(client, &b.listener);
124 wl_resource_add_destroy_listener(resource, &b.resource_listener);
125 wl_client_add_destroy_late_listener(client, &b.late_listener);
126
127 wl_list_remove(&a.listener.link);
128 wl_list_remove(&a.resource_listener.link);
129 wl_list_remove(&a.late_listener.link);
130
131 wl_client_destroy(client);
132
133 assert(!a.done);
134 assert(!a.resource_done);
135 assert(!a.late_done);
136 assert(b.done);
137 assert(b.resource_done);
138 assert(b.late_done);
139
140 close(s[0]);
141 close(s[1]);
142
143 wl_display_destroy(display);
144 }
145
146