#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <memory.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <unistd.h>
#include <fcntl.h>
typedef void (*smartlink_msg_cb)(int fd, short msgs, void *userdata);
typedef int bool;
struct smartlink_message {
struct smartlink_message *next;
struct smartlink_message *prev;
int fd;
int index;
bool persist;
struct timeval timeout;
smartlink_msg_cb func;
void *param;
};
#define MAX_FD_MESSAGES 16
static struct smartlink_message s_wakeup_msg;
static struct smartlink_message *smartlink_watch_list[MAX_FD_MESSAGES];
static struct smartlink_message smartlink_pending_list;
int fd_num ;
fd_set rfds;
fd_set read_fds;
int s_fd_wakeup_read ;
int s_fd_wakeup_write ;
static void process_wakeup_callback(int fd ,
short flags , void *param )
{
char buff[16] = {0};
int ret;
do
{
ret = read(s_fd_wakeup_read, &buff, sizeof(buff));
printf("ret %d,buff %s\n",ret ,buff);
}
while (ret > 0 || (ret < 0 && errno == EINTR));
}
void smartlink_msg_set(struct smartlink_message *msg, int fd, bool persist,
smartlink_msg_cb func, void *param) {
memset(msg, 0, sizeof(struct smartlink_message));
msg->fd = fd;
msg->index = -1;
msg->persist = persist;
msg->func = func;
msg->param = param;
fcntl(fd, F_SETFL, O_NONBLOCK);
}
static void add_to_list(struct smartlink_message *msg, struct smartlink_message *list) {
msg->next = list;
msg->prev = list->prev;
msg->prev->next = msg;
list->prev = msg;
}
void smartlink_msg_add(struct smartlink_message *msg) {
for (int i = 0; i < MAX_FD_MESSAGES; i++) {
if (smartlink_watch_list[i] == NULL) {
smartlink_watch_list[i] = msg;
msg->index = i;
//add msg->fd to read_fds
FD_SET(msg->fd, &read_fds);
if (msg->fd >= fd_num) fd_num = msg->fd+1;
break;
}
}
}
static void smartlink_msg_add_wakeup(struct smartlink_message* msg)
{
smartlink_msg_add(msg);
int ret;
do
{
ret = write(s_fd_wakeup_write, "1111", 4);
printf("ret %d\n",ret);
} while (ret < 0 && errno == EINTR);
}
static void process_read_readies(fd_set *rfds, int n) {
for (int i = 0; (i < MAX_FD_MESSAGES) && (n > 0); i++) {
struct smartlink_message *msg = smartlink_watch_list[i];
if (msg != NULL && FD_ISSET(msg->fd, rfds)) {
add_to_list(msg, &smartlink_pending_list);
if (msg->persist == 0) {
//remove_watch(msg, i);
}
n--;
}
}
}
static void remove_from_list(struct smartlink_message *msg) {
msg->next->prev = msg->prev;
msg->prev->next = msg->next;
msg->next = NULL;
msg->prev = NULL;
}
static void fire_pending() {
struct smartlink_message *msg = smartlink_pending_list.next;
int index = 1;
while (msg != &smartlink_pending_list)
{
msg->func(msg->fd, 0, msg->param);
printf("%d\n",index++);
struct smartlink_message *next = msg->next;
remove_from_list(msg);
msg = next;
}
}
static void init_msg_list(struct smartlink_message *list) {
memset(list, 0, sizeof(struct smartlink_message));
list->next = list;
list->prev = list;
list->fd = -1;
}
int main()
{
int filedes[2] = {0};
int ret = -1;
//int s_fd_wakeup_read,s_fd_wakeup_write;
int n ;
char buf[1024] = {0};
init_msg_list(&smartlink_pending_list);
FD_ZERO(&rfds);
ret = pipe(filedes);
s_fd_wakeup_read = filedes[0];
s_fd_wakeup_write = filedes[1];
fcntl(s_fd_wakeup_read, F_SETFL, O_NONBLOCK);
smartlink_msg_set(&s_wakeup_msg, s_fd_wakeup_read, 1,
process_wakeup_callback, NULL);
smartlink_msg_add_wakeup(&s_wakeup_msg);
FD_SET(s_fd_wakeup_read,&rfds);
fd_num = s_fd_wakeup_read + 1;
#if 0
do
{
ret = write(s_fd_wakeup_write, "d", 1);
//printf("%d\n",ret);
} while (ret < 0 && errno == EINTR);
#endif
n = select(fd_num, &rfds, NULL, NULL, NULL);
printf("n %d \n",n);
process_read_readies(&rfds, n);
fire_pending();
//printf("%s - %d\n",buf,n);
}
思路
1 定义事件结构体,包含fd 回调函数
2 填充每个 事件
3 select 检测事件
4 遍历上报的事件,执行