summaryrefslogtreecommitdiffstats
path: root/libs/binder/ProcessState.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/binder/ProcessState.cpp')
-rw-r--r--libs/binder/ProcessState.cpp359
1 files changed, 0 insertions, 359 deletions
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
deleted file mode 100644
index 9fa412c..0000000
--- a/libs/binder/ProcessState.cpp
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ProcessState"
-
-#include <cutils/process_name.h>
-
-#include <binder/ProcessState.h>
-
-#include <utils/Atomic.h>
-#include <binder/BpBinder.h>
-#include <binder/IPCThreadState.h>
-#include <utils/Log.h>
-#include <utils/String8.h>
-#include <binder/IServiceManager.h>
-#include <utils/String8.h>
-#include <utils/threads.h>
-
-#include <private/binder/binder_module.h>
-#include <private/binder/Static.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-
-#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
-
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-// Global variables
-int mArgC;
-const char* const* mArgV;
-int mArgLen;
-
-class PoolThread : public Thread
-{
-public:
- PoolThread(bool isMain)
- : mIsMain(isMain)
- {
- }
-
-protected:
- virtual bool threadLoop()
- {
- IPCThreadState::self()->joinThreadPool(mIsMain);
- return false;
- }
-
- const bool mIsMain;
-};
-
-sp<ProcessState> ProcessState::self()
-{
- if (gProcess != NULL) return gProcess;
-
- AutoMutex _l(gProcessMutex);
- if (gProcess == NULL) gProcess = new ProcessState;
- return gProcess;
-}
-
-void ProcessState::setContextObject(const sp<IBinder>& object)
-{
- setContextObject(object, String16("default"));
-}
-
-sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
-{
- return getStrongProxyForHandle(0);
-}
-
-void ProcessState::setContextObject(const sp<IBinder>& object, const String16& name)
-{
- AutoMutex _l(mLock);
- mContexts.add(name, object);
-}
-
-sp<IBinder> ProcessState::getContextObject(const String16& name, const sp<IBinder>& caller)
-{
- mLock.lock();
- sp<IBinder> object(
- mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : NULL);
- mLock.unlock();
-
- //printf("Getting context object %s for %p\n", String8(name).string(), caller.get());
-
- if (object != NULL) return object;
-
- // Don't attempt to retrieve contexts if we manage them
- if (mManagesContexts) {
- ALOGE("getContextObject(%s) failed, but we manage the contexts!\n",
- String8(name).string());
- return NULL;
- }
-
- IPCThreadState* ipc = IPCThreadState::self();
- {
- Parcel data, reply;
- // no interface token on this magic transaction
- data.writeString16(name);
- data.writeStrongBinder(caller);
- status_t result = ipc->transact(0 /*magic*/, 0, data, &reply, 0);
- if (result == NO_ERROR) {
- object = reply.readStrongBinder();
- }
- }
-
- ipc->flushCommands();
-
- if (object != NULL) setContextObject(object, name);
- return object;
-}
-
-void ProcessState::startThreadPool()
-{
- AutoMutex _l(mLock);
- if (!mThreadPoolStarted) {
- mThreadPoolStarted = true;
- spawnPooledThread(true);
- }
-}
-
-bool ProcessState::isContextManager(void) const
-{
- return mManagesContexts;
-}
-
-bool ProcessState::becomeContextManager(context_check_func checkFunc, void* userData)
-{
- if (!mManagesContexts) {
- AutoMutex _l(mLock);
- mBinderContextCheckFunc = checkFunc;
- mBinderContextUserData = userData;
-
- int dummy = 0;
- status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
- if (result == 0) {
- mManagesContexts = true;
- } else if (result == -1) {
- mBinderContextCheckFunc = NULL;
- mBinderContextUserData = NULL;
- ALOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
- }
- }
- return mManagesContexts;
-}
-
-ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
-{
- const size_t N=mHandleToObject.size();
- if (N <= (size_t)handle) {
- handle_entry e;
- e.binder = NULL;
- e.refs = NULL;
- status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
- if (err < NO_ERROR) return NULL;
- }
- return &mHandleToObject.editItemAt(handle);
-}
-
-sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
-{
- sp<IBinder> result;
-
- AutoMutex _l(mLock);
-
- handle_entry* e = lookupHandleLocked(handle);
-
- if (e != NULL) {
- // We need to create a new BpBinder if there isn't currently one, OR we
- // are unable to acquire a weak reference on this current one. See comment
- // in getWeakProxyForHandle() for more info about this.
- IBinder* b = e->binder;
- if (b == NULL || !e->refs->attemptIncWeak(this)) {
- b = new BpBinder(handle);
- e->binder = b;
- if (b) e->refs = b->getWeakRefs();
- result = b;
- } else {
- // This little bit of nastyness is to allow us to add a primary
- // reference to the remote proxy when this team doesn't have one
- // but another team is sending the handle to us.
- result.force_set(b);
- e->refs->decWeak(this);
- }
- }
-
- return result;
-}
-
-wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
-{
- wp<IBinder> result;
-
- AutoMutex _l(mLock);
-
- handle_entry* e = lookupHandleLocked(handle);
-
- if (e != NULL) {
- // We need to create a new BpBinder if there isn't currently one, OR we
- // are unable to acquire a weak reference on this current one. The
- // attemptIncWeak() is safe because we know the BpBinder destructor will always
- // call expungeHandle(), which acquires the same lock we are holding now.
- // We need to do this because there is a race condition between someone
- // releasing a reference on this BpBinder, and a new reference on its handle
- // arriving from the driver.
- IBinder* b = e->binder;
- if (b == NULL || !e->refs->attemptIncWeak(this)) {
- b = new BpBinder(handle);
- result = b;
- e->binder = b;
- if (b) e->refs = b->getWeakRefs();
- } else {
- result = b;
- e->refs->decWeak(this);
- }
- }
-
- return result;
-}
-
-void ProcessState::expungeHandle(int32_t handle, IBinder* binder)
-{
- AutoMutex _l(mLock);
-
- handle_entry* e = lookupHandleLocked(handle);
-
- // This handle may have already been replaced with a new BpBinder
- // (if someone failed the AttemptIncWeak() above); we don't want
- // to overwrite it.
- if (e && e->binder == binder) e->binder = NULL;
-}
-
-void ProcessState::setArgs(int argc, const char* const argv[])
-{
- mArgC = argc;
- mArgV = (const char **)argv;
-
- mArgLen = 0;
- for (int i=0; i<argc; i++) {
- mArgLen += strlen(argv[i]) + 1;
- }
- mArgLen--;
-}
-
-int ProcessState::getArgC() const
-{
- return mArgC;
-}
-
-const char* const* ProcessState::getArgV() const
-{
- return mArgV;
-}
-
-void ProcessState::setArgV0(const char* txt)
-{
- if (mArgV != NULL) {
- strncpy((char*)mArgV[0], txt, mArgLen);
- set_process_name(txt);
- }
-}
-
-void ProcessState::spawnPooledThread(bool isMain)
-{
- if (mThreadPoolStarted) {
- int32_t s = android_atomic_add(1, &mThreadPoolSeq);
- char buf[16];
- snprintf(buf, sizeof(buf), "Binder_%X", s);
- ALOGV("Spawning new pooled thread, name=%s\n", buf);
- sp<Thread> t = new PoolThread(isMain);
- t->run(buf);
- }
-}
-
-static int open_driver()
-{
- int fd = open("/dev/binder", O_RDWR);
- if (fd >= 0) {
- fcntl(fd, F_SETFD, FD_CLOEXEC);
- int vers;
- status_t result = ioctl(fd, BINDER_VERSION, &vers);
- if (result == -1) {
- ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
- close(fd);
- fd = -1;
- }
- if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
- ALOGE("Binder driver protocol does not match user space protocol!");
- close(fd);
- fd = -1;
- }
- size_t maxThreads = 15;
- result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
- if (result == -1) {
- ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
- }
- } else {
- ALOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));
- }
- return fd;
-}
-
-ProcessState::ProcessState()
- : mDriverFD(open_driver())
- , mVMStart(MAP_FAILED)
- , mManagesContexts(false)
- , mBinderContextCheckFunc(NULL)
- , mBinderContextUserData(NULL)
- , mThreadPoolStarted(false)
- , mThreadPoolSeq(1)
-{
- if (mDriverFD >= 0) {
- // XXX Ideally, there should be a specific define for whether we
- // have mmap (or whether we could possibly have the kernel module
- // availabla).
-#if !defined(HAVE_WIN32_IPC)
- // mmap the binder, providing a chunk of virtual address space to receive transactions.
- mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
- if (mVMStart == MAP_FAILED) {
- // *sigh*
- ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
- close(mDriverFD);
- mDriverFD = -1;
- }
-#else
- mDriverFD = -1;
-#endif
- }
-
- LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating.");
-}
-
-ProcessState::~ProcessState()
-{
-}
-
-}; // namespace android