无论是在Activity启动流程 上篇(Android 10)还是在SystemServer启动流程中都有提到,在fork出进程之后都会调用到ZygoteInit.nativeZygoteInit()
也就是启动binder相关的内容。本篇将从这个函数开始,详细讲讲这个函数到底是如何开启binder的。
该函数在\frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
的声明如下:
private static final native void nativeZygoteInit();
是一个本地方法,在\frameworks\base\cmds\app_process\app_main.cpp
中:
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
首先来看ProcessState::self()
sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
if (gProcess != nullptr) {
return gProcess;
}
gProcess = new ProcessState(DEFAULT_BINDER_VM_SIZE);
return gProcess;
}
这里单例创建了ProcessState
,传入了一个参数DEFAULT_BINDER_VM_SIZE
,其定义为:
#define DEFAULT_BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
也就是我们常说的1M-8K,ProcessState
的构造函数如下:
ProcessState::ProcessState(size_t mmap_size)
: mDriverFD(open_driver())
, mVMStart(MAP_FAILED)
, mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
, mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
, mExecutingThreadsCount(0)
, mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
, mStarvationStartTimeMs(0)
, mManagesContexts(false)
, mBinderContextCheckFunc(nullptr)
, mBinderContextUserData(nullptr)
, mThreadPoolStarted(false)
, mSpawnThreadOnStart(true)
, mThreadPoolSeq(1)
, mMmapSize(mmap_size)
, mCallRestriction(CallRestriction::NONE)
{
if (mDriverFD >= 0) {
// mmap the binder, providing a chunk of virtual address space to receive transactions.
mVMStart = mmap(nullptr, mMmapSize, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
if (mVMStart == MAP_FAILED) {
// *sigh*
ALOGE("Mmapping /dev/hwbinder failed: %s\n", strerror(errno));
close(mDriverFD);
mDriverFD = -1;
}
}
else {
ALOGE("Binder driver could not be opened. Terminating.");
}
}
这里初始化了一系列参数,最重要的就是第二个参数mDriverFD(open_driver())
,其打开了Binder驱动并设置了一些值:
static int open_driver()
{
//打开binder驱动
int fd = open("/dev/hwbinder", O_RDWR | O_CLOEXEC);
if (fd >= 0) {
int vers = 0;
//发送binder版本
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(%d) does not match user space protocol(%d)!", vers, BINDER_CURRENT_PROTOCOL_VERSION);
close(fd);
fd = -1;
}
size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
//发送binder最大线程
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/hwbinder' failed: %s\n", strerror(errno));
}
return fd;
}
回到上面的onZygoteInit()
函数,该函数调用完ProcessState::self()
之后调用了proc->startThreadPool()
,也就是ProcessState
的startThreadPool
函数:
void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
if (mSpawnThreadOnStart) {
//spawn:产卵,产生Binder线程池线程,和zygote意思差不多,还是比较形象的。
spawnPooledThread(true);
}
}
}
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
String8 name = makeBinderThreadName();
ALOGV("Spawning new pooled thread, name=%s\n", name.string());
sp<Thread> t = new PoolThread(isMain);
t->run(name.string());
}
}
这里首先创建了PoolThread,之后调用了其run方法,这个线程了定义如下,继承了Thread类,这个Thread类是android自己定义的,路径为\system\libhwbinder\ProcessState.cpp
,这里可以简单的认为,其会运行threadLoop
中的内容即可,如果想了解更多信息的话,可以参考Android Framework中的线程Thread及它的threadLoop方法:
class PoolThread : public Thread
{
public:
explicit PoolThread(bool isMain)
: mIsMain(isMain)
{
}
protected:
virtual bool threadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain);
return false;
}
const bool mIsMain;
};
IPCThreadState::self()
内容如下
static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
static bool gHaveTLS = false;
static pthread_key_t gTLS = 0;
static bool gShutdown = false;
IPCThreadState* IPCThreadState::self()
{
if (gHaveTLS) {
restart:
const pthread_key_t k = gTLS;
IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
if (st) return st;
return new IPCThreadState;
}
if (gShutdown) {
ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n");
return nullptr;
}
pthread_mutex_lock(&gTLSMutex);
if (!gHaveTLS) {
int key_create_value = pthread_key_create(&gTLS, threadDestructor);
if (key_create_value != 0) {
pthread_mutex_unlock(&gTLSMutex);
ALOGW("IPCThreadState::self() unable to create TLS key, expect a crash: %s\n",
strerror(key_create_value));
return nullptr;
}
gHaveTLS = true;
}
pthread_mutex_unlock(&gTLSMutex);
goto restart;
}
该函数gHaveTLS
初始值为false
,所以先直接来到最后一个if判断,首先创建一个ThreadLocal key
,这里和java的ThreadLocal key
一个道理,然后返回到restart
,获取这个key
对应的IPCThreadState
如果为null
,则创建一个,所以可以明白,每个线程都有自己的一个IPCThreadState
,如果没有,则创建,当然这一点从名字也可以看出来。
回到上面IPCThreadState::self()
调用完成,需要调用IPCThreadState
的joinThreadPool
函数了:
void IPCThreadState::joinThreadPool(bool isMain)
{
LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
//告诉驱动线程将进入循环
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
status_t result;
mIsLooper = true;
do {
processPendingDerefs();
// now get the next command to be processed, waiting if necessary
//获取和执行命令
result = getAndExecuteCommand();
if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
mProcess->mDriverFD, result);
abort();
}
// 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) {
break;
}
} while (result != -ECONNREFUSED && result != -EBADF);
LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%d\n",
(void*)pthread_self(), getpid(), result);
mOut.writeInt32(BC_EXIT_LOOPER);
mIsLooper = false;
talkWithDriver(false);
}
在这里等待和binder驱动传送命令过来,并执行(详见getAndExecuteCommand()
,不再赘述),如果不是主线程则退出循环,主线程则继续循环。至此,进程中的binder线程就启动完成了。