在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 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& 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& 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& 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;
......
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& recipient, void* cookie, uint32_t flags,
wp* outRecipient)
{
......
const size_t N = mObituaries ? mObituaries->size() : 0;
// 在mObituaries中查找相应的recipient
for (size_t i=0; iitemAt(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* 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; iitemAt(i));
}
delete obits;
}
}
void BpBinder::reportOneDeath(const Obituary& obit)
{
sp recipient = obit.recipient.promote();
ALOGV("Reporting death to recipient: %p\n", recipient.get());
if (recipient == NULL) return;
// 调用上层应用死亡通知的binderDied
recipient->binderDied(this);
}