本文参考《Android系统源代码情景分析》,作者罗升阳
一、测试代码:
~/Android/external/binder/server
----FregServer.cpp
~/Android/external/binder/common
----IFregService.cpp
----IFregService.h
~/Android/external/binder/client
----FregClient.cpp
Binder库(libbinder)代码:
~/Android/frameworks/base/libs/binder
----BpBinder.cpp
----Parcel.cpp
----ProcessState.cpp
----Binder.cpp
----IInterface.cpp
----IPCThreadState.cpp
----IServiceManager.cpp
----Static.cpp
~/Android/frameworks/base/include/binder
----Binder.h
----BpBinder.h
----IInterface.h
----IPCThreadState.h
----IServiceManager.h
----IBinder.h
----Parcel.h
----ProcessState.h
驱动层代码:
~/Android//kernel/goldfish/drivers/staging/android
----binder.c
----binder.h
二、源码分析
继续上一篇Android Binder进程间通信---FregServer进程,处理BC_REPLY,返回BR_REPLYhttp://blog.csdn.net/jltxgcy/article/details/26339313,执行完waitForResponse函数,参考Android Binder进程间通信---FregServer进程,发送BC_TRANSACTION,睡眠等待http://blog.csdn.net/jltxgcy/article/details/26076149。应该返回IPCThreadState类的transact方法,再返回BpBinder类的transact函数,最后返回BpServiceManager类addService函数。最后再返回FregService类的main函数,实现如下:
~/Android/external/binder/server
----FregServer.cpp
int main(int argc, char** argv)
{
FregService::instantiate();
ProcessState::self()->startThreadPool();//启动一个Binder线程池
IPCThreadState::self()->joinThreadPool();//主线程加入线程池
return 0;
}
首先当前进程的ProcessState对象的成员函数startThreadPool来启动一个Binder线程池,接着继续调用当前线程的IPCThreadState对象的成员函数joinThreadPool,将当前线程加入到前面所启动的Binder线程池中去等待和处理来自Client进程的进程间通信请求。
下面我们就分析ProcessState类的成员函数startThreadPool的实现,在分析过程中,同时也会分析IPCThreadState类的成员函数joinThreadPool的实现。
ProcessState类的成员函数startThreadPool的实现如下:
~/Android/frameworks/base/libs/binder
----ProcessState.cpp
void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {//默认值为false
mThreadPoolStarted = true;//防止它的成员函数spawnPooledThread被重复调用来启动Binder线程池
spawnPooledThread(true);
}
}
当前进程的ProcessState对象的成员变量mThreadPoolStarted被初始化为false,当它将一个Binder线程池启动起来之后,就会将内部的成员变量mThreadPoolStarted的值设置为true,防止它的成员函数spawnPooledThread被重复调用来启动Binder线程池。spawnPooledThread函数实现如下:
~/Android/frameworks/base/libs/binder
----ProcessState.cpp
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
int32_t s = android_atomic_add(1, &mThreadPoolSeq);
char buf[32];
sprintf(buf, "Binder Thread #%d", s);
LOGV("Spawning new pooled thread, name=%s\n", buf);
sp<Thread> t = new PoolThread(isMain);//isMain为true
t->run(buf);//启动一个新的线程
}
}
创建了一个PoolThread对象t,调用它的成员函数run来启动一个新的线程。
PoolThread类继承了线程类Thread,并且重写了它的线程入口成员函数threadLoop,因此当一个PoolThread对象t所对应的线程启动起来之后,它的成员函数threadLoop就会被调用。实现如下:
~/Android/frameworks/base/libs/binder
----ProcessState.cpp
class PoolThread : public Thread
{
public:
PoolThread(bool isMain)
: mIsMain(isMain)//isMain为true
{
}
protected:
virtual bool threadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain);//isMain为true
return false;
}
const bool mIsMain;
};
和主线程一样调用了IPCThreadState类的成员函数joinThreadPool。实现如下:
~/Android/frameworks/base/libs/binder
----IPCThreadState.cpp
void IPCThreadState::joinThreadPool(bool isMain)//默认值为true
{
.........
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);//isMain为true,BC_ENTER_LOOPER
........
status_t result;
do {
int32_t cmd;
.......
result = talkWithDriver();//将自己注册到Binder线程池中,一个无线循环中不断等待进程间通信请求
if (result >= NO_ERROR) {
size_t IN = mIn.dataAvail();
if (IN < sizeof(int32_t)) continue;
cmd = mIn.readInt32();
........
result = executeCommand(cmd);//处理进程间通信请求
}
.........
if(result == TIMED_OUT && !isMain) {//一直为false,因为isMain为true
break;
}
} while (result != -ECONNREFUSED && result != -EBADF);
........
mOut.writeInt32(BC_EXIT_LOOPER);//退出Binder线程池
talkWithDriver(false);
}
参数isMain是一个默认参数,它的默认值为true。从前面的调用过程可以知道,无论是FregServer进程的主线程,还是FregServer进程刚才所创建的线程,它们都是主动(isMain为true)请求加入到Binder线程池的,即它们都不是由于Binder驱动程序请求创建而加入到Binder线程池的。
一个Binder线程的生命周期可以划分为三个阶段:
第一阶段是将自己注册到Binder线程池中;
第二阶段是一个无线循环中不断等待和处理进程间通信请求;
第三阶段是退出Binder线程池。
最后执行完的结果是FregServer有两个线程,睡眠等待进程间通信数据的到来。