select event处理方式

#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 遍历上报的事件,执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用 select 系统调用接收 vblank 信号的简单示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/select.h> #include <sys/ioctl.h> #include <drm/drm.h> #include <drm/drm_mode.h> int main() { int fd, ret; fd_set fds; struct timeval tv; drmEventContext evctx = { .version = DRM_EVENT_CONTEXT_VERSION, .vblank_handler = NULL, .page_flip_handler = NULL, }; drmVBlank vbl; // 打开 DRM 设备文件 fd = open("/dev/dri/card0", O_RDWR); if (fd < 0) { perror("open"); exit(EXIT_FAILURE); } // 注册 vblank 事件 vbl.request.type = DRM_VBLANK_RELATIVE; vbl.request.sequence = 1; ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, &vbl); if (ret < 0) { perror("ioctl"); exit(EXIT_FAILURE); } // 将 vblank 事件转换为文件描述符 ret = drmHandleEvent(fd, &evctx); if (ret < 0) { perror("drmHandleEvent"); exit(EXIT_FAILURE); } // 将 vblank 事件的文件描述符添加到 select 监视的文件描述符集合中 FD_ZERO(&fds); FD_SET(fd, &fds); // 等待 vblank 事件的发生 tv.tv_sec = 5; tv.tv_usec = 0; ret = select(fd + 1, &fds, NULL, NULL, &tv); if (ret < 0) { perror("select"); exit(EXIT_FAILURE); } else if (ret == 0) { printf("timeout\n"); } else if (ret > 0) { if (FD_ISSET(fd, &fds)) { printf("vblank event received\n"); } } // 关闭 DRM 设备文件 close(fd); return 0; } ``` 需要注意的是,这只是一个简单的示例代码,实际应用程序可能需要更复杂的逻辑来处理 vblank 事件。此外,由于不同的操作系统和显卡驱动可能会有不同的实现方式,因此在实际应用程序中,你可能需要根据具体情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值