[Android]adb学习笔记(一)

1,adb中fdevent系统的学习
  由于一台电脑可以连多个手机或者多个android模拟器,所以adb server可能同时监听多个文件描述符是否有数据可读或者可写,
fdevent就是处理这样情况,先将需要监听的文件描述符fd注册到fdevent系统中,然后设定是要监听的类型(可读,可写)等,最后
开始监听并调用相应的回调处理函数。
首先定义一个fdevent结构体

struct fdevent{
	fdevent *next;
	fdevent *prev;
	int fd;
	int force_eof;
	unsigned short state;
	unsigned short events;
	fd_func func;
	void *arg;
};

typedef void (fd_func*)(int fd,unsigned events,void*userdata);
static fdevent **fd_table=0;
static int fd_table_max=0;
static int epoll_fd = -1;
#define FDE_ACTIVE 0x0100
#define FDE_PENDING 0x0200
#define FDE_CREDED 0x0400

#define FDE_READ              0x0001
#define FDE_WRITE             0x0002
#define FDE_ERROR             0x0004
#define FDE_TIMEOUT           0x0008

首先利用fdevent_install()函数初始化fdevent结构体,将要监听的fdevent注册进fd_table中,
void fdevent_install(fdevent *fde,int fd,fd_func func,void *arg)
{
	memset(fde,0,sizeof(fdevent));
	fde->fd=fd;
	fde->force_eof=0;
	fde->func=func;
	fde->arg=arg;
	fde->state=FDE_ACTIVE;
	fdevent_register(fde);
	fdevent_connect(fde);
	fde->state |= FDE_ACTIVE;
}
/*
根据fdevent->fd的大小动态创建fd_table
*/
static void fdevent_register(fdevent *fde)
{
	if((fde->fd)<0)
	{
		printf("Error:negative fd\n")
	}
	if(fde->fd >= fd_table_max)
	{
		int oldmax=fd_table_max;
		if(fd_table_max == 0)
		{
			fdevent_init();
			fd_table_max=256;
		}
		while(fd_table_max<fde->fd)
		{
			fd_table_max *=2;
		}
		fd_table=realloc(fd_table,sizeof(fdevent*)*fd_table_max);
		if(fd_table == 0)
		{
			printf("Error:realloc fd_table error\n");
		}
		memset(fd_table+oldmax,0,sizeof(fd_table_max-oldmax));
	}
}

/*
因为fdevent底层还是利用了epoll的系统调用,这里先创建epoll_fd文件描述符
*/
static void fdevent_init()
{
	epoll_fd=epoll_creat(256);
	if(epoll_fd < 0)
	{
		printf("epoll_creat error\n")
		exit(1);
	}
	fcntl(epoll_fd,F_SETFD,FD_CLOEXEC);  //FD_CLOEXEC表示在通过exec()时fd失效
}

static void fdevent_connect(fdevent *fde)
{
	struct epoll_event ev;
	memset(&ev,0,sizeof(ev));
	ev.events=0;
	ev.data.ptr=fde;
}

void fdevent_set(fdevent *fde, unsigned events)
{
    events &= FDE_EVENTMASK;

    if((fde->state & FDE_EVENTMASK) == events) return;

    if(fde->state & FDE_ACTIVE) {
        fdevent_update(fde, events);
        dump_fde(fde, "update");
    }

    fde->state = (fde->state & FDE_STATEMASK) | events;

    if(fde->state & FDE_PENDING) {
            /* if we're pending, make sure
            ** we don't signal an event that
            ** is no longer wanted.
            */
        fde->events &= (~events);
        if(fde->events == 0) {
            fdevent_plist_remove(fde);
            fde->state &= (~FDE_PENDING);
        }
    }
}


static void fdevent_update(fdevent *fde, unsigned events)
{
    struct epoll_event ev;
    int active;

    active = (fde->state & FDE_EVENTMASK) != 0;

    memset(&ev, 0, sizeof(ev));
    ev.events = 0;
    ev.data.ptr = fde;

    if(events & FDE_READ) ev.events |= EPOLLIN;
    if(events & FDE_WRITE) ev.events |= EPOLLOUT;
    if(events & FDE_ERROR) ev.events |= (EPOLLERR | EPOLLHUP);

    fde->state = (fde->state & FDE_STATEMASK) | events;

    if(active) {
        if(ev.events) {
            if(epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fde->fd, &ev)) {
                perror("epoll_ctl() failed\n");
                exit(1);
            }
        } else {
            if(epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev)) {
                perror("epoll_ctl() failed\n");
                exit(1);
            }
        }
    } else {
        if(ev.events) {
            if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) {
                perror("epoll_ctl() failed\n");
                exit(1);
            }
        }
    }
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值