IPCThreadState
来源:互联网 发布:淘宝手机充值代理加盟 编辑:程序博客网 时间:2024/04/30 06:56
IPCThreadState的构造函数是private的:
private:
IPCThreadState();
因此,IPCThreadState类的对象,就只能通过成员函数self()来生成:
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) return NULL;
pthread_mutex_lock(&gTLSMutex);
if (!gHaveTLS)
{
if (pthread_key_create(&gTLS, threadDestructor) != 0)
{
pthread_mutex_unlock(&gTLSMutex);
return NULL;
}
gHaveTLS = true;
}
pthread_mutex_unlock(&gTLSMutex);
goto restart;
}
IPCThreadState类的构造函数:
IPCThreadState::IPCThreadState()
: mProcess(ProcessState::self()),
mMyThreadId(androidGetTid()),
mStrictModePolicy(0),
mLastTransactionBinderFlags(0)
{
pthread_setspecific(gTLS, this);
clearCaller();
mIn.setDataCapacity(256);
mOut.setDataCapacity(256);
}
设置mIn和mOut两个Parcel的Capacity
IPCThreadState类中,有一个重要的函数,也是private的:
private:
status_t talkWithDriver(bool doReceive=true);
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
if (mProcess->mDriverFD <= 0)
{
return -EBADF;
}
binder_write_read bwr;
// Is the read buffer empty?
// dataPosition() >= dataSize() 表示mIn中的数据已经被全部读取,没有剩余数据,是empty buffer
const bool needRead = mIn.dataPosition() >= mIn.dataSize();
// We don't want to write anything if we are still reading
// from data left in the input buffer and the caller
// has requested to read the next data.
// 这个地方有点难理解:
// needRead为true,表示mIn是empty buffer,可以更新其中的内容,因此此时不管是否需要更新mIn中的数据,
// 都可以将mOut中的数据写入binder driver, needRead为false时,表示mIn中还有剩余数据,此时只有当doReceive
// 为false时,不需要更新mIn中的数据时,才能将mOut中的数据写入binder driver;
// doReceive为false时,不需要更新mIn中的数据,此时mIn是不是empty buffer不重要,都可以将mOut中的数据写入
// binder driver,如果doReceiver为true,需要更新mIn中的数据,此时needRead必须为true;
const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
bwr.write_size = outAvail;
bwr.write_buffer = (long unsigned int)mOut.data();
// This is what we'll read.
// mIn中的数据需要更新,并且mIn中没有剩余数据时,mIn中的数据才可以更新
if (doReceive && needRead)
{
// /* bytes to read */
bwr.read_size = mIn.dataCapacity();
bwr.read_buffer = (long unsigned int)mIn.data();
}
else
{
bwr.read_size = 0;
bwr.read_buffer = 0;
}
// Return immediately if there is nothing to do.
if ((bwr.write_size == 0) && (bwr.read_size == 0))
return NO_ERROR;
bwr.write_consumed = 0;
bwr.read_consumed = 0;
status_t err;
do
{
IF_LOG_COMMANDS()
{
alog << "About to read/write, write size = " << mOut.dataSize() << endl;
}
#if defined(HAVE_ANDROID_OS)
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
#else
err = INVALID_OPERATION;
#endif
if (mProcess->mDriverFD <= 0)
{
err = -EBADF;
}
}
while (err == -EINTR);
if (err >= NO_ERROR)
{
if (bwr.write_consumed > 0)
{
if (bwr.write_consumed < (ssize_t)mOut.dataSize())
mOut.remove(0, bwr.write_consumed);
else
mOut.setDataSize(0);
}
if (bwr.read_consumed > 0)
{
mIn.setDataSize(bwr.read_consumed);
mIn.setDataPosition(0);
}
return NO_ERROR;
}
return err;
}
关于talkWithDriver函数参数doReceive的作用,代码中没有注释,只是缺省其值为true,因此,可以从代码中了解参数doReceive的作用,代码中用到函数talkWithDriver的地方并不多:
查看这几个代码片段,不难发现,当doReceive为true时,talkWithDriver函数后会紧跟对mIn中数据进行处理的代码片段,当doReceive为false时,则后面没有任何对mIn中数据进行处理的代码:
为false时:
为true时:
通过代码,可以确定参数doReceive值的意义:
当doReceive为true时,表示mIn中会收到新的数据,mIn中的数据更新;
当doReceive为false时,表示mIn中不会收到新的数据,mIn中的数据不会更新,函数调用对mIn中现在的数据没有影响;
结构体binder_write_read的定义可以在内核源码文件binder.h中找到:
struct binder_write_read
{
signed long write_size; /* bytes to write */
signed long write_consumed; /* bytes consumed by driver */
unsigned long write_buffer;
signed long read_size; /* bytes to read */
signed long read_consumed; /* bytes consumed by driver */
unsigned long read_buffer;
};
函数调用 if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)将指向结构体变量bwr的指针传递给binder driver函数:
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
查看binder_ioctl函数的实现代码:
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int ret;
struct binder_proc *proc = filp->private_data;
struct binder_thread *thread;
unsigned int size = _IOC_SIZE(cmd);
void __user *ubuf = (void __user *)arg;
/*printk(KERN_INFO "binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/
trace_binder_ioctl(cmd, arg);
ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
if (ret)
goto err_unlocked;
binder_lock(__func__);
thread = binder_get_thread(proc);
if (thread == NULL) {
ret = -ENOMEM;
goto err;
}
switch (cmd) {
case BINDER_WRITE_READ: {
struct binder_write_read bwr;
if (size != sizeof(struct binder_write_read)) {
ret = -EINVAL;
goto err;
}
// 将数据从用户空间,复制到内核空间,变量bwr占据的空间
if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
ret = -EFAULT;
goto err;
}
binder_debug(BINDER_DEBUG_READ_WRITE,
"binder: %d:%d write %ld at %08lx, read %ld at %08lx\n",
proc->pid, thread->pid, bwr.write_size, bwr.write_buffer,
bwr.read_size, bwr.read_buffer);
if (bwr.write_size > 0) {
ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);
trace_binder_write_done(ret);
if (ret < 0) {
bwr.read_consumed = 0;
if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
ret = -EFAULT;
goto err;
}
}
if (bwr.read_size > 0) {
ret = binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK);
trace_binder_read_done(ret);
if (!list_empty(&proc->todo))
wake_up_interruptible(&proc->wait);
if (ret < 0) {
if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
ret = -EFAULT;
goto err;
}
}
binder_debug(BINDER_DEBUG_READ_WRITE,
"binder: %d:%d wrote %ld of %ld, read return %ld of %ld\n",
proc->pid, thread->pid, bwr.write_consumed, bwr.write_size,
bwr.read_consumed, bwr.read_size);
if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
ret = -EFAULT;
goto err;
}
break;
}
case BINDER_SET_MAX_THREADS:
if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) {
ret = -EINVAL;
goto err;
}
break;
case BINDER_SET_CONTEXT_MGR:
if (binder_context_mgr_node != NULL) {
printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already set\n");
ret = -EBUSY;
goto err;
}
ret = security_binder_set_context_mgr(proc->tsk);
if (ret < 0)
goto err;
if (binder_context_mgr_uid != -1) {
if (binder_context_mgr_uid != current->cred->euid) {
printk(KERN_ERR "binder: BINDER_SET_"
"CONTEXT_MGR bad uid %d != %d\n",
current->cred->euid,
binder_context_mgr_uid);
ret = -EPERM;
goto err;
}
} else
binder_context_mgr_uid = current->cred->euid;
binder_context_mgr_node = binder_new_node(proc, NULL, NULL);
if (binder_context_mgr_node == NULL) {
ret = -ENOMEM;
goto err;
}
binder_context_mgr_node->local_weak_refs++;
binder_context_mgr_node->local_strong_refs++;
binder_context_mgr_node->has_strong_ref = 1;
binder_context_mgr_node->has_weak_ref = 1;
break;
case BINDER_THREAD_EXIT:
binder_debug(BINDER_DEBUG_THREADS, "binder: %d:%d exit\n",
proc->pid, thread->pid);
binder_free_thread(proc, thread);
thread = NULL;
break;
case BINDER_VERSION:
if (size != sizeof(struct binder_version)) {
ret = -EINVAL;
goto err;
}
if (put_user(BINDER_CURRENT_PROTOCOL_VERSION, &((struct binder_version *)ubuf)->protocol_version)) {
ret = -EINVAL;
goto err;
}
break;
default:
ret = -EINVAL;
goto err;
}
ret = 0;
err:
if (thread)
thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN;
binder_unlock(__func__);
wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
if (ret && ret != -ERESTARTSYS)
printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret);
err_unlocked:
trace_binder_ioctl_done(ret);
return ret;
}
调用binder_thread_write函数和binder_thread_read函数分别执行写入和读取操作;
- IPCThreadState
- IPCThreadState
- IPCThreadState 详解
- IPCThreadState中的TLS
- binder 与 ProcessState & IPCThreadState
- Android - Binder机制 - ProcessState和IPCThreadState
- Android - Binder机制 - ProcessState和IPCThreadState
- Android - Binder机制 - ProcessState和IPCThreadState
- Binder中的ProcessState和IPCThreadState分析
- Android Binder ProcessState & IPCThreadState相关介绍
- Android Binder ProcessState & IPCThreadState相关介绍
- Android - Binder机制 - ProcessState和IPCThreadState
- Android开发之ProcessState和IPCThreadState类分析
- Android开发之ProcessState和IPCThreadState类分析
- Android5.0中Binder相关的ProcessState和IPCThreadState的认识.
- c语言的编程!
- 大道至简,原来你就是这么KISS---ArchLinux基本系统到XFCE4桌面搭建【转载】
- 快速学习新技术的几条建议
- seo优化必知的网站全面分析策略
- Mahout并行频繁集挖掘算法源码分析(1)--实战
- IPCThreadState
- Maven系列学习(4)-仓库简介
- 34,UC(13)
- 美化代码的15个代码语法高亮工具
- android控件可以拖动处理方法
- Android——界面特效 相关知识总结贴
- Win32多线程之进程
- 去掉字符串中的空格
- thread_cleanup