blob: c4b9a8c88d1986c222aa2712a39cf98d3a28d265 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include <gtest/gtest.h>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07002#include <poll.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08003#include <private/dvr/buffer_hub_client.h>
Corey Tabaka52ea25c2017-09-13 18:02:48 -07004#include <private/dvr/bufferhub_rpc.h>
5#include <sys/epoll.h>
6#include <sys/eventfd.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08007
8#include <mutex>
9#include <thread>
10
Alex Vakulenko4fe60582017-02-02 11:35:59 -080011#define RETRY_EINTR(fnc_call) \
12 ([&]() -> decltype(fnc_call) { \
13 decltype(fnc_call) result; \
14 do { \
15 result = (fnc_call); \
16 } while (result == -1 && errno == EINTR); \
17 return result; \
18 })()
19
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080020using android::dvr::BufferConsumer;
Corey Tabaka52ea25c2017-09-13 18:02:48 -070021using android::dvr::BufferHubDefs::kConsumerStateMask;
22using android::dvr::BufferHubDefs::kProducerStateBit;
23using android::dvr::BufferProducer;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080024using android::pdx::LocalHandle;
25
26const int kWidth = 640;
27const int kHeight = 480;
28const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
29const int kUsage = 0;
30const uint64_t kContext = 42;
31
32using LibBufferHubTest = ::testing::Test;
33
34TEST_F(LibBufferHubTest, TestBasicUsage) {
35 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
36 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
37 ASSERT_TRUE(p.get() != nullptr);
38 std::unique_ptr<BufferConsumer> c =
39 BufferConsumer::Import(p->CreateConsumer());
40 ASSERT_TRUE(c.get() != nullptr);
41 // Check that consumers can spawn other consumers.
42 std::unique_ptr<BufferConsumer> c2 =
43 BufferConsumer::Import(c->CreateConsumer());
44 ASSERT_TRUE(c2.get() != nullptr);
45
Corey Tabaka52ea25c2017-09-13 18:02:48 -070046 // Producer state mask is unique, i.e. 1.
47 EXPECT_EQ(p->buffer_state_bit(), kProducerStateBit);
48 // Consumer state mask cannot have producer bit on.
49 EXPECT_EQ(c->buffer_state_bit() & kProducerStateBit, 0);
50 // Consumer state mask must be a single, i.e. power of 2.
51 EXPECT_NE(c->buffer_state_bit(), 0);
52 EXPECT_EQ(c->buffer_state_bit() & (c->buffer_state_bit() - 1), 0);
53 // Consumer state mask cannot have producer bit on.
54 EXPECT_EQ(c2->buffer_state_bit() & kProducerStateBit, 0);
55 // Consumer state mask must be a single, i.e. power of 2.
56 EXPECT_NE(c2->buffer_state_bit(), 0);
57 EXPECT_EQ(c2->buffer_state_bit() & (c2->buffer_state_bit() - 1), 0);
58 // Each consumer should have unique bit.
59 EXPECT_EQ(c->buffer_state_bit() & c2->buffer_state_bit(), 0);
60
61 // Initial state: producer not available, consumers not available.
62 EXPECT_EQ(0, RETRY_EINTR(p->Poll(100)));
63 EXPECT_EQ(0, RETRY_EINTR(c->Poll(100)));
64 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(100)));
65
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080066 EXPECT_EQ(0, p->Post(LocalHandle(), kContext));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070067
68 // New state: producer not available, consumers available.
69 EXPECT_EQ(0, RETRY_EINTR(p->Poll(100)));
70 EXPECT_EQ(1, RETRY_EINTR(c->Poll(100)));
71 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(100)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080072
73 uint64_t context;
74 LocalHandle fence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -070075 EXPECT_EQ(0, c->Acquire(&fence, &context));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080076 EXPECT_EQ(kContext, context);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070077 EXPECT_EQ(0, RETRY_EINTR(c->Poll(100)));
78 EXPECT_EQ(1, RETRY_EINTR(c2->Poll(100)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080079
Corey Tabaka52ea25c2017-09-13 18:02:48 -070080 EXPECT_EQ(0, c2->Acquire(&fence, &context));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080081 EXPECT_EQ(kContext, context);
Corey Tabaka52ea25c2017-09-13 18:02:48 -070082 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(100)));
83 EXPECT_EQ(0, RETRY_EINTR(c->Poll(100)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080084
85 EXPECT_EQ(0, c->Release(LocalHandle()));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070086 EXPECT_EQ(0, RETRY_EINTR(p->Poll(100)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080087 EXPECT_EQ(0, c2->Discard());
88
Corey Tabaka52ea25c2017-09-13 18:02:48 -070089 EXPECT_EQ(1, RETRY_EINTR(p->Poll(100)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080090 EXPECT_EQ(0, p->Gain(&fence));
Corey Tabaka52ea25c2017-09-13 18:02:48 -070091 EXPECT_EQ(0, RETRY_EINTR(p->Poll(100)));
92 EXPECT_EQ(0, RETRY_EINTR(c->Poll(100)));
93 EXPECT_EQ(0, RETRY_EINTR(c2->Poll(100)));
94}
95
96TEST_F(LibBufferHubTest, TestEpoll) {
97 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
98 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
99 ASSERT_TRUE(p.get() != nullptr);
100 std::unique_ptr<BufferConsumer> c =
101 BufferConsumer::Import(p->CreateConsumer());
102 ASSERT_TRUE(c.get() != nullptr);
103
104 LocalHandle epoll_fd{epoll_create1(EPOLL_CLOEXEC)};
105 ASSERT_TRUE(epoll_fd.IsValid());
106
107 epoll_event event;
108 std::array<epoll_event, 64> events;
109
110 auto event_sources = p->GetEventSources();
111 ASSERT_LT(event_sources.size(), events.size());
112
113 for (const auto& event_source : event_sources) {
114 event = {.events = event_source.event_mask | EPOLLET,
115 .data = {.fd = p->event_fd()}};
116 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
117 &event));
118 }
119
120 event_sources = c->GetEventSources();
121 ASSERT_LT(event_sources.size(), events.size());
122
123 for (const auto& event_source : event_sources) {
124 event = {.events = event_source.event_mask | EPOLLET,
125 .data = {.fd = c->event_fd()}};
126 ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
127 &event));
128 }
129
130 // No events should be signaled initially.
131 ASSERT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 0));
132
133 // Post the producer and check for consumer signal.
134 EXPECT_EQ(0, p->Post({}, kContext));
135 ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
136 ASSERT_TRUE(events[0].events & EPOLLIN);
137 ASSERT_EQ(c->event_fd(), events[0].data.fd);
138
139 // Save the event bits to translate later.
140 event = events[0];
141
142 // Check for events again. Edge-triggered mode should prevent any.
143 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
144 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
145 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
146 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
147
148 // Translate the events.
149 auto event_status = c->GetEventMask(event.events);
150 ASSERT_TRUE(event_status);
151 ASSERT_TRUE(event_status.get() & EPOLLIN);
152
153 // Check for events again. Edge-triggered mode should prevent any.
154 EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
155}
156
157TEST_F(LibBufferHubTest, TestStateMask) {
158 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
159 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
160 ASSERT_TRUE(p.get() != nullptr);
161
162 // It's ok to create up to 63 consumer buffers.
163 uint64_t buffer_state_bits = p->buffer_state_bit();
164 std::array<std::unique_ptr<BufferConsumer>, 63> cs;
165 for (size_t i = 0; i < 63; i++) {
166 cs[i] = BufferConsumer::Import(p->CreateConsumer());
167 ASSERT_TRUE(cs[i].get() != nullptr);
168 // Expect all buffers have unique state mask.
169 EXPECT_EQ(buffer_state_bits & cs[i]->buffer_state_bit(), 0);
170 buffer_state_bits |= cs[i]->buffer_state_bit();
171 }
172 EXPECT_EQ(buffer_state_bits, kProducerStateBit | kConsumerStateMask);
173
174 // The 64th creation will fail with out-of-memory error.
175 auto state = p->CreateConsumer();
176 EXPECT_EQ(state.error(), E2BIG);
177
178 // Release any consumer should allow us to re-create.
179 for (size_t i = 0; i < 63; i++) {
180 buffer_state_bits &= ~cs[i]->buffer_state_bit();
181 cs[i] = nullptr;
182 cs[i] = BufferConsumer::Import(p->CreateConsumer());
183 ASSERT_TRUE(cs[i].get() != nullptr);
184 // The released state mask will be reused.
185 EXPECT_EQ(buffer_state_bits & cs[i]->buffer_state_bit(), 0);
186 buffer_state_bits |= cs[i]->buffer_state_bit();
187 EXPECT_EQ(buffer_state_bits, kProducerStateBit | kConsumerStateMask);
188 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800189}
190
Corey Tabakad53870c2017-07-06 18:04:27 -0700191TEST_F(LibBufferHubTest, TestStateTransitions) {
192 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
193 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
194 ASSERT_TRUE(p.get() != nullptr);
195 std::unique_ptr<BufferConsumer> c =
196 BufferConsumer::Import(p->CreateConsumer());
197 ASSERT_TRUE(c.get() != nullptr);
198
199 uint64_t context;
200 LocalHandle fence;
201
202 // The producer buffer starts in gained state.
203
204 // Acquire, release, and gain in gained state should fail.
205 EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
206 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
207 EXPECT_EQ(-EALREADY, p->Gain(&fence));
208
209 // Post in gained state should succeed.
210 EXPECT_EQ(0, p->Post(LocalHandle(), kContext));
211
212 // Post, release, and gain in posted state should fail.
213 EXPECT_EQ(-EBUSY, p->Post(LocalHandle(), kContext));
214 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
215 EXPECT_EQ(-EBUSY, p->Gain(&fence));
216
217 // Acquire in posted state should succeed.
218 EXPECT_LE(0, c->Acquire(&fence, &context));
219
220 // Acquire, post, and gain in acquired state should fail.
221 EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
222 EXPECT_EQ(-EBUSY, p->Post(LocalHandle(), kContext));
223 EXPECT_EQ(-EBUSY, p->Gain(&fence));
224
225 // Release in acquired state should succeed.
226 EXPECT_EQ(0, c->Release(LocalHandle()));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700227 EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
Corey Tabakad53870c2017-07-06 18:04:27 -0700228
229 // Release, acquire, and post in released state should fail.
230 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
231 EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
232 EXPECT_EQ(-EBUSY, p->Post(LocalHandle(), kContext));
233
234 // Gain in released state should succeed.
235 EXPECT_EQ(0, p->Gain(&fence));
236
237 // Acquire, release, and gain in gained state should fail.
238 EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
239 EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
240 EXPECT_EQ(-EALREADY, p->Gain(&fence));
241}
242
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800243TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
244 struct Metadata {
245 int64_t field1;
246 int64_t field2;
247 };
248 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
249 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
250 ASSERT_TRUE(p.get() != nullptr);
251 std::unique_ptr<BufferConsumer> c =
252 BufferConsumer::Import(p->CreateConsumer());
253 ASSERT_TRUE(c.get() != nullptr);
254
255 Metadata m = {1, 3};
256 EXPECT_EQ(0, p->Post(LocalHandle(), m));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800257 EXPECT_LE(0, RETRY_EINTR(c->Poll(10)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800258
259 LocalHandle fence;
260 Metadata m2 = {};
261 EXPECT_EQ(0, c->Acquire(&fence, &m2));
262 EXPECT_EQ(m.field1, m2.field1);
263 EXPECT_EQ(m.field2, m2.field2);
264
265 EXPECT_EQ(0, c->Release(LocalHandle()));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800266 EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800267}
268
269TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
270 struct Metadata {
271 int64_t field1;
272 int64_t field2;
273 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700274 struct OverSizedMetadata {
275 int64_t field1;
276 int64_t field2;
277 int64_t field3;
278 };
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800279 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
280 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
281 ASSERT_TRUE(p.get() != nullptr);
282 std::unique_ptr<BufferConsumer> c =
283 BufferConsumer::Import(p->CreateConsumer());
284 ASSERT_TRUE(c.get() != nullptr);
285
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700286 // It is illegal to post metadata larger than originally requested during
287 // buffer allocation.
288 OverSizedMetadata evil_meta = {};
289 EXPECT_NE(0, p->Post(LocalHandle(), evil_meta));
Alex Vakulenko4fe60582017-02-02 11:35:59 -0800290 EXPECT_GE(0, RETRY_EINTR(c->Poll(10)));
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700291
292 // It is ok to post metadata smaller than originally requested during
293 // buffer allocation.
294 int64_t sequence = 42;
295 EXPECT_EQ(0, p->Post(LocalHandle(), sequence));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800296}
297
298TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
299 struct Metadata {
300 int64_t field1;
301 int64_t field2;
302 };
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700303 struct OverSizedMetadata {
304 int64_t field1;
305 int64_t field2;
306 int64_t field3;
307 };
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800308 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
309 kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
310 ASSERT_TRUE(p.get() != nullptr);
311 std::unique_ptr<BufferConsumer> c =
312 BufferConsumer::Import(p->CreateConsumer());
313 ASSERT_TRUE(c.get() != nullptr);
314
315 Metadata m = {1, 3};
316 EXPECT_EQ(0, p->Post(LocalHandle(), m));
317
318 LocalHandle fence;
319 int64_t sequence;
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700320 OverSizedMetadata e;
321
322 // It is illegal to acquire metadata larger than originally requested during
323 // buffer allocation.
324 EXPECT_NE(0, c->Acquire(&fence, &e));
325
326 // It is ok to acquire metadata smaller than originally requested during
327 // buffer allocation.
328 EXPECT_EQ(0, c->Acquire(&fence, &sequence));
329 EXPECT_EQ(m.field1, sequence);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800330}
331
332TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
333 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
334 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
335 ASSERT_TRUE(p.get() != nullptr);
336 std::unique_ptr<BufferConsumer> c =
337 BufferConsumer::Import(p->CreateConsumer());
338 ASSERT_TRUE(c.get() != nullptr);
339
340 int64_t sequence = 3;
341 EXPECT_EQ(0, p->Post(LocalHandle(), sequence));
342
343 LocalHandle fence;
344 EXPECT_EQ(0, c->Acquire(&fence));
345}
346
347TEST_F(LibBufferHubTest, TestWithNoMeta) {
348 std::unique_ptr<BufferProducer> p =
349 BufferProducer::Create(kWidth, kHeight, kFormat, kUsage);
350 ASSERT_TRUE(p.get() != nullptr);
351 std::unique_ptr<BufferConsumer> c =
352 BufferConsumer::Import(p->CreateConsumer());
353 ASSERT_TRUE(c.get() != nullptr);
354
355 LocalHandle fence;
356
357 EXPECT_EQ(0, p->Post<void>(LocalHandle()));
358 EXPECT_EQ(0, c->Acquire(&fence));
359}
360
361TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
362 std::unique_ptr<BufferProducer> p =
363 BufferProducer::Create(kWidth, kHeight, kFormat, kUsage);
364 ASSERT_TRUE(p.get() != nullptr);
365 std::unique_ptr<BufferConsumer> c =
366 BufferConsumer::Import(p->CreateConsumer());
367 ASSERT_TRUE(c.get() != nullptr);
368
369 int64_t sequence = 3;
370 EXPECT_NE(0, p->Post(LocalHandle(), sequence));
371}
372
373TEST_F(LibBufferHubTest, TestPersistentBufferPersistence) {
374 auto p = BufferProducer::Create("TestPersistentBuffer", -1, -1, kWidth,
375 kHeight, kFormat, kUsage);
376 ASSERT_NE(nullptr, p);
377
378 // Record the original buffer id for later comparison.
379 const int buffer_id = p->id();
380
381 auto c = BufferConsumer::Import(p->CreateConsumer());
382 ASSERT_NE(nullptr, c);
383
384 EXPECT_EQ(0, p->Post<void>(LocalHandle()));
385
386 // Close the connection to the producer. This should not affect the consumer.
387 p = nullptr;
388
389 LocalHandle fence;
390 EXPECT_EQ(0, c->Acquire(&fence));
391 EXPECT_EQ(0, c->Release(LocalHandle()));
392
393 // Attempt to reconnect to the persistent buffer.
394 p = BufferProducer::Create("TestPersistentBuffer");
395 ASSERT_NE(nullptr, p);
396 EXPECT_EQ(buffer_id, p->id());
397 EXPECT_EQ(0, p->Gain(&fence));
398}
399
400TEST_F(LibBufferHubTest, TestPersistentBufferMismatchParams) {
401 auto p = BufferProducer::Create("TestPersistentBuffer", -1, -1, kWidth,
402 kHeight, kFormat, kUsage);
403 ASSERT_NE(nullptr, p);
404
405 // Close the connection to the producer.
406 p = nullptr;
407
408 // Mismatch the params.
409 p = BufferProducer::Create("TestPersistentBuffer", -1, -1, kWidth * 2,
410 kHeight, kFormat, kUsage);
411 ASSERT_EQ(nullptr, p);
412}
413
414TEST_F(LibBufferHubTest, TestRemovePersistentBuffer) {
415 auto p = BufferProducer::Create("TestPersistentBuffer", -1, -1, kWidth,
416 kHeight, kFormat, kUsage);
417 ASSERT_NE(nullptr, p);
418
419 LocalHandle fence;
420 auto c = BufferConsumer::Import(p->CreateConsumer());
421 ASSERT_NE(nullptr, c);
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700422 EXPECT_EQ(0, p->Post<void>(LocalHandle()));
423 EXPECT_EQ(0, c->Acquire(&fence));
424 EXPECT_EQ(0, c->Release(LocalHandle()));
425 EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800426
427 // Test that removing persistence and closing the producer orphans the
428 // consumer.
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700429 EXPECT_EQ(0, p->Gain(&fence));
430 EXPECT_EQ(0, p->Post<void>(LocalHandle()));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800431 EXPECT_EQ(0, p->RemovePersistence());
432 p = nullptr;
433
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700434 // Orphaned consumer can acquire the posted buffer one more time in
435 // asynchronous manner. But synchronous call will fail.
436 DvrNativeBufferMetadata meta;
437 EXPECT_EQ(0, c->AcquireAsync(&meta, &fence));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800438 EXPECT_EQ(-EPIPE, c->Release(LocalHandle()));
439}
Corey Tabaka52ea25c2017-09-13 18:02:48 -0700440
441namespace {
442
443int PollFd(int fd, int timeout_ms) {
444 pollfd p = {fd, POLLIN, 0};
445 return poll(&p, 1, timeout_ms);
446}
447
448} // namespace
449
450TEST_F(LibBufferHubTest, TestAcquireFence) {
451 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
452 kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
453 ASSERT_TRUE(p.get() != nullptr);
454 std::unique_ptr<BufferConsumer> c =
455 BufferConsumer::Import(p->CreateConsumer());
456 ASSERT_TRUE(c.get() != nullptr);
457
458 DvrNativeBufferMetadata meta;
459 LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
460
461 // Post with unsignaled fence.
462 EXPECT_EQ(0, p->PostAsync(&meta, f1));
463
464 // Should acquire a valid fence.
465 LocalHandle f2;
466 EXPECT_LT(0, RETRY_EINTR(c->Poll(10)));
467 EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
468 EXPECT_TRUE(f2.IsValid());
469 // The original fence and acquired fence should have different fd number.
470 EXPECT_NE(f1.Get(), f2.Get());
471 EXPECT_GE(0, PollFd(f2.Get(), 0));
472
473 // Signal the original fence will trigger the new fence.
474 eventfd_write(f1.Get(), 1);
475 // Now the original FD has been signaled.
476 EXPECT_LT(0, PollFd(f2.Get(), 10));
477
478 // Release the consumer with an invalid fence.
479 EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
480
481 // Should gain an invalid fence.
482 LocalHandle f3;
483 EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
484 EXPECT_EQ(0, p->GainAsync(&meta, &f3));
485 EXPECT_FALSE(f3.IsValid());
486
487 // Post with a signaled fence.
488 EXPECT_EQ(0, p->PostAsync(&meta, f1));
489
490 // Should acquire a valid fence and it's already signalled.
491 LocalHandle f4;
492 EXPECT_LT(0, RETRY_EINTR(c->Poll(10)));
493 EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
494 EXPECT_TRUE(f4.IsValid());
495 EXPECT_LT(0, PollFd(f4.Get(), 10));
496
497 // Release with an unsignalled fence and signal it immediately after release
498 // without producer gainning.
499 LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
500 EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
501 eventfd_write(f5.Get(), 1);
502
503 // Should gain a valid fence, which is already signaled.
504 LocalHandle f6;
505 EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
506 EXPECT_EQ(0, p->GainAsync(&meta, &f6));
507 EXPECT_TRUE(f6.IsValid());
508 EXPECT_LT(0, PollFd(f6.Get(), 10));
509}
510
511TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
512 std::unique_ptr<BufferProducer> p = BufferProducer::Create(
513 kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
514 ASSERT_TRUE(p.get() != nullptr);
515 std::unique_ptr<BufferConsumer> c1 =
516 BufferConsumer::Import(p->CreateConsumer());
517 ASSERT_TRUE(c1.get() != nullptr);
518 const uint64_t consumer_state_bit1 = c1->buffer_state_bit();
519
520 DvrNativeBufferMetadata meta;
521 EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
522
523 LocalHandle fence;
524 EXPECT_LT(0, RETRY_EINTR(c1->Poll(10)));
525 EXPECT_LE(0, c1->AcquireAsync(&meta, &fence));
526 // Destroy the consumer now will make it orphaned and the buffer is still
527 // acquired.
528 c1 = nullptr;
529 EXPECT_GE(0, RETRY_EINTR(p->Poll(10)));
530
531 std::unique_ptr<BufferConsumer> c2 =
532 BufferConsumer::Import(p->CreateConsumer());
533 ASSERT_TRUE(c2.get() != nullptr);
534 const uint64_t consumer_state_bit2 = c2->buffer_state_bit();
535 EXPECT_NE(consumer_state_bit1, consumer_state_bit2);
536
537 // The new consumer is available for acquire.
538 EXPECT_LT(0, RETRY_EINTR(c2->Poll(10)));
539 EXPECT_LE(0, c2->AcquireAsync(&meta, &fence));
540 // Releasing the consumer makes the buffer gainable.
541 EXPECT_EQ(0, c2->ReleaseAsync(&meta, LocalHandle()));
542
543 // The buffer is now available for the producer to gain.
544 EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
545
546 // But if another consumer is created in released state.
547 std::unique_ptr<BufferConsumer> c3 =
548 BufferConsumer::Import(p->CreateConsumer());
549 ASSERT_TRUE(c3.get() != nullptr);
550 const uint64_t consumer_state_bit3 = c3->buffer_state_bit();
551 EXPECT_NE(consumer_state_bit2, consumer_state_bit3);
552 // The consumer buffer is not acquirable.
553 EXPECT_GE(0, RETRY_EINTR(c3->Poll(10)));
554 EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &fence));
555
556 // Producer should be able to gain no matter what.
557 EXPECT_EQ(0, p->GainAsync(&meta, &fence));
558}