diff options
Diffstat (limited to 'libs/binder/IPCThreadState.cpp')
-rw-r--r-- | libs/binder/IPCThreadState.cpp | 181 |
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 |