Codebase list wayland / f74c9b9
tests: Add a test for fd leaks on zombie objects Until recently, if a client destroying a resource raced with the server generating an event on that resource that delivered a file descriptor, we would leak the fd. This tests for a leaked fd from that race condition. Reviewed-by: Daniel Stone <daniels@collabora.com> Signed-off-by: Derek Foreman <derekf@osg.samsung.com> Derek Foreman authored 6 years ago Daniel Stone committed 6 years ago
3 changed file(s) with 151 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
113113 BUILT_SOURCES = \
114114 $(nodist_libwayland_server_la_SOURCES) \
115115 $(nodist_libwayland_client_la_SOURCES) \
116 $(nodist_headers_test_SOURCES)
116 $(nodist_headers_test_SOURCES) \
117 $(nodist_display_test_SOURCES)
117118
118119 CLEANFILES = $(BUILT_SOURCES) doc/doxygen/doxygen_sqlite3.db
119120 DISTCLEANFILES = src/wayland-version.h
205206 client_test_LDADD = libtest-runner.la
206207 display_test_SOURCES = tests/display-test.c
207208 display_test_LDADD = libtest-runner.la
209 nodist_display_test_SOURCES = \
210 protocol/tests-server-protocol.h \
211 protocol/tests-client-protocol.h \
212 protocol/tests-protocol.c
208213 connection_test_SOURCES = tests/connection-test.c
209214 connection_test_LDADD = libtest-runner.la
210215 event_loop_test_SOURCES = tests/event-loop-test.c
0 <?xml version="1.0" encoding="UTF-8"?>
1 <protocol name="build_time_wayland_tests">
2
3 <copyright>
4 Copyright © 2017 Samsung Electronics Co., Ltd
5
6 Permission is hereby granted, free of charge, to any person
7 obtaining a copy of this software and associated documentation files
8 (the "Software"), to deal in the Software without restriction,
9 including without limitation the rights to use, copy, modify, merge,
10 publish, distribute, sublicense, and/or sell copies of the Software,
11 and to permit persons to whom the Software is furnished to do so,
12 subject to the following conditions:
13
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial
16 portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 SOFTWARE.
26 </copyright>
27
28 <interface name="fd_passer" version="1">
29 <description summary="Sends an event with an fd">
30 A trivial interface for fd passing tests.
31 </description>
32
33 <request name="destroy" type="destructor"/>
34
35 <event name="pre_fd"/>
36
37 <event name="fd">
38 <description summary="passes a file descriptor"/>
39 <arg name="fd" type="fd" summary="file descriptor"/>
40 </event>
41 </interface>
42 </protocol>
4646 #include "test-runner.h"
4747 #include "test-compositor.h"
4848
49 #include "tests-server-protocol.h"
50 #include "tests-client-protocol.h"
51
4952 struct display_destroy_listener {
5053 struct wl_listener listener;
5154 int done;
10651068
10661069 display_destroy(d);
10671070 }
1071
1072 static void
1073 pre_fd(void *data, struct fd_passer *fdp)
1074 {
1075 fd_passer_destroy(fdp);
1076 }
1077
1078 static void
1079 fd(void *data, struct fd_passer *fdp, int32_t fd)
1080 {
1081 /* We destroyed the resource before this event */
1082 assert(false);
1083 }
1084
1085 struct fd_passer_listener fd_passer_listener = {
1086 pre_fd,
1087 fd,
1088 };
1089
1090 static void
1091 zombie_fd_handle_globals(void *data, struct wl_registry *registry,
1092 uint32_t id, const char *intf, uint32_t ver)
1093 {
1094 struct fd_passer *fdp;
1095
1096 if (!strcmp(intf, "fd_passer")) {
1097 fdp = wl_registry_bind(registry, id, &fd_passer_interface, 1);
1098 fd_passer_add_listener(fdp, &fd_passer_listener, NULL);
1099 }
1100 }
1101
1102 static const struct wl_registry_listener zombie_fd_registry_listener = {
1103 zombie_fd_handle_globals,
1104 NULL
1105 };
1106
1107 static void
1108 zombie_client(void *data)
1109 {
1110 struct client *c = client_connect();
1111 struct wl_registry *registry;
1112
1113 registry = wl_display_get_registry(c->wl_display);
1114 wl_registry_add_listener(registry, &zombie_fd_registry_listener, NULL);
1115
1116 /* Gets the registry */
1117 wl_display_roundtrip(c->wl_display);
1118
1119 /* push out the fd_passer bind */
1120 wl_display_roundtrip(c->wl_display);
1121
1122 /* push out our fd_passer.destroy */
1123 wl_display_roundtrip(c->wl_display);
1124
1125 wl_registry_destroy(registry);
1126
1127 client_disconnect_nocheck(c);
1128 }
1129
1130 static void
1131 fd_passer_clobber(struct wl_client *client, struct wl_resource *res)
1132 {
1133 wl_resource_destroy(res);
1134 }
1135
1136 static const struct fd_passer_interface fdp_interface = {
1137 fd_passer_clobber,
1138 };
1139
1140 static void
1141 bind_fd_passer(struct wl_client *client, void *data,
1142 uint32_t vers, uint32_t id)
1143 {
1144 struct wl_resource *res;
1145
1146 res = wl_resource_create(client, &fd_passer_interface, vers, id);
1147 wl_resource_set_implementation(res, &fdp_interface, NULL, NULL);
1148 assert(res);
1149 fd_passer_send_pre_fd(res);
1150 fd_passer_send_fd(res, fileno(stdin));
1151 }
1152
1153 TEST(zombie_fd)
1154 {
1155 struct display *d;
1156 struct wl_global *g;
1157
1158 d = display_create();
1159
1160 g = wl_global_create(d->wl_display, &fd_passer_interface,
1161 1, d, bind_fd_passer);
1162
1163 client_create_noarg(d, zombie_client);
1164 display_run(d);
1165
1166 wl_global_destroy(g);
1167
1168 display_destroy(d);
1169 }