Home | History | Annotate | Download | only in libhwbinder
      1 /*
      2  * Copyright (C) 2005 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "hw-ProcessState"
     18 
     19 #include <hwbinder/ProcessState.h>
     20 
     21 #include <utils/Atomic.h>
     22 #include <hwbinder/BpHwBinder.h>
     23 #include <hwbinder/IPCThreadState.h>
     24 #include <utils/Log.h>
     25 #include <utils/String8.h>
     26 #include <utils/String8.h>
     27 #include <utils/threads.h>
     28 
     29 #include <private/binder/binder_module.h>
     30 #include <hwbinder/Static.h>
     31 
     32 #include <errno.h>
     33 #include <fcntl.h>
     34 #include <stdio.h>
     35 #include <stdlib.h>
     36 #include <unistd.h>
     37 #include <sys/ioctl.h>
     38 #include <sys/mman.h>
     39 #include <sys/stat.h>
     40 #include <sys/types.h>
     41 
     42 #define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
     43 #define DEFAULT_MAX_BINDER_THREADS 0
     44 
     45 // -------------------------------------------------------------------------
     46 
     47 namespace android {
     48 namespace hardware {
     49 
     50 class PoolThread : public Thread
     51 {
     52 public:
     53     explicit PoolThread(bool isMain)
     54         : mIsMain(isMain)
     55     {
     56     }
     57 
     58 protected:
     59     virtual bool threadLoop()
     60     {
     61         IPCThreadState::self()->joinThreadPool(mIsMain);
     62         return false;
     63     }
     64 
     65     const bool mIsMain;
     66 };
     67 
     68 sp<ProcessState> ProcessState::self()
     69 {
     70     Mutex::Autolock _l(gProcessMutex);
     71     if (gProcess != NULL) {
     72         return gProcess;
     73     }
     74     gProcess = new ProcessState;
     75     return gProcess;
     76 }
     77 
     78 void ProcessState::setContextObject(const sp<IBinder>& object)
     79 {
     80     setContextObject(object, String16("default"));
     81 }
     82 
     83 sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
     84 {
     85     return getStrongProxyForHandle(0);
     86 }
     87 
     88 void ProcessState::setContextObject(const sp<IBinder>& object, const String16& name)
     89 {
     90     AutoMutex _l(mLock);
     91     mContexts.add(name, object);
     92 }
     93 
     94 sp<IBinder> ProcessState::getContextObject(const String16& name, const sp<IBinder>& caller)
     95 {
     96     mLock.lock();
     97     sp<IBinder> object(
     98         mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : NULL);
     99     mLock.unlock();
    100 
    101     //printf("Getting context object %s for %p\n", String8(name).string(), caller.get());
    102 
    103     if (object != NULL) return object;
    104 
    105     // Don't attempt to retrieve contexts if we manage them
    106     if (mManagesContexts) {
    107         ALOGE("getContextObject(%s) failed, but we manage the contexts!\n",
    108             String8(name).string());
    109         return NULL;
    110     }
    111 
    112     IPCThreadState* ipc = IPCThreadState::self();
    113     {
    114         Parcel data, reply;
    115         // no interface token on this magic transaction
    116         data.writeString16(name);
    117         data.writeStrongBinder(caller);
    118         status_t result = ipc->transact(0 /*magic*/, 0, data, &reply, 0);
    119         if (result == NO_ERROR) {
    120             object = reply.readStrongBinder();
    121         }
    122     }
    123 
    124     ipc->flushCommands();
    125 
    126     if (object != NULL) setContextObject(object, name);
    127     return object;
    128 }
    129 
    130 void ProcessState::startThreadPool()
    131 {
    132     AutoMutex _l(mLock);
    133     if (!mThreadPoolStarted) {
    134         mThreadPoolStarted = true;
    135         if (mSpawnThreadOnStart) {
    136             spawnPooledThread(true);
    137         }
    138     }
    139 }
    140 
    141 bool ProcessState::isContextManager(void) const
    142 {
    143     return mManagesContexts;
    144 }
    145 
    146 bool ProcessState::becomeContextManager(context_check_func checkFunc, void* userData)
    147 {
    148     if (!mManagesContexts) {
    149         AutoMutex _l(mLock);
    150         mBinderContextCheckFunc = checkFunc;
    151         mBinderContextUserData = userData;
    152 
    153         int dummy = 0;
    154         status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
    155         if (result == 0) {
    156             mManagesContexts = true;
    157         } else if (result == -1) {
    158             mBinderContextCheckFunc = NULL;
    159             mBinderContextUserData = NULL;
    160             ALOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
    161         }
    162     }
    163     return mManagesContexts;
    164 }
    165 
    166 ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
    167 {
    168     const size_t N=mHandleToObject.size();
    169     if (N <= (size_t)handle) {
    170         handle_entry e;
    171         e.binder = NULL;
    172         e.refs = NULL;
    173         status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
    174         if (err < NO_ERROR) return NULL;
    175     }
    176     return &mHandleToObject.editItemAt(handle);
    177 }
    178 
    179 sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
    180 {
    181     sp<IBinder> result;
    182 
    183     AutoMutex _l(mLock);
    184 
    185     handle_entry* e = lookupHandleLocked(handle);
    186 
    187     if (e != NULL) {
    188         // We need to create a new BpHwBinder if there isn't currently one, OR we
    189         // are unable to acquire a weak reference on this current one.  See comment
    190         // in getWeakProxyForHandle() for more info about this.
    191         IBinder* b = e->binder;
    192         if (b == NULL || !e->refs->attemptIncWeak(this)) {
    193             b = new BpHwBinder(handle);
    194             e->binder = b;
    195             if (b) e->refs = b->getWeakRefs();
    196             result = b;
    197         } else {
    198             // This little bit of nastyness is to allow us to add a primary
    199             // reference to the remote proxy when this team doesn't have one
    200             // but another team is sending the handle to us.
    201             result.force_set(b);
    202             e->refs->decWeak(this);
    203         }
    204     }
    205 
    206     return result;
    207 }
    208 
    209 wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
    210 {
    211     wp<IBinder> result;
    212 
    213     AutoMutex _l(mLock);
    214 
    215     handle_entry* e = lookupHandleLocked(handle);
    216 
    217     if (e != NULL) {
    218         // We need to create a new BpHwBinder if there isn't currently one, OR we
    219         // are unable to acquire a weak reference on this current one.  The
    220         // attemptIncWeak() is safe because we know the BpHwBinder destructor will always
    221         // call expungeHandle(), which acquires the same lock we are holding now.
    222         // We need to do this because there is a race condition between someone
    223         // releasing a reference on this BpHwBinder, and a new reference on its handle
    224         // arriving from the driver.
    225         IBinder* b = e->binder;
    226         if (b == NULL || !e->refs->attemptIncWeak(this)) {
    227             b = new BpHwBinder(handle);
    228             result = b;
    229             e->binder = b;
    230             if (b) e->refs = b->getWeakRefs();
    231         } else {
    232             result = b;
    233             e->refs->decWeak(this);
    234         }
    235     }
    236 
    237     return result;
    238 }
    239 
    240 void ProcessState::expungeHandle(int32_t handle, IBinder* binder)
    241 {
    242     AutoMutex _l(mLock);
    243 
    244     handle_entry* e = lookupHandleLocked(handle);
    245 
    246     // This handle may have already been replaced with a new BpHwBinder
    247     // (if someone failed the AttemptIncWeak() above); we don't want
    248     // to overwrite it.
    249     if (e && e->binder == binder) e->binder = NULL;
    250 }
    251 
    252 String8 ProcessState::makeBinderThreadName() {
    253     int32_t s = android_atomic_add(1, &mThreadPoolSeq);
    254     pid_t pid = getpid();
    255     String8 name;
    256     name.appendFormat("HwBinder:%d_%X", pid, s);
    257     return name;
    258 }
    259 
    260 void ProcessState::spawnPooledThread(bool isMain)
    261 {
    262     if (mThreadPoolStarted) {
    263         String8 name = makeBinderThreadName();
    264         ALOGV("Spawning new pooled thread, name=%s\n", name.string());
    265         sp<Thread> t = new PoolThread(isMain);
    266         t->run(name.string());
    267     }
    268 }
    269 
    270 status_t ProcessState::setThreadPoolConfiguration(size_t maxThreads, bool callerJoinsPool) {
    271     LOG_ALWAYS_FATAL_IF(maxThreads < 1, "Binder threadpool must have a minimum of one thread.");
    272     status_t result = NO_ERROR;
    273     // the BINDER_SET_MAX_THREADS ioctl really tells the kernel how many threads
    274     // it's allowed to spawn, *in addition* to any threads we may have already
    275     // spawned locally. If 'callerJoinsPool' is true, it means that the caller
    276     // will join the threadpool, and so the kernel needs to create one less thread.
    277     // If 'callerJoinsPool' is false, we will still spawn a thread locally, and we should
    278     // also tell the kernel to create one less thread than what was requested here.
    279     size_t kernelMaxThreads = maxThreads - 1;
    280     if (ioctl(mDriverFD, BINDER_SET_MAX_THREADS, &kernelMaxThreads) != -1) {
    281         AutoMutex _l(mLock);
    282         mMaxThreads = maxThreads;
    283         mSpawnThreadOnStart = !callerJoinsPool;
    284     } else {
    285         result = -errno;
    286         ALOGE("Binder ioctl to set max threads failed: %s", strerror(-result));
    287     }
    288     return result;
    289 }
    290 
    291 void ProcessState::giveThreadPoolName() {
    292     androidSetThreadName( makeBinderThreadName().string() );
    293 }
    294 
    295 static int open_driver()
    296 {
    297     int fd = open("/dev/hwbinder", O_RDWR | O_CLOEXEC);
    298     if (fd >= 0) {
    299         int vers = 0;
    300         status_t result = ioctl(fd, BINDER_VERSION, &vers);
    301         if (result == -1) {
    302             ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
    303             close(fd);
    304             fd = -1;
    305         }
    306         if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
    307           ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)!", vers, BINDER_CURRENT_PROTOCOL_VERSION);
    308             close(fd);
    309             fd = -1;
    310         }
    311         size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
    312         result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
    313         if (result == -1) {
    314             ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
    315         }
    316     } else {
    317         ALOGW("Opening '/dev/hwbinder' failed: %s\n", strerror(errno));
    318     }
    319     return fd;
    320 }
    321 
    322 ProcessState::ProcessState()
    323     : mDriverFD(open_driver())
    324     , mVMStart(MAP_FAILED)
    325     , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    326     , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    327     , mExecutingThreadsCount(0)
    328     , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    329     , mStarvationStartTimeMs(0)
    330     , mManagesContexts(false)
    331     , mBinderContextCheckFunc(NULL)
    332     , mBinderContextUserData(NULL)
    333     , mThreadPoolStarted(false)
    334     , mSpawnThreadOnStart(true)
    335     , mThreadPoolSeq(1)
    336 {
    337     if (mDriverFD >= 0) {
    338         // mmap the binder, providing a chunk of virtual address space to receive transactions.
    339         mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
    340         if (mVMStart == MAP_FAILED) {
    341             // *sigh*
    342             ALOGE("Using /dev/hwbinder failed: unable to mmap transaction memory.\n");
    343             close(mDriverFD);
    344             mDriverFD = -1;
    345         }
    346     }
    347     else {
    348         ALOGE("Binder driver could not be opened.  Terminating.");
    349     }
    350 }
    351 
    352 ProcessState::~ProcessState()
    353 {
    354     if (mDriverFD >= 0) {
    355         if (mVMStart != MAP_FAILED) {
    356             munmap(mVMStart, BINDER_VM_SIZE);
    357         }
    358         close(mDriverFD);
    359     }
    360     mDriverFD = -1;
    361 }
    362 
    363 }; // namespace hardware
    364 }; // namespace android
    365