Gentoo Archives: gentoo-commits

From: Sam James <sam@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] repo/gentoo:master commit in: media-libs/gstreamer/files/, media-libs/gstreamer/
Date: Sun, 29 Jan 2023 07:33:31
Message-Id: 1674977591.2c57b02687ae18efdc6638b6562e6472167b6e8a.sam@gentoo
1 commit: 2c57b02687ae18efdc6638b6562e6472167b6e8a
2 Author: Sam James <sam <AT> gentoo <DOT> org>
3 AuthorDate: Sun Jan 29 07:29:20 2023 +0000
4 Commit: Sam James <sam <AT> gentoo <DOT> org>
5 CommitDate: Sun Jan 29 07:33:11 2023 +0000
6 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=2c57b026
7
8 media-libs/gstreamer: backport race condition fix for tests
9
10 Closes: https://bugs.gentoo.org/888986
11 Signed-off-by: Sam James <sam <AT> gentoo.org>
12
13 .../files/gstreamer-1.20.5-tests-race.patch | 293 +++++++++++++++++++++
14 media-libs/gstreamer/gstreamer-1.20.5.ebuild | 1 +
15 2 files changed, 294 insertions(+)
16
17 diff --git a/media-libs/gstreamer/files/gstreamer-1.20.5-tests-race.patch b/media-libs/gstreamer/files/gstreamer-1.20.5-tests-race.patch
18 new file mode 100644
19 index 000000000000..05b183ec3054
20 --- /dev/null
21 +++ b/media-libs/gstreamer/files/gstreamer-1.20.5-tests-race.patch
22 @@ -0,0 +1,293 @@
23 +https://bugs.gentoo.org/888986
24 +https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/ccd582c3321312fe96b28ce90fe6f2fd7adfa058
25 +
26 +From ccd582c3321312fe96b28ce90fe6f2fd7adfa058 Mon Sep 17 00:00:00 2001
27 +From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@×××××××××××.com>
28 +Date: Tue, 21 Jun 2022 11:51:35 +0300
29 +Subject: [PATCH] bin: Fix race conditions in tests
30 +
31 +The latency messages are non-deterministic and can arrive before/after
32 +async-done or during state-changes as they are posted by e.g. sinks from
33 +their streaming thread but bins are finishing asynchronous state changes
34 +from a secondary helper thread.
35 +
36 +To solve this, expect latency messages at any time and assert that we
37 +receive one at some point during the test.
38 +
39 +Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3647>
40 +--- a/tests/check/gst/gstbin.c
41 ++++ b/tests/check/gst/gstbin.c
42 +@@ -27,50 +27,95 @@
43 + #include <gst/base/gstbasesrc.h>
44 +
45 + static void
46 +-pop_async_done (GstBus * bus)
47 ++pop_async_done (GstBus * bus, gboolean * had_latency)
48 + {
49 + GstMessage *message;
50 ++ GstMessageType types = GST_MESSAGE_ASYNC_DONE;
51 ++
52 ++ if (!*had_latency)
53 ++ types |= GST_MESSAGE_LATENCY;
54 +
55 + GST_DEBUG ("popping async-done message");
56 +- message = gst_bus_poll (bus, GST_MESSAGE_ASYNC_DONE, -1);
57 +
58 +- fail_unless (message && GST_MESSAGE_TYPE (message)
59 +- == GST_MESSAGE_ASYNC_DONE, "did not get GST_MESSAGE_ASYNC_DONE");
60 ++ do {
61 ++ message = gst_bus_poll (bus, types, -1);
62 +
63 +- gst_message_unref (message);
64 +- GST_DEBUG ("popped message");
65 ++ fail_unless (message);
66 ++ GST_DEBUG ("popped message %s",
67 ++ gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
68 ++
69 ++ if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_LATENCY) {
70 ++ fail_unless (*had_latency == FALSE);
71 ++ *had_latency = TRUE;
72 ++ gst_clear_message (&message);
73 ++ types &= ~GST_MESSAGE_LATENCY;
74 ++ continue;
75 ++ }
76 ++
77 ++ fail_unless (GST_MESSAGE_TYPE (message)
78 ++ == GST_MESSAGE_ASYNC_DONE, "did not get GST_MESSAGE_ASYNC_DONE");
79 ++
80 ++ gst_clear_message (&message);
81 ++ break;
82 ++ } while (TRUE);
83 + }
84 +
85 + static void
86 +-pop_latency (GstBus * bus)
87 ++pop_latency (GstBus * bus, gboolean * had_latency)
88 + {
89 + GstMessage *message;
90 +
91 +- GST_DEBUG ("popping async-done message");
92 ++ if (*had_latency)
93 ++ return;
94 ++
95 ++ GST_DEBUG ("popping latency message");
96 + message = gst_bus_poll (bus, GST_MESSAGE_LATENCY, -1);
97 +
98 +- fail_unless (message && GST_MESSAGE_TYPE (message)
99 ++ fail_unless (message);
100 ++ fail_unless (GST_MESSAGE_TYPE (message)
101 + == GST_MESSAGE_LATENCY, "did not get GST_MESSAGE_LATENCY");
102 +
103 +- gst_message_unref (message);
104 +- GST_DEBUG ("popped message");
105 ++ GST_DEBUG ("popped message %s",
106 ++ gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
107 ++ gst_clear_message (&message);
108 ++
109 ++ *had_latency = TRUE;
110 + }
111 +
112 + static void
113 +-pop_state_changed (GstBus * bus, int count)
114 ++pop_state_changed (GstBus * bus, int count, gboolean * had_latency)
115 + {
116 + GstMessage *message;
117 +-
118 ++ GstMessageType types = GST_MESSAGE_STATE_CHANGED;
119 + int i;
120 +
121 ++ if (!*had_latency)
122 ++ types |= GST_MESSAGE_LATENCY;
123 ++
124 + GST_DEBUG ("popping %d messages", count);
125 + for (i = 0; i < count; ++i) {
126 +- message = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1);
127 +-
128 +- fail_unless (message && GST_MESSAGE_TYPE (message)
129 +- == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
130 +-
131 +- gst_message_unref (message);
132 ++ do {
133 ++ message = gst_bus_poll (bus, types, -1);
134 ++
135 ++ fail_unless (message);
136 ++ GST_DEBUG ("popped message %s",
137 ++ gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
138 ++
139 ++ if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_LATENCY) {
140 ++ fail_unless (*had_latency == FALSE);
141 ++ *had_latency = TRUE;
142 ++ gst_clear_message (&message);
143 ++ types &= ~GST_MESSAGE_LATENCY;
144 ++ continue;
145 ++ }
146 ++
147 ++ fail_unless (GST_MESSAGE_TYPE (message)
148 ++ == GST_MESSAGE_STATE_CHANGED,
149 ++ "did not get GST_MESSAGE_STATE_CHANGED");
150 ++
151 ++ gst_message_unref (message);
152 ++ break;
153 ++ } while (TRUE);
154 + }
155 + GST_DEBUG ("popped %d messages", count);
156 + }
157 +@@ -538,6 +583,7 @@ GST_START_TEST (test_message_state_changed_children)
158 + GstBus *bus;
159 + GstStateChangeReturn ret;
160 + GstState current, pending;
161 ++ gboolean had_latency = FALSE;
162 +
163 + pipeline = GST_PIPELINE (gst_pipeline_new (NULL));
164 + fail_unless (pipeline != NULL, "Could not create pipeline");
165 +@@ -576,7 +622,7 @@ GST_START_TEST (test_message_state_changed_children)
166 + ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
167 + ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
168 +
169 +- pop_state_changed (bus, 3);
170 ++ pop_state_changed (bus, 3, &had_latency);
171 + fail_if (gst_bus_have_pending (bus), "unexpected pending messages");
172 +
173 + ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
174 +@@ -619,9 +665,9 @@ GST_START_TEST (test_message_state_changed_children)
175 + * its state_change message */
176 + ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "pipeline", 3, 4);
177 +
178 +- pop_state_changed (bus, 3);
179 +- pop_async_done (bus);
180 +- pop_latency (bus);
181 ++ pop_state_changed (bus, 3, &had_latency);
182 ++ pop_async_done (bus, &had_latency);
183 ++ pop_latency (bus, &had_latency);
184 + fail_if ((gst_bus_pop (bus)) != NULL);
185 +
186 + ASSERT_OBJECT_REFCOUNT_BETWEEN (bus, "bus", 2, 3);
187 +@@ -648,7 +694,7 @@ GST_START_TEST (test_message_state_changed_children)
188 + ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 2, 4);
189 + ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 3);
190 +
191 +- pop_state_changed (bus, 3);
192 ++ pop_state_changed (bus, 3, &had_latency);
193 + fail_if ((gst_bus_pop (bus)) != NULL);
194 +
195 + ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
196 +@@ -669,7 +715,7 @@ GST_START_TEST (test_message_state_changed_children)
197 + ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 3, 4);
198 + ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 3);
199 +
200 +- pop_state_changed (bus, 6);
201 ++ pop_state_changed (bus, 6, &had_latency);
202 + fail_if ((gst_bus_pop (bus)) != NULL);
203 +
204 + ASSERT_OBJECT_REFCOUNT (src, "src", 1);
205 +@@ -696,6 +742,7 @@ GST_START_TEST (test_watch_for_state_change)
206 + GstElement *src, *sink, *bin;
207 + GstBus *bus;
208 + GstStateChangeReturn ret;
209 ++ gboolean had_latency = FALSE;
210 +
211 + bin = gst_element_factory_make ("bin", NULL);
212 + fail_unless (bin != NULL, "Could not create bin");
213 +@@ -722,9 +769,9 @@ GST_START_TEST (test_watch_for_state_change)
214 + GST_CLOCK_TIME_NONE);
215 + fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
216 +
217 +- pop_state_changed (bus, 6);
218 +- pop_async_done (bus);
219 +- pop_latency (bus);
220 ++ pop_state_changed (bus, 6, &had_latency);
221 ++ pop_async_done (bus, &had_latency);
222 ++ pop_latency (bus, &had_latency);
223 +
224 + fail_unless (gst_bus_have_pending (bus) == FALSE,
225 + "Unexpected messages on bus");
226 +@@ -732,16 +779,17 @@ GST_START_TEST (test_watch_for_state_change)
227 + ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
228 + fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
229 +
230 +- pop_state_changed (bus, 3);
231 ++ pop_state_changed (bus, 3, &had_latency);
232 +
233 ++ had_latency = FALSE;
234 + /* this one might return either SUCCESS or ASYNC, likely SUCCESS */
235 + ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED);
236 + gst_element_get_state (GST_ELEMENT (bin), NULL, NULL, GST_CLOCK_TIME_NONE);
237 +
238 +- pop_state_changed (bus, 3);
239 ++ pop_state_changed (bus, 3, &had_latency);
240 + if (ret == GST_STATE_CHANGE_ASYNC) {
241 +- pop_async_done (bus);
242 +- pop_latency (bus);
243 ++ pop_async_done (bus, &had_latency);
244 ++ pop_latency (bus, &had_latency);
245 + }
246 +
247 + fail_unless (gst_bus_have_pending (bus) == FALSE,
248 +@@ -898,6 +946,7 @@ GST_START_TEST (test_children_state_change_order_flagged_sink)
249 + GstStateChangeReturn ret;
250 + GstState current, pending;
251 + GstBus *bus;
252 ++ gboolean had_latency = FALSE;
253 +
254 + pipeline = gst_pipeline_new (NULL);
255 + fail_unless (pipeline != NULL, "Could not create pipeline");
256 +@@ -951,10 +1000,11 @@ GST_START_TEST (test_children_state_change_order_flagged_sink)
257 + ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_READY, GST_STATE_PAUSED, 107);
258 + #else
259 +
260 +- pop_state_changed (bus, 2); /* pop remaining ready => paused messages off the bus */
261 ++ pop_state_changed (bus, 2, &had_latency); /* pop remaining ready => paused messages off the bus */
262 + ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_READY, GST_STATE_PAUSED,
263 + 108);
264 +- pop_async_done (bus);
265 ++ pop_async_done (bus, &had_latency);
266 ++ pop_latency (bus, &had_latency);
267 + #endif
268 + /* PAUSED => PLAYING */
269 + GST_DEBUG ("popping PAUSED -> PLAYING messages");
270 +@@ -972,8 +1022,8 @@ GST_START_TEST (test_children_state_change_order_flagged_sink)
271 + fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to READY failed");
272 +
273 + /* TODO: do we need to check downwards state change order as well? */
274 +- pop_state_changed (bus, 4); /* pop playing => paused messages off the bus */
275 +- pop_state_changed (bus, 4); /* pop paused => ready messages off the bus */
276 ++ pop_state_changed (bus, 4, &had_latency); /* pop playing => paused messages off the bus */
277 ++ pop_state_changed (bus, 4, &had_latency); /* pop paused => ready messages off the bus */
278 +
279 + while (GST_OBJECT_REFCOUNT_VALUE (pipeline) > 1)
280 + THREAD_SWITCH ();
281 +@@ -1002,6 +1052,7 @@ GST_START_TEST (test_children_state_change_order_semi_sink)
282 + GstStateChangeReturn ret;
283 + GstState current, pending;
284 + GstBus *bus;
285 ++ gboolean had_latency = FALSE;
286 +
287 + /* (2) Now again, but check other code path where we don't have
288 + * a proper sink correctly flagged as such, but a 'semi-sink' */
289 +@@ -1056,10 +1107,11 @@ GST_START_TEST (test_children_state_change_order_semi_sink)
290 + ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_READY, GST_STATE_PAUSED, 206);
291 + ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_READY, GST_STATE_PAUSED, 207);
292 + #else
293 +- pop_state_changed (bus, 2); /* pop remaining ready => paused messages off the bus */
294 ++ pop_state_changed (bus, 2, &had_latency); /* pop remaining ready => paused messages off the bus */
295 + ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_READY, GST_STATE_PAUSED,
296 + 208);
297 +- pop_async_done (bus);
298 ++ pop_async_done (bus, &had_latency);
299 ++ pop_latency (bus, &had_latency);
300 +
301 + /* PAUSED => PLAYING */
302 + GST_DEBUG ("popping PAUSED -> PLAYING messages");
303 +@@ -1076,8 +1128,8 @@ GST_START_TEST (test_children_state_change_order_semi_sink)
304 + fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to READY failed");
305 +
306 + /* TODO: do we need to check downwards state change order as well? */
307 +- pop_state_changed (bus, 4); /* pop playing => paused messages off the bus */
308 +- pop_state_changed (bus, 4); /* pop paused => ready messages off the bus */
309 ++ pop_state_changed (bus, 4, &had_latency); /* pop playing => paused messages off the bus */
310 ++ pop_state_changed (bus, 4, &had_latency); /* pop paused => ready messages off the bus */
311 +
312 + GST_DEBUG ("waiting for pipeline to reach refcount 1");
313 + while (GST_OBJECT_REFCOUNT_VALUE (pipeline) > 1)
314 +--
315 +GitLab
316
317 diff --git a/media-libs/gstreamer/gstreamer-1.20.5.ebuild b/media-libs/gstreamer/gstreamer-1.20.5.ebuild
318 index 311e94692cbe..8226608a2c54 100644
319 --- a/media-libs/gstreamer/gstreamer-1.20.5.ebuild
320 +++ b/media-libs/gstreamer/gstreamer-1.20.5.ebuild
321 @@ -34,6 +34,7 @@ BDEPEND="
322 DOCS=( AUTHORS ChangeLog NEWS MAINTAINERS README.md RELEASE )
323
324 PATCHES=(
325 + "${FILESDIR}"/${P}-tests-race.patch
326 )
327
328 multilib_src_configure() {