在Binder通信建立后,Client端可能需要知道Server端的存活状态。当Server端挂掉时,Client端需要清理与通信相关的数据和行为,这个清理过程就是通过Binder死亡通知机制实现的。
应用层通过调用BpBinder::linkToDeath()来注册死亡通知。Native Binder通信可以直接调用这个接口,Java通信需要通过Jni来调用。
frameworks/base/core/jni/android_util_Binder.cpp static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj, jobject recipient, jint flags) // throws RemoteException { ...... // 获取BpBinder对象 IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject); ...... // 只有远程传输需要注册死亡通知 if (!target->localBinder()) { // 获取死亡通知队列 DeathRecipientList* list = (DeathRecipientList*) env->GetLongField(obj, gBinderProxyOffsets.mOrgue); // 创建JavaDeathRecipient对象,将其加入到死亡回收队列 sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list); // 调用BpBinder::linkToDeath()来建立死亡通知 status_t err = target->linkToDeath(jdr, NULL, flags); ...... } }
处理死亡通知的是JavaDeathRecipient,它继承IBinder::DeathRecipient,接收到死亡通知时会回调binderDied()。
frameworks/base/core/jni/android_util_Binder.cpp class JavaDeathRecipient : public IBinder::DeathRecipient { public: JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list) : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)), mObjectWeak(NULL), mList(list) { ...... // 加入到回收队列 list->add(this); android_atomic_inc(&gNumDeathRefs); // 增加对象引用计数,当创建对象个数达到200时强行出发GC incRefsCreated(env); } void binderDied(const wp<IBinder>& who) { if (mObject != NULL) { JNIEnv* env = javavm_to_jnienv(mVM); // 调用Java的sendDeathNotice方法 env->CallStaticVoidMethod(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mSendDeathNotice, mObject); ...... // 释放全局引用,增加弱引用,以便GC回收 mObjectWeak = env->NewWeakGlobalRef(mObject); env->DeleteGlobalRef(mObject); mObject = NULL; } }
Java的注册过程最终也是指向到BpBinder中。死亡通知的注销也同样在这里,一起看一下。
frameworks/native/libs/binder/BpBinder.cpp status_t BpBinder::linkToDeath( const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags) { Obituary ob; ob.recipient = recipient; ob.cookie = cookie; ob.flags = flags; ...... // 如果死亡通知已经发出,mObitsSent将被设置 if (!mObitsSent) { // 第一个死亡通知将创建mObituaries,并向驱动注册死亡通知 if (!mObituaries) { mObituaries = new Vector<Obituary>; ...... getWeakRefs()->incWeak(this); // 向驱动注册死亡通知 IPCThreadState* self = IPCThreadState::self(); self->requestDeathNotification(mHandle, this); self->flushCommands(); } // 加入到mObituaries中 ssize_t res = mObituaries->add(ob); return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res; } ...... } status_t BpBinder::unlinkToDeath( const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags, wp<DeathRecipient>* outRecipient) { ...... const size_t N = mObituaries ? mObituaries->size() : 0; // 在mObituaries中查找相应的recipient for (size_t i=0; i<N; i++) { const Obituary& obit = mObituaries->itemAt(i); if ((obit.recipient == recipient || (recipient == NULL && obit.cookie == cookie)) && obit.flags == flags) { const uint32_t allFlags = obit.flags|flags; if (outRecipient != NULL) { *outRecipient = mObituaries->itemAt(i).recipient; } // 将死亡通知从mObituaries移除 mObituaries->removeAt(i); // 如果是mObituaries中最后一个死亡通知,则像驱动注销死亡通知 if (mObituaries->size() == 0) { ALOGV("Clearing death notification: %p handle %d/n", this, mHandle); // 与驱动交互 IPCThreadState* self = IPCThreadState::self(); self->clearDeathNotification(mHandle, this); self->flushCommands(); delete mObituaries; mObituaries = NULL; } return NO_ERROR; } } ...... }
Obituary翻译过来是讣告的意思,也就是死亡通知,这里用中文解释就有些混乱。一个Binder代理在驱动上只注册一次死亡通知,但是多个应用可以同时注册Obituary到Binder代理上。就是说一个Binder代理接收到死亡通知后可以告诉多个感兴趣的应用,但其都来源于一个死亡通知。真正注册和注销死亡通知是通过IPCThreadState实现的。
frameworks/native/libs/binder/IPCThreadState.cpp void IPCThreadState::flushCommands() { if (mProcess->mDriverFD <= 0) return; // 向驱动发送命令,不需要回复 talkWithDriver(false); } ...... status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* proxy) { // 注册死亡通知命令 mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION); mOut.writeInt32((int32_t)handle); mOut.writePointer((uintptr_t)proxy); return NO_ERROR; } status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy) { // 注销死亡通知命令 mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION); mOut.writeInt32((int32_t)handle); mOut.writePointer((uintptr_t)proxy); return NO_ERROR; }
接下来进入到驱动中,看看死亡通知命令的处理过程。
drivers/staging/android/binder.c static int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, binder_uintptr_t binder_buffer, size_t size, binder_size_t *consumed) { ...... case BC_REQUEST_DEATH_NOTIFICATION: case BC_CLEAR_DEATH_NOTIFICATION: { uint32_t target; binder_uintptr_t cookie; struct binder_ref *ref; struct binder_ref_death *death; // 获取用户空间数据 if (get_user(target, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); if (get_user(cookie, (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); // 根据handle获取binder引用 ref = binder_get_ref(proc, target, false); ...... if (cmd == BC_REQUEST_DEATH_NOTIFICATION) ...... // 分配binder_ref_death结构 death = kzalloc(sizeof(*death), GFP_KERNEL); ...... binder_stats_created(BINDER_STAT_DEATH); // 初始化death工作队列 INIT_LIST_HEAD(&death->work.entry); death->cookie = cookie; ref->death = death; // 如果proc死掉,发送死亡通知 if (ref->node->proc == NULL) { ref->death->work.type = BINDER_WORK_DEAD_BINDER; if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { list_add_tail(&ref->death->work.entry, &thread->todo); } else { list_add_tail(&ref->death->work.entry, &proc->todo); wake_up_interruptible(&proc->wait); } } } else { ...... death = ref->death; ...... // 清除binder引用的death ref->death = NULL; if (list_empty(&death->work.entry)) { // 加入清理死亡通知work到队列 death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { list_add_tail(&death->work.entry, &thread->todo); } else { list_add_tail(&death->work.entry, &proc->todo); wake_up_interruptible(&proc->wait); } } else { // 死亡通知已经发生,修改work的类型 BUG_ON(death->work.type != BINDER_WORK_DEAD_BINDER); death->work.type = BINDER_WORK_DEAD_BINDER_AND_CLEAR; } } } break; ...... }
死亡通知的注册过程就是创建一个binder_ref_death结构,赋值给Binder引用的death上,Binder实体死亡时会根据death发送死亡通知。注销死亡通知的过程就是清理Binder引用的death,并创建一个清理的work。
drivers/staging/android/binder.c static int binder_thread_read(struct binder_proc *proc, struct binder_thread *thread, binder_uintptr_t binder_buffer, size_t size, binder_size_t *consumed, int non_block) { ...... case BINDER_WORK_DEAD_BINDER: case BINDER_WORK_DEAD_BINDER_AND_CLEAR: case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: { struct binder_ref_death *death; uint32_t cmd; death = container_of(w, struct binder_ref_death, work); if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) // 注销时回复这个命令 cmd = BR_CLEAR_DEATH_NOTIFICATION_DONE; Else // Binder死亡时回复这个命令 cmd = BR_DEAD_BINDER; ...... if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) { // 注销时释放death list_del(&w->entry); kfree(death); binder_stats_deleted(BINDER_STAT_DEATH); } else list_move(&w->entry, &proc->delivered_death); if (cmd == BR_DEAD_BINDER) goto done; /* DEAD_BINDER notifications can cause transactions */ } break; ...... }
Binder进程退出或异常终止时都会调用exit流程,在Binder驱动中会调用到binder_release。Release中会启动一个BINDER_DEFERRED_RELEASE内核workqueue,这里进行具体的清理工作。
drivers/staging/android/binder.c static int binder_release(struct inode *nodp, struct file *filp) { struct binder_proc *proc = filp->private_data; debugfs_remove(proc->debugfs_entry); // 启动workqueue binder_defer_work(proc, BINDER_DEFERRED_RELEASE); return 0; } static int binder_node_release(struct binder_node *node, int refs) { ...... list_del_init(&node->work.entry); binder_release_work(&node->async_todo); ...... // 循环处理binder实体中的每一个引用 hlist_for_each_entry(ref, &node->refs, node_entry) { ...... if (list_empty(&ref->death->work.entry)) { // 将Binder死亡work加入到进程的todo队列 ref->death->work.type = BINDER_WORK_DEAD_BINDER; list_add_tail(&ref->death->work.entry, &ref->proc->todo); wake_up_interruptible(&ref->proc->wait); } else BUG(); } ...... } static void binder_deferred_release(struct binder_proc *proc) { ...... while ((n = rb_first(&proc->nodes))) { struct binder_node *node; node = rb_entry(n, struct binder_node, rb_node); nodes++; rb_erase(&node->rb_node, &proc->nodes); // 释放Binder实体 incoming_refs = binder_node_release(node, incoming_refs); } ...... }
Binder驱动处理完release后会将BR_DEAD_BINDER命令发送给应用层。
frameworks/native/libs/binder/IPCThreadState.cpp status_t IPCThreadState::executeCommand(int32_t cmd) { ...... case BR_DEAD_BINDER: { BpBinder *proxy = (BpBinder*)mIn.readPointer(); // 调用Binder代理的sendObituary proxy->sendObituary(); // 告诉驱动死亡通知已经处理 mOut.writeInt32(BC_DEAD_BINDER_DONE); mOut.writePointer((uintptr_t)proxy); } break; ...... }
Binder代理处理死亡回收工作,最终回调到binderDied()上。
frameworks/native/libs/binder/BpBinder.cpp void BpBinder::sendObituary() { ...... mLock.lock(); Vector<Obituary>* obits = mObituaries; // 向驱动发送注销死亡通知命令 if(obits != NULL) { ALOGV("Clearing sent death notification: %p handle %d/n", this, mHandle); IPCThreadState* self = IPCThreadState::self(); self->clearDeathNotification(mHandle, this); self->flushCommands(); mObituaries = NULL; } // 设置flag,表明收到死亡通知 mObitsSent = 1; mLock.unlock(); ...... if (obits != NULL) { const size_t N = obits->size(); // 循环给mObituaries中每一个向量发送死亡通知 for (size_t i=0; i<N; i++) { reportOneDeath(obits->itemAt(i)); } delete obits; } } void BpBinder::reportOneDeath(const Obituary& obit) { sp<DeathRecipient> recipient = obit.recipient.promote(); ALOGV("Reporting death to recipient: %p/n", recipient.get()); if (recipient == NULL) return; // 调用上层应用死亡通知的binderDied recipient->binderDied(this); }