在 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);
}