1#include <gtest/gtest.h>
2#include <poll.h>
3#include <private/dvr/buffer_hub_client.h>
4#include <private/dvr/bufferhub_rpc.h>
5#include <sys/epoll.h>
6#include <sys/eventfd.h>
7
8#include <mutex>
9#include <thread>
10
11#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
20using android::dvr::BufferConsumer;
21using android::dvr::BufferHubDefs::kConsumerStateMask;
22using android::dvr::BufferHubDefs::kProducerStateBit;
23using android::dvr::BufferProducer;
24using 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
46  // 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
66  EXPECT_EQ(0, p->Post(LocalHandle(), kContext));
67
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)));
72
73  uint64_t context;
74  LocalHandle fence;
75  EXPECT_EQ(0, c->Acquire(&fence, &context));
76  EXPECT_EQ(kContext, context);
77  EXPECT_EQ(0, RETRY_EINTR(c->Poll(100)));
78  EXPECT_EQ(1, RETRY_EINTR(c2->Poll(100)));
79
80  EXPECT_EQ(0, c2->Acquire(&fence, &context));
81  EXPECT_EQ(kContext, context);
82  EXPECT_EQ(0, RETRY_EINTR(c2->Poll(100)));
83  EXPECT_EQ(0, RETRY_EINTR(c->Poll(100)));
84
85  EXPECT_EQ(0, c->Release(LocalHandle()));
86  EXPECT_EQ(0, RETRY_EINTR(p->Poll(100)));
87  EXPECT_EQ(0, c2->Discard());
88
89  EXPECT_EQ(1, RETRY_EINTR(p->Poll(100)));
90  EXPECT_EQ(0, p->Gain(&fence));
91  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  }
189}
190
191TEST_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()));
227  EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
228
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
243TEST_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));
257  EXPECT_LE(0, RETRY_EINTR(c->Poll(10)));
258
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()));
266  EXPECT_LT(0, RETRY_EINTR(p->Poll(0)));
267}
268
269TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
270  struct Metadata {
271    int64_t field1;
272    int64_t field2;
273  };
274  struct OverSizedMetadata {
275    int64_t field1;
276    int64_t field2;
277    int64_t field3;
278  };
279  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
286  // 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));
290  EXPECT_GE(0, RETRY_EINTR(c->Poll(10)));
291
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));
296}
297
298TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
299  struct Metadata {
300    int64_t field1;
301    int64_t field2;
302  };
303  struct OverSizedMetadata {
304    int64_t field1;
305    int64_t field2;
306    int64_t field3;
307  };
308  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;
320  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);
330}
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);
422  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)));
426
427  // Test that removing persistence and closing the producer orphans the
428  // consumer.
429  EXPECT_EQ(0, p->Gain(&fence));
430  EXPECT_EQ(0, p->Post<void>(LocalHandle()));
431  EXPECT_EQ(0, p->RemovePersistence());
432  p = nullptr;
433
434  // 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));
438  EXPECT_EQ(-EPIPE, c->Release(LocalHandle()));
439}
440
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}
559