diff options
| -rw-r--r-- | libs/binder/tests/binderLibTest.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp index a5261e59bf..e2193fadab 100644 --- a/libs/binder/tests/binderLibTest.cpp +++ b/libs/binder/tests/binderLibTest.cpp @@ -21,6 +21,7 @@ #include <pthread.h> #include <stdio.h> #include <stdlib.h> +#include <thread> #include <gtest/gtest.h> @@ -28,6 +29,7 @@ #include <binder/IBinder.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> +#include <binder/ParcelRef.h> #include <private/binder/binder_module.h> #include <linux/sched.h> @@ -916,6 +918,36 @@ TEST_F(BinderLibTest, FreedBinder) { } } +TEST_F(BinderLibTest, ParcelAllocatedOnAnotherThread) { + sp<IBinder> server = addServer(); + ASSERT_TRUE(server != nullptr); + + Parcel data; + sp<ParcelRef> reply = ParcelRef::create(); + + // when we have a Parcel which is deleted on another thread, if it gets + // deleted, it will tell the kernel this, and it will drop strong references + // to binder, so that we can't BR_ACQUIRE would fail + IPCThreadState::self()->createTransactionReference(reply.get()); + ASSERT_EQ(NO_ERROR, server->transact(BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION, + data, + reply.get())); + + // we have sp to binder, but it is not actually acquired by kernel, the + // transaction is sitting on an out buffer + sp<IBinder> binder = reply->readStrongBinder(); + + std::thread([&] { + // without the transaction reference, this would cause the Parcel to be + // deallocated before the first thread flushes BR_ACQUIRE + reply = nullptr; + IPCThreadState::self()->flushCommands(); + }).join(); + + ASSERT_NE(nullptr, binder); + ASSERT_EQ(NO_ERROR, binder->pingBinder()); +} + TEST_F(BinderLibTest, CheckNoHeaderMappedInUser) { status_t ret; Parcel data, reply; |