Android应用程序启动Binder线程源码分析

来源:互联网 发布:一拳超人知乎 编辑:程序博客网 时间:2024/06/10 03:48

http://blog.csdn.net/yangwen123/article/details/9254827


Android的应用程序包括Java应用及本地应用,Java应用运行在davik虚拟机中,由zygote进程来创建启动,而本地服务应用在Android系统启动时,通过配置init.rc文件来由Init进程启动。Zygote启动Android应用程序的过程请查看文章Zygote孵化应用进程过程的源码分析,关于本地应用服务的启动过程在Android Init进程源码分析中有详细的介绍。无论是Android的Java应用还是本地服务应用程序,都支持Binder进程间通信机制,本文将介绍Android应用程序是如何启动Binder线程来支持Binder进程间通信的相关内容。

在zygote启动Android应用程序时,会调用zygoteInit函数来初始化应用程序运行环境,比如虚拟机堆栈大小,Binder线程的注册等

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public static final void zygoteInit(int targetSdkVersion, String[] argv)  
  2.         throws ZygoteInit.MethodAndArgsCaller {  
  3.     redirectLogStreams();  
  4.     commonInit();  
  5.     //启动Binder线程池以支持Binder通信  
  6.     nativeZygoteInit();  
  7.     applicationInit(targetSdkVersion, argv);  
  8. }  
nativeZygoteInit函数用于创建线程池,该函数是一个本地函数,其对应的JNI函数为

frameworks\base\core\jni\AndroidRuntime.cpp 

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)  
  2. {  
  3.     gCurRuntime->onZygoteInit();  
  4. }  
变量gCurRuntime的类型是AndroidRuntime,AndroidRuntime类的onZygoteInit()函数是一个虚函数,在AndroidRuntime的子类AppRuntime中被实现

frameworks\base\cmds\app_process\App_main.cpp 

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. virtual void onZygoteInit()  
  2. {  
  3.     sp<ProcessState> proc = ProcessState::self();  
  4.     ALOGV("App process: starting thread pool.\n");  
  5.     proc->startThreadPool();  
  6. }  
函数首先得到ProcessState对象,然后调用它的startThreadPool()函数来启动线程池。
[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. void ProcessState::startThreadPool()  
  2. {  
  3.     AutoMutex _l(mLock);  
  4.     if (!mThreadPoolStarted) {  
  5.         mThreadPoolStarted = true;  
  6.         spawnPooledThread(true);  
  7.     }  
  8. }  
mThreadPoolStarted是线程池启动标志位,在startThreadPool()函数中被设置为true
[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. void ProcessState::spawnPooledThread(bool isMain)  
  2. {  
  3.     if (mThreadPoolStarted) {  
  4.         //统计启动的Binder线程数量  
  5.         int32_t s = android_atomic_add(1, &mThreadPoolSeq);  
  6.         char buf[16];  
  7.         snprintf(buf, sizeof(buf), "Binder_%X", s);  
  8.         ALOGV("Spawning new pooled thread, name=%s\n", buf);  
  9.         //创建一个PoolThread线程  
  10.         sp<Thread> t = new PoolThread(isMain);  
  11.         //启动线程  
  12.         t->run(buf);  
  13.     }  
  14. }  
PoolThread是Thread的子类,PoolThread类的定义如下

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. class PoolThread : public Thread  
  2. {  
  3. public:  
  4.     PoolThread(bool isMain)  
  5.         : mIsMain(isMain)  
  6.     {  
  7.     }  
  8.       
  9. protected:  
  10.     virtual bool threadLoop()  
  11.     {  
  12.         IPCThreadState::self()->joinThreadPool(mIsMain);  
  13.         return false;  
  14.     }  
  15.       
  16.     const bool mIsMain;  
  17. };  

通过t->run(buf)来启动该线程,并且重写了线程执行函数threadLoop(),当线程启动运行后,threadLoop()被调用执行

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. virtual bool threadLoop()  
  2. {  
  3.     IPCThreadState::self()->joinThreadPool(mIsMain);  
  4.     return false;  
  5. }  
直接执行joinThreadPool(mIsMain)函数将线程注册到Binder驱动程序中,mIsMain = true表示当前线程是主线程
[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. void IPCThreadState::joinThreadPool(bool isMain)  
  2. {  
  3.   
  4.     mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);  
  5.     //设置线程组  
  6.     androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);  
  7.     status_t result;  
  8.     do {  
  9.         int32_t cmd;  
  10.         if (mIn.dataPosition() >= mIn.dataSize()) {  
  11.             size_t numPending = mPendingWeakDerefs.size();  
  12.             if (numPending > 0) {  
  13.                 for (size_t i = 0; i < numPending; i++) {  
  14.                     RefBase::weakref_type* refs = mPendingWeakDerefs[i];  
  15.                     refs->decWeak(mProcess.get());  
  16.                 }  
  17.                 mPendingWeakDerefs.clear();  
  18.             }  
  19.   
  20.             numPending = mPendingStrongDerefs.size();  
  21.             if (numPending > 0) {  
  22.                 for (size_t i = 0; i < numPending; i++) {  
  23.                     BBinder* obj = mPendingStrongDerefs[i];  
  24.                     obj->decStrong(mProcess.get());  
  25.                 }  
  26.                 mPendingStrongDerefs.clear();  
  27.             }  
  28.         }  
  29.   
  30.         //通知Binder驱动线程进入循环执行  
  31.         result = talkWithDriver();  
  32.         if (result >= NO_ERROR) {  
  33.             size_t IN = mIn.dataAvail();  
  34.             if (IN < sizeof(int32_t)) continue;  
  35.             //读取并执行Binder驱动返回来的命令  
  36.             cmd = mIn.readInt32();  
  37.             result = executeCommand(cmd);  
  38.         }  
  39.         androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);  
  40.         // 如果该线程不是主线程并且不在需要该线程时,线程退出  
  41.         if(result == TIMED_OUT && !isMain) {  
  42.             break;  
  43.         }  
  44.     } while (result != -ECONNREFUSED && result != -EBADF);  
  45.     //通知Binder驱动线程退出  
  46.     mOut.writeInt32(BC_EXIT_LOOPER);  
  47.     talkWithDriver(false);  
  48. }  
函数首先向IPCThreadState对象的mOut Parcel对象中写入BC_ENTER_LOOPER Binder协议命,该命令告诉Binder驱动该线程进入循环执行状态
[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);  
然后调用函数result = talkWithDriver()将mOut中的数据发送到Binder驱动程序中

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. status_t IPCThreadState::talkWithDriver(bool doReceive)  
  2. {  
  3.     ALOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");  
  4.       
  5.     binder_write_read bwr;  
  6.     const bool needRead = mIn.dataPosition() >= mIn.dataSize();  
  7.     const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;  
  8.       
  9.     bwr.write_size = outAvail;  
  10.     bwr.write_buffer = (long unsigned int)mOut.data();  
  11.   
  12.     if (doReceive && needRead) {  
  13.         bwr.read_size = mIn.dataCapacity();  
  14.         bwr.read_buffer = (long unsigned int)mIn.data();  
  15.     } else {  
  16.         bwr.read_size = 0;  
  17.         bwr.read_buffer = 0;  
  18.     }  
  19.       
  20.     // Return immediately if there is nothing to do.  
  21.     if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;  
  22.   
  23.     bwr.write_consumed = 0;  
  24.     bwr.read_consumed = 0;  
  25.     status_t err;  
  26.     do {  
  27. #if defined(HAVE_ANDROID_OS)  
  28.         if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)  
  29.             err = NO_ERROR;  
  30.         else  
  31.             err = -errno;  
  32. #else  
  33.         err = INVALID_OPERATION;  
  34. #endif  
  35.     } while (err == -EINTR);  
  36.   
  37.     if (err >= NO_ERROR) {  
  38.         if (bwr.write_consumed > 0) {  
  39.             if (bwr.write_consumed < (ssize_t)mOut.dataSize())  
  40.                 mOut.remove(0, bwr.write_consumed);  
  41.             else  
  42.                 mOut.setDataSize(0);  
  43.         }  
  44.         if (bwr.read_consumed > 0) {  
  45.             mIn.setDataSize(bwr.read_consumed);  
  46.             mIn.setDataPosition(0);  
  47.         }  
  48.         return NO_ERROR;  
  49.     }  
  50.     return err;  
  51. }  

通过ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)进入Binder驱动中,此时执行的Binder命令为BINDER_WRITE_READ,发送给Binder驱动的数据保存在binder_write_read结构体中
发送的数据为
bwr.write_size = outAvail;
bwr.write_buffer = (long unsigned int)mOut.data();
bwr.read_size = mIn.dataCapacity();
bwr.read_buffer = (long unsigned int)mIn.data();
在执行binder_ioctl()函数时先执行Binder驱动写在执行Binder驱动读操作

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)  
  2. {  
  3.     int ret;  
  4.     struct binder_proc *proc = filp->private_data;  
  5.     struct binder_thread *thread;  
  6.     unsigned int size = _IOC_SIZE(cmd);  
  7.     void __user *ubuf = (void __user *)arg;  
  8.     /*printk(KERN_INFO "binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/  
  9.     ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);  
  10.     if (ret)  
  11.         return ret;  
  12.   
  13.     mutex_lock(&binder_lock);  
  14.     thread = binder_get_thread(proc);  
  15.     if (thread == NULL) {  
  16.         ret = -ENOMEM;  
  17.         goto err;  
  18.     }  
  19.   
  20.     switch (cmd) {  
  21.     case BINDER_WRITE_READ: {  
  22.         struct binder_write_read bwr;  
  23.         if (size != sizeof(struct binder_write_read)) {  
  24.             ret = -EINVAL;  
  25.             goto err;  
  26.         }  
  27.         if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {  
  28.             ret = -EFAULT;  
  29.             goto err;  
  30.         }  
  31.         if (bwr.write_size > 0) {  
  32.             ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);  
  33.             if (ret < 0) {  
  34.                 bwr.read_consumed = 0;  
  35.                 if (copy_to_user(ubuf, &bwr, sizeof(bwr)))  
  36.                     ret = -EFAULT;  
  37.                 goto err;  
  38.             }  
  39.         }  
  40.         if (bwr.read_size > 0) {  
  41.             ret = binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK);  
  42.             if (!list_empty(&proc->todo))  
  43.                 wake_up_interruptible(&proc->wait);  
  44.             if (ret < 0) {  
  45.                 if (copy_to_user(ubuf, &bwr, sizeof(bwr)))  
  46.                     ret = -EFAULT;  
  47.                 goto err;  
  48.             }  
  49.         }  
  50.         if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {  
  51.             ret = -EFAULT;  
  52.             goto err;  
  53.         }  
  54.         break;  
  55.     }  
  56.     default:  
  57.         ret = -EINVAL;  
  58.         goto err;  
  59.     }  
  60.     ret = 0;  
  61. err:  
  62.     if (thread)  
  63.         thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN;  
  64.     mutex_unlock(&binder_lock);  
  65.     wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);  
  66.     if (ret && ret != -ERESTARTSYS)  
  67.         printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret);  
  68.     return ret;  
  69. }  

在内核数据发送缓冲区中保存了BC_ENTER_LOOPER命令,因此在执行binder_thread_write函数时,只处理BC_ENTER_LOOPER命令

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,  
  2.             void __user *buffer, int size, signed long *consumed)  
  3. {  
  4.     uint32_t cmd;  
  5.     void __user *ptr = buffer + *consumed;  
  6.     void __user *end = buffer + size;  
  7.   
  8.     while (ptr < end && thread->return_error == BR_OK) {  
  9.         if (get_user(cmd, (uint32_t __user *)ptr))  
  10.             return -EFAULT;  
  11.         ptr += sizeof(uint32_t);  
  12.         if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) {  
  13.             binder_stats.bc[_IOC_NR(cmd)]++;  
  14.             proc->stats.bc[_IOC_NR(cmd)]++;  
  15.             thread->stats.bc[_IOC_NR(cmd)]++;  
  16.         }  
  17.         switch (cmd) {  
  18.         case BC_ENTER_LOOPER:  
  19.             if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) {  
  20.                 thread->looper |= BINDER_LOOPER_STATE_INVALID;  
  21.             }  
  22.             thread->looper |= BINDER_LOOPER_STATE_ENTERED;  
  23.             break;  
  24.         default:  
  25.             printk(KERN_ERR "binder: %d:%d unknown command %d\n",  
  26.                    proc->pid, thread->pid, cmd);  
  27.             return -EINVAL;  
  28.         }  
  29.         *consumed = ptr - buffer;  
  30.     }  
  31.     return 0;  
  32. }  

BC_ENTER_LOOPER命令下的处理非常简单,仅仅是将当前线程binder_thread的状态标志位设置为BINDER_LOOPER_STATE_ENTERED,binder_thread_write函数执行完后,由于bwr.read_size > 0,因此binder_ioctl()函数还会执行Binder驱动读

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. static int binder_thread_read(struct binder_proc *proc,  
  2.                   struct binder_thread *thread,  
  3.                   void  __user *buffer, int size,  
  4.                   signed long *consumed, int non_block)  
  5. {  
  6.     void __user *ptr = buffer + *consumed;  
  7.     void __user *end = buffer + size;  
  8.   
  9.     int ret = 0;  
  10.     int wait_for_proc_work;  
  11.     //向用户空间发送一个BR_NOOP  
  12.     if (*consumed == 0) {  
  13.         if (put_user(BR_NOOP, (uint32_t __user *)ptr))  
  14.             return -EFAULT;  
  15.         ptr += sizeof(uint32_t);  
  16.     }  
  17. retry:  
  18.     //由于当前线程首次注册到Binder驱动中,因此事务栈和待处理队列都为空,wait_for_proc_work = true  
  19.     wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo);  
  20.     //在初始化binder_thread时,return_error被初始化为BR_OK,因此这里为false  
  21.     if (thread->return_error != BR_OK && ptr < end) {  
  22.         if (thread->return_error2 != BR_OK) {  
  23.             if (put_user(thread->return_error2, (uint32_t __user *)ptr))  
  24.                 return -EFAULT;  
  25.             ptr += sizeof(uint32_t);  
  26.             if (ptr == end)  
  27.                 goto done;  
  28.             thread->return_error2 = BR_OK;  
  29.         }  
  30.         if (put_user(thread->return_error, (uint32_t __user *)ptr))  
  31.             return -EFAULT;  
  32.         ptr += sizeof(uint32_t);  
  33.         thread->return_error = BR_OK;  
  34.         goto done;  
  35.     }  
  36.     //设置当前线程的运行状态为BINDER_LOOPER_STATE_WAITING  
  37.     thread->looper |= BINDER_LOOPER_STATE_WAITING;  
  38.     if (wait_for_proc_work)  
  39.         proc->ready_threads++;  
  40.     mutex_unlock(&binder_lock);  
  41.     if (wait_for_proc_work) {  
  42.         //在注册Binder线程时已经设置为BINDER_LOOPER_STATE_ENTERED,因此这里的条件为false  
  43.         if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED))) {  
  44.             wait_event_interruptible(binder_user_error_wait,binder_stop_on_user_error < 2);  
  45.         }  
  46.         //设置线程默认优先级  
  47.         binder_set_nice(proc->default_priority);  
  48.         if (non_block) {  
  49.             if (!binder_has_proc_work(proc, thread))  
  50.                 ret = -EAGAIN;  
  51.         } else  
  52.             //在为当前线程创建binder_thread时,线程状态标志位被初始化为BINDER_LOOPER_STATE_NEED_RETURN,因此binder_has_proc_work函数返回true,当前线程睡眠在当前进程的等待队列中  
  53.             ret = wait_event_interruptible_exclusive(proc->wait, binder_has_proc_work(proc, thread));  
  54.     } else {  
  55.         ...  
  56.     }  
  57.     mutex_lock(&binder_lock);  
  58.     if (wait_for_proc_work)  
  59.         proc->ready_threads--;  
  60.     thread->looper &= ~BINDER_LOOPER_STATE_WAITING;  
  61.     if (ret)  
  62.         return ret;  
  63.     while (1) {  
  64.         uint32_t cmd;  
  65.         struct binder_transaction_data tr;  
  66.         struct binder_work *w;  
  67.         struct binder_transaction *t = NULL;  
  68.         if (!list_empty(&thread->todo))  
  69.             w = list_first_entry(&thread->todo, struct binder_work, entry);  
  70.         else if (!list_empty(&proc->todo) && wait_for_proc_work)  
  71.             w = list_first_entry(&proc->todo, struct binder_work, entry);  
  72.         else {  
  73.             if (ptr - buffer == 4 && !(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN)) /* no data added */  
  74.                 goto retry;  
  75.             break;  
  76.         }  
  77.         if (end - ptr < sizeof(tr) + 4)  
  78.             break;  
  79.   
  80.         switch (w->type) {  
  81.         case BINDER_WORK_TRANSACTION:   
  82.             break;  
  83.         case BINDER_WORK_TRANSACTION_COMPLETE:   
  84.             break;  
  85.         case BINDER_WORK_NODE:   
  86.             break;  
  87.         case BINDER_WORK_DEAD_BINDER:  
  88.         case BINDER_WORK_DEAD_BINDER_AND_CLEAR:  
  89.         case BINDER_WORK_CLEAR_DEATH_NOTIFICATION:   
  90.             break;  
  91.     }  
  92.   
  93. done:  
  94.     *consumed = ptr - buffer;  
  95.     if (proc->requested_threads + proc->ready_threads == 0 &&  
  96.         proc->requested_threads_started < proc->max_threads &&  
  97.         (thread->looper & (BINDER_LOOPER_STATE_REGISTERED |  
  98.          BINDER_LOOPER_STATE_ENTERED))) {  
  99.         proc->requested_threads++;  
  100.         if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer))  
  101.             return -EFAULT;  
  102.     }  
  103.     return 0;  
  104. }  

这样就将当前线程注册到了Binder驱动中,同时该线程进入睡眠等待客户端请求,当有客户端请求到来时,该Binder线程被唤醒,接收并处理客户端的请求。因此Android应用程序通过注册Binder线程来支持Binder进程间通信机制。

2
0

0 0
原创粉丝点击