summaryrefslogtreecommitdiff
path: root/libs/binder/IPCThreadState.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/binder/IPCThreadState.cpp')
-rw-r--r--libs/binder/IPCThreadState.cpp181
1 files changed, 39 insertions, 142 deletions
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 445df9eeff..d67ce15ca9 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -29,6 +29,8 @@
#include <utils/SystemClock.h>
#include <utils/threads.h>
+#include <private/binder/binder_module.h>
+
#include <atomic>
#include <errno.h>
#include <inttypes.h>
@@ -41,7 +43,6 @@
#include <unistd.h>
#include "Static.h"
-#include "binder_module.h"
#if LOG_NDEBUG
@@ -89,8 +90,6 @@ static const char *kReturnStrings[] = {
"BR_DEAD_BINDER",
"BR_CLEAR_DEATH_NOTIFICATION_DONE",
"BR_FAILED_REPLY",
- "BR_FROZEN_REPLY",
- "BR_ONEWAY_SPAM_SUSPECT",
"BR_TRANSACTION_SEC_CTX",
};
@@ -136,7 +135,7 @@ static const void* printBinderTransactionData(TextOutput& out, const void* data)
out << "target.ptr=" << btd->target.ptr;
}
out << " (cookie " << btd->cookie << ")" << endl
- << "code=" << TypeCode(btd->code) << ", flags=" << (void*)(uint64_t)btd->flags << endl
+ << "code=" << TypeCode(btd->code) << ", flags=" << (void*)(long)btd->flags << endl
<< "data=" << btd->data.ptr.buffer << " (" << (void*)btd->data_size
<< " bytes)" << endl
<< "offsets=" << btd->data.ptr.offsets << " (" << (void*)btd->offsets_size
@@ -151,7 +150,7 @@ static const void* printReturnCommand(TextOutput& out, const void* _cmd)
uint32_t code = (uint32_t)*cmd++;
size_t cmdIndex = code & 0xff;
if (code == BR_ERROR) {
- out << "BR_ERROR: " << (void*)(uint64_t)(*cmd++) << endl;
+ out << "BR_ERROR: " << (void*)(long)(*cmd++) << endl;
return cmd;
} else if (cmdIndex >= N) {
out << "Unknown reply: " << code << endl;
@@ -178,21 +177,21 @@ static const void* printReturnCommand(TextOutput& out, const void* _cmd)
case BR_DECREFS: {
const int32_t b = *cmd++;
const int32_t c = *cmd++;
- out << ": target=" << (void*)(uint64_t)b << " (cookie " << (void*)(uint64_t)c << ")";
+ out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")";
} break;
case BR_ATTEMPT_ACQUIRE: {
const int32_t p = *cmd++;
const int32_t b = *cmd++;
const int32_t c = *cmd++;
- out << ": target=" << (void*)(uint64_t)b << " (cookie " << (void*)(uint64_t)c
+ out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c
<< "), pri=" << p;
} break;
case BR_DEAD_BINDER:
case BR_CLEAR_DEATH_NOTIFICATION_DONE: {
const int32_t c = *cmd++;
- out << ": death cookie " << (void*)(uint64_t)c;
+ out << ": death cookie " << (void*)(long)c;
} break;
default:
@@ -233,7 +232,7 @@ static const void* printCommand(TextOutput& out, const void* _cmd)
case BC_FREE_BUFFER: {
const int32_t buf = *cmd++;
- out << ": buffer=" << (void*)(uint64_t)buf;
+ out << ": buffer=" << (void*)(long)buf;
} break;
case BC_INCREFS:
@@ -248,7 +247,7 @@ static const void* printCommand(TextOutput& out, const void* _cmd)
case BC_ACQUIRE_DONE: {
const int32_t b = *cmd++;
const int32_t c = *cmd++;
- out << ": target=" << (void*)(uint64_t)b << " (cookie " << (void*)(uint64_t)c << ")";
+ out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")";
} break;
case BC_ATTEMPT_ACQUIRE: {
@@ -261,12 +260,12 @@ static const void* printCommand(TextOutput& out, const void* _cmd)
case BC_CLEAR_DEATH_NOTIFICATION: {
const int32_t h = *cmd++;
const int32_t c = *cmd++;
- out << ": handle=" << h << " (death cookie " << (void*)(uint64_t)c << ")";
+ out << ": handle=" << h << " (death cookie " << (void*)(long)c << ")";
} break;
case BC_DEAD_BINDER_DONE: {
const int32_t c = *cmd++;
- out << ": death cookie " << (void*)(uint64_t)c;
+ out << ": death cookie " << (void*)(long)c;
} break;
default:
@@ -449,14 +448,6 @@ int32_t IPCThreadState::getLastTransactionBinderFlags() const
return mLastTransactionBinderFlags;
}
-void IPCThreadState::setCallRestriction(ProcessState::CallRestriction restriction) {
- mCallRestriction = restriction;
-}
-
-ProcessState::CallRestriction IPCThreadState::getCallRestriction() const {
- return mCallRestriction;
-}
-
void IPCThreadState::restoreCallingIdentity(int64_t token)
{
mCallingUid = (int)(token>>32);
@@ -487,32 +478,15 @@ void IPCThreadState::flushCommands()
}
}
-bool IPCThreadState::flushIfNeeded()
-{
- if (mIsLooper || mServingStackPointer != nullptr || mIsFlushing) {
- return false;
- }
- mIsFlushing = true;
- // In case this thread is not a looper and is not currently serving a binder transaction,
- // there's no guarantee that this thread will call back into the kernel driver any time
- // soon. Therefore, flush pending commands such as BC_FREE_BUFFER, to prevent them from getting
- // stuck in this thread's out buffer.
- flushCommands();
- mIsFlushing = false;
- return true;
-}
-
void IPCThreadState::blockUntilThreadAvailable()
{
pthread_mutex_lock(&mProcess->mThreadCountLock);
- mProcess->mWaitingForThreads++;
while (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads) {
ALOGW("Waiting for thread to be free. mExecutingThreadsCount=%lu mMaxThreads=%lu\n",
static_cast<unsigned long>(mProcess->mExecutingThreadsCount),
static_cast<unsigned long>(mProcess->mMaxThreads));
pthread_cond_wait(&mProcess->mThreadCountDecrement, &mProcess->mThreadCountLock);
}
- mProcess->mWaitingForThreads--;
pthread_mutex_unlock(&mProcess->mThreadCountLock);
}
@@ -552,12 +526,7 @@ status_t IPCThreadState::getAndExecuteCommand()
}
mProcess->mStarvationStartTimeMs = 0;
}
-
- // Cond broadcast can be expensive, so don't send it every time a binder
- // call is processed. b/168806193
- if (mProcess->mWaitingForThreads > 0) {
- pthread_cond_broadcast(&mProcess->mThreadCountDecrement);
- }
+ pthread_cond_broadcast(&mProcess->mThreadCountDecrement);
pthread_mutex_unlock(&mProcess->mThreadCountLock);
}
@@ -620,7 +589,6 @@ void IPCThreadState::joinThreadPool(bool isMain)
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
- mIsLooper = true;
status_t result;
do {
processPendingDerefs();
@@ -643,18 +611,16 @@ void IPCThreadState::joinThreadPool(bool isMain)
(void*)pthread_self(), getpid(), result);
mOut.writeInt32(BC_EXIT_LOOPER);
- mIsLooper = false;
talkWithDriver(false);
}
-status_t IPCThreadState::setupPolling(int* fd)
+int IPCThreadState::setupPolling(int* fd)
{
if (mProcess->mDriverFD < 0) {
return -EBADF;
}
mOut.writeInt32(BC_ENTER_LOOPER);
- flushCommands();
*fd = mProcess->mDriverFD;
return 0;
}
@@ -686,8 +652,6 @@ status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
- LOG_ALWAYS_FATAL_IF(data.isForRpc(), "Parcel constructed for RPC, but being used with binder.");
-
status_t err;
flags |= TF_ACCEPT_FDS;
@@ -715,7 +679,7 @@ status_t IPCThreadState::transact(int32_t handle,
CallStack::logStack("non-oneway call", CallStack::getCurrent(10).get(),
ANDROID_LOG_ERROR);
} else /* FATAL_IF_NOT_ONEWAY */ {
- LOG_ALWAYS_FATAL("Process may not make non-oneway calls (code: %u).", code);
+ LOG_ALWAYS_FATAL("Process may not make oneway calls (code: %u).", code);
}
}
@@ -759,11 +723,9 @@ void IPCThreadState::incStrongHandle(int32_t handle, BpBinder *proxy)
LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle);
mOut.writeInt32(BC_ACQUIRE);
mOut.writeInt32(handle);
- if (!flushIfNeeded()) {
- // Create a temp reference until the driver has handled this command.
- proxy->incStrong(mProcess.get());
- mPostWriteStrongDerefs.push(proxy);
- }
+ // Create a temp reference until the driver has handled this command.
+ proxy->incStrong(mProcess.get());
+ mPostWriteStrongDerefs.push(proxy);
}
void IPCThreadState::decStrongHandle(int32_t handle)
@@ -771,7 +733,6 @@ void IPCThreadState::decStrongHandle(int32_t handle)
LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)\n", handle);
mOut.writeInt32(BC_RELEASE);
mOut.writeInt32(handle);
- flushIfNeeded();
}
void IPCThreadState::incWeakHandle(int32_t handle, BpBinder *proxy)
@@ -779,11 +740,9 @@ void IPCThreadState::incWeakHandle(int32_t handle, BpBinder *proxy)
LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
mOut.writeInt32(BC_INCREFS);
mOut.writeInt32(handle);
- if (!flushIfNeeded()) {
- // Create a temp reference until the driver has handled this command.
- proxy->getWeakRefs()->incWeak(mProcess.get());
- mPostWriteWeakDerefs.push(proxy->getWeakRefs());
- }
+ // Create a temp reference until the driver has handled this command.
+ proxy->getWeakRefs()->incWeak(mProcess.get());
+ mPostWriteWeakDerefs.push(proxy->getWeakRefs());
}
void IPCThreadState::decWeakHandle(int32_t handle)
@@ -791,7 +750,6 @@ void IPCThreadState::decWeakHandle(int32_t handle)
LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)\n", handle);
mOut.writeInt32(BC_DECREFS);
mOut.writeInt32(handle);
- flushIfNeeded();
}
status_t IPCThreadState::attemptIncStrongHandle(int32_t handle)
@@ -843,15 +801,14 @@ status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)
}
IPCThreadState::IPCThreadState()
- : mProcess(ProcessState::self()),
- mServingStackPointer(nullptr),
- mWorkSource(kUnsetWorkSource),
- mPropagateWorkSource(false),
- mIsLooper(false),
- mIsFlushing(false),
- mStrictModePolicy(0),
- mLastTransactionBinderFlags(0),
- mCallRestriction(mProcess->mCallRestriction) {
+ : mProcess(ProcessState::self()),
+ mServingStackPointer(nullptr),
+ mWorkSource(kUnsetWorkSource),
+ mPropagateWorkSource(false),
+ mStrictModePolicy(0),
+ mLastTransactionBinderFlags(0),
+ mCallRestriction(mProcess->mCallRestriction)
+{
pthread_setspecific(gTLS, this);
clearCaller();
mIn.setDataCapacity(256);
@@ -891,11 +848,6 @@ status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
}
switch (cmd) {
- case BR_ONEWAY_SPAM_SUSPECT:
- ALOGE("Process seems to be sending too many oneway calls.");
- CallStack::logStack("oneway spamming", CallStack::getCurrent().get(),
- ANDROID_LOG_ERROR);
- [[fallthrough]];
case BR_TRANSACTION_COMPLETE:
if (!reply && !acquireResult) goto finish;
break;
@@ -908,10 +860,6 @@ status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
err = FAILED_TRANSACTION;
goto finish;
- case BR_FROZEN_REPLY:
- err = FAILED_TRANSACTION;
- goto finish;
-
case BR_ACQUIRE_RESULT:
{
ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
@@ -935,21 +883,21 @@ status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(binder_size_t),
- freeBuffer);
+ freeBuffer, this);
} else {
err = *reinterpret_cast<const status_t*>(tr.data.ptr.buffer);
freeBuffer(nullptr,
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
- tr.offsets_size/sizeof(binder_size_t));
+ tr.offsets_size/sizeof(binder_size_t), this);
}
} else {
freeBuffer(nullptr,
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
- tr.offsets_size/sizeof(binder_size_t));
+ tr.offsets_size/sizeof(binder_size_t), this);
continue;
}
}
@@ -1117,7 +1065,7 @@ status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
sp<BBinder> the_context_object;
-void IPCThreadState::setTheContextObject(const sp<BBinder>& obj)
+void IPCThreadState::setTheContextObject(sp<BBinder> obj)
{
the_context_object = obj;
}
@@ -1223,7 +1171,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
- tr.offsets_size/sizeof(binder_size_t), freeBuffer);
+ tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
const void* origServingStackPointer = mServingStackPointer;
mServingStackPointer = &origServingStackPointer; // anything on the stack
@@ -1284,26 +1232,12 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
if ((tr.flags & TF_ONE_WAY) == 0) {
LOG_ONEWAY("Sending reply to %d!", mCallingPid);
if (error < NO_ERROR) reply.setError(error);
-
- constexpr uint32_t kForwardReplyFlags = TF_CLEAR_BUF;
- sendReply(reply, (tr.flags & kForwardReplyFlags));
+ sendReply(reply, 0);
} else {
- if (error != OK) {
- alog << "oneway function results for code " << tr.code
- << " on binder at "
- << reinterpret_cast<void*>(tr.target.ptr)
- << " will be dropped but finished with status "
- << statusToString(error);
-
- // ideally we could log this even when error == OK, but it
- // causes too much logspam because some manually-written
- // interfaces have clients that call methods which always
- // write results, sometimes as oneway methods.
- if (reply.dataSize() != 0) {
- alog << " and reply parcel size " << reply.dataSize();
- }
-
- alog << endl;
+ if (error != OK || reply.dataSize() != 0) {
+ alog << "oneway function results will be dropped but finished with status "
+ << statusToString(error)
+ << " and parcel size " << reply.dataSize() << endl;
}
LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
}
@@ -1382,47 +1316,11 @@ void IPCThreadState::threadDestructor(void *st)
}
}
-status_t IPCThreadState::getProcessFreezeInfo(pid_t pid, bool *sync_received, bool *async_received)
-{
- int ret = 0;
- binder_frozen_status_info info;
- info.pid = pid;
-
-#if defined(__ANDROID__)
- if (ioctl(self()->mProcess->mDriverFD, BINDER_GET_FROZEN_INFO, &info) < 0)
- ret = -errno;
-#endif
- *sync_received = info.sync_recv;
- *async_received = info.async_recv;
-
- return ret;
-}
-
-status_t IPCThreadState::freeze(pid_t pid, bool enable, uint32_t timeout_ms) {
- struct binder_freeze_info info;
- int ret = 0;
-
- info.pid = pid;
- info.enable = enable;
- info.timeout_ms = timeout_ms;
-
-
-#if defined(__ANDROID__)
- if (ioctl(self()->mProcess->mDriverFD, BINDER_FREEZE, &info) < 0)
- ret = -errno;
-#endif
-
- //
- // ret==-EAGAIN indicates that transactions have not drained.
- // Call again to poll for completion.
- //
- return ret;
-}
void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data,
size_t /*dataSize*/,
const binder_size_t* /*objects*/,
- size_t /*objectsSize*/)
+ size_t /*objectsSize*/, void* /*cookie*/)
{
//ALOGI("Freeing parcel %p", &parcel);
IF_LOG_COMMANDS() {
@@ -1433,7 +1331,6 @@ void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data,
IPCThreadState* state = self();
state->mOut.writeInt32(BC_FREE_BUFFER);
state->mOut.writePointer((uintptr_t)data);
- state->flushIfNeeded();
}
} // namespace android