summaryrefslogtreecommitdiffstats
path: root/libs/binder/IPCThreadState.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/binder/IPCThreadState.cpp')
-rw-r--r--libs/binder/IPCThreadState.cpp146
1 files changed, 92 insertions, 54 deletions
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 2ffa927..5951a3f 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -20,10 +20,11 @@
#include <binder/Binder.h>
#include <binder/BpBinder.h>
+#include <binder/TextOutput.h>
+
#include <cutils/sched_policy.h>
#include <utils/Debug.h>
#include <utils/Log.h>
-#include <utils/TextOutput.h>
#include <utils/threads.h>
#include <private/binder/binder_module.h>
@@ -361,12 +362,12 @@ status_t IPCThreadState::clearLastError()
return err;
}
-int IPCThreadState::getCallingPid()
+int IPCThreadState::getCallingPid() const
{
return mCallingPid;
}
-int IPCThreadState::getCallingUid()
+int IPCThreadState::getCallingUid() const
{
return mCallingUid;
}
@@ -417,6 +418,60 @@ void IPCThreadState::flushCommands()
talkWithDriver(false);
}
+status_t IPCThreadState::getAndExecuteCommand()
+{
+ status_t result;
+ int32_t cmd;
+
+ result = talkWithDriver();
+ if (result >= NO_ERROR) {
+ size_t IN = mIn.dataAvail();
+ if (IN < sizeof(int32_t)) return result;
+ cmd = mIn.readInt32();
+ IF_LOG_COMMANDS() {
+ alog << "Processing top-level Command: "
+ << getReturnString(cmd) << endl;
+ }
+
+ result = executeCommand(cmd);
+
+ // After executing the command, ensure that the thread is returned to the
+ // foreground cgroup before rejoining the pool. The driver takes care of
+ // restoring the priority, but doesn't do anything with cgroups so we
+ // need to take care of that here in userspace. Note that we do make
+ // sure to go in the foreground after executing a transaction, but
+ // there are other callbacks into user code that could have changed
+ // our group so we want to make absolutely sure it is put back.
+ set_sched_policy(mMyThreadId, SP_FOREGROUND);
+ }
+
+ return result;
+}
+
+// When we've cleared the incoming command queue, process any pending derefs
+void IPCThreadState::processPendingDerefs()
+{
+ if (mIn.dataPosition() >= mIn.dataSize()) {
+ size_t numPending = mPendingWeakDerefs.size();
+ if (numPending > 0) {
+ for (size_t i = 0; i < numPending; i++) {
+ RefBase::weakref_type* refs = mPendingWeakDerefs[i];
+ refs->decWeak(mProcess.get());
+ }
+ mPendingWeakDerefs.clear();
+ }
+
+ numPending = mPendingStrongDerefs.size();
+ if (numPending > 0) {
+ for (size_t i = 0; i < numPending; i++) {
+ BBinder* obj = mPendingStrongDerefs[i];
+ obj->decStrong(mProcess.get());
+ }
+ mPendingStrongDerefs.clear();
+ }
+ }
+}
+
void IPCThreadState::joinThreadPool(bool isMain)
{
LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
@@ -430,57 +485,16 @@ void IPCThreadState::joinThreadPool(bool isMain)
status_t result;
do {
- int32_t cmd;
-
- // When we've cleared the incoming command queue, process any pending derefs
- if (mIn.dataPosition() >= mIn.dataSize()) {
- size_t numPending = mPendingWeakDerefs.size();
- if (numPending > 0) {
- for (size_t i = 0; i < numPending; i++) {
- RefBase::weakref_type* refs = mPendingWeakDerefs[i];
- refs->decWeak(mProcess.get());
- }
- mPendingWeakDerefs.clear();
- }
-
- numPending = mPendingStrongDerefs.size();
- if (numPending > 0) {
- for (size_t i = 0; i < numPending; i++) {
- BBinder* obj = mPendingStrongDerefs[i];
- obj->decStrong(mProcess.get());
- }
- mPendingStrongDerefs.clear();
- }
- }
-
+ processPendingDerefs();
// now get the next command to be processed, waiting if necessary
- result = talkWithDriver();
- if (result >= NO_ERROR) {
- size_t IN = mIn.dataAvail();
- if (IN < sizeof(int32_t)) continue;
- cmd = mIn.readInt32();
- IF_LOG_COMMANDS() {
- alog << "Processing top-level Command: "
- << getReturnString(cmd) << endl;
- }
+ result = getAndExecuteCommand();
-
- result = executeCommand(cmd);
- } else if (result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
- ALOGE("talkWithDriver(fd=%d) returned unexpected error %d, aborting",
+ if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
+ ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
mProcess->mDriverFD, result);
abort();
}
- // After executing the command, ensure that the thread is returned to the
- // foreground cgroup before rejoining the pool. The driver takes care of
- // restoring the priority, but doesn't do anything with cgroups so we
- // need to take care of that here in userspace. Note that we do make
- // sure to go in the foreground after executing a transaction, but
- // there are other callbacks into user code that could have changed
- // our group so we want to make absolutely sure it is put back.
- set_sched_policy(mMyThreadId, SP_FOREGROUND);
-
// Let this thread exit the thread pool if it is no longer
// needed and it is not the main process thread.
if(result == TIMED_OUT && !isMain) {
@@ -495,6 +509,30 @@ void IPCThreadState::joinThreadPool(bool isMain)
talkWithDriver(false);
}
+int IPCThreadState::setupPolling(int* fd)
+{
+ if (mProcess->mDriverFD <= 0) {
+ return -EBADF;
+ }
+
+ mOut.writeInt32(BC_ENTER_LOOPER);
+ *fd = mProcess->mDriverFD;
+ return 0;
+}
+
+status_t IPCThreadState::handlePolledCommands()
+{
+ status_t result;
+
+ do {
+ result = getAndExecuteCommand();
+ } while (mIn.dataPosition() < mIn.dataSize());
+
+ processPendingDerefs();
+ flushCommands();
+ return result;
+}
+
void IPCThreadState::stopProcess(bool immediate)
{
//ALOGI("**** STOPPING PROCESS");
@@ -825,7 +863,7 @@ status_t IPCThreadState::talkWithDriver(bool doReceive)
IF_LOG_COMMANDS() {
alog << "Our err: " << (void*)err << ", write consumed: "
<< bwr.write_consumed << " (of " << mOut.dataSize()
- << "), read consumed: " << bwr.read_consumed << endl;
+ << "), read consumed: " << bwr.read_consumed << endl;
}
if (err >= NO_ERROR) {
@@ -1103,16 +1141,16 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
void IPCThreadState::threadDestructor(void *st)
{
- IPCThreadState* const self = static_cast<IPCThreadState*>(st);
- if (self) {
- self->flushCommands();
+ IPCThreadState* const self = static_cast<IPCThreadState*>(st);
+ if (self) {
+ self->flushCommands();
#if defined(HAVE_ANDROID_OS)
if (self->mProcess->mDriverFD > 0) {
ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
}
#endif
- delete self;
- }
+ delete self;
+ }
}