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 20 using android::dvr::BufferConsumer; 21 using android::dvr::BufferHubDefs::kConsumerStateMask; 22 using android::dvr::BufferHubDefs::kProducerStateBit; 23 using android::dvr::BufferProducer; 24 using android::pdx::LocalHandle; 25 26 const int kWidth = 640; 27 const int kHeight = 480; 28 const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888; 29 const int kUsage = 0; 30 const uint64_t kContext = 42; 31 32 using LibBufferHubTest = ::testing::Test; 33 34 TEST_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 96 TEST_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 157 TEST_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 191 TEST_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 243 TEST_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 269 TEST_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 298 TEST_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 332 TEST_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 347 TEST_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 361 TEST_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 373 TEST_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 400 TEST_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 414 TEST_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 441 namespace { 442 443 int PollFd(int fd, int timeout_ms) { 444 pollfd p = {fd, POLLIN, 0}; 445 return poll(&p, 1, timeout_ms); 446 } 447 448 } // namespace 449 450 TEST_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 511 TEST_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