android uevent_open_socket,解决android系统唤醒时间偏长------healthd里的epoll以及socket

在healthd中,有一个很好的例子,特地截取下来作为参考:

首先是

static int uevent_fd;

static int eventct;

static int epollfd;

int uevent_open_socket(int buf_sz, bool passcred)

{

struct sockaddr_nl addr;

int on = passcred;

int s;

memset(&addr, 0, sizeof(addr));

addr.nl_family = AF_NETLINK;

addr.nl_pid = getpid();

addr.nl_groups = 0xffffffff;

s = socket(PF_NETLINK#协议族, SOCK_DGRAM | SOCK_CLOEXEC#指定的socket类型-无保障的面向消息的socket, NETLINK_KOBJECT_UEVENT#特殊的uevent类型的socket);

if(s < 0)

return -1;

setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, &buf_sz, sizeof(buf_sz));

setsockopt(s, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));

#

int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);

sockfd:标识一个套接口的描述字。

level:选项定义的层次;支持SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP和IPPROTO_IPV6。

optname:需设置的选项。

optval:

指针,指向存放选项待设置的新值的

缓冲区。

optlen:optval缓冲区长度

#

if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {

#

参数sockfd

指定地址与哪个套接字绑定,这是一个由之前的socket函数调用返回的套接字。调用bind的函数之后,该套接字与一个相应的地址关联,发送到这个地址的数据可以通过这个套接字来读取与使用。

参数addr

指定地址。这是一个地址结构,并且是一个已经经过填写的有效的地址结构。调用bind之后这个地址与参数sockfd指定的套接字关联,从而实现上面所说的效果。

参数addrlen

正如大多数socket接口一样,内核不关心地址结构,当它复制或传递地址给驱动的时候,它依据这个值来确定需要复制多少数据。这已经成为socket接口中最常见的参数之一了。

#

close(s);

return -1;

}

return s;

}

static void uevent_init(void) {

uevent_fd = uevent_open_socket(64*1024, true);

if (uevent_fd < 0) {

KLOG_ERROR(LOG_TAG, "uevent_init: uevent_open_socket failed\n");

return;

}

fcntl(uevent_fd, F_SETFL, O_NONBLOCK);

#fcntl()针对(文件)描述符提供控制.参数fd 是被参数cmd操作(如下面的描述)的描述符

if (healthd_register_event(uevent_fd, uevent_event))  //收到event之后的处理函数

KLOG_ERROR(LOG_TAG,

"register for uevent events failed\n");

// close(uevent_fd);

}

int healthd_register_event(int fd, void (*handler)(uint32_t)) {

struct epoll_event ev;

ev.events = EPOLLIN | EPOLLWAKEUP;

ev.data.ptr = (void *)handler;

if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) {

#该函数用于控制某个epoll文件描述符上的事件,可以注册事件,修改事件,删除事件

KLOG_ERROR(LOG_TAG,

"epoll_ctl failed; errno=%d\n", errno);

return -1;

}

eventct++;

return 0;

}

static void healthd_mainloop(void) {

while (1) {

struct epoll_event events[eventct];

int nevents;

int timeout = awake_poll_interval;

nevents = epoll_wait(epollfd, events, eventct, timeout);

}

这样就把uevent和socket以及处理的handler联系到了一起

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值