forked from gozfree/gear-lib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpoll.c
121 lines (107 loc) · 2.83 KB
/
poll.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*****************************************************************************
* Copyright (C) 2014-2015
* file: poll.c
* author: gozfree <[email protected]>
* created: 2015-04-27 00:59
* updated: 2015-07-12 00:41
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <errno.h>
#include <poll.h>
#include <liblog.h>
#include "libgevent.h"
#define POLL_MAX_FD (1024)
#define MAX_SECONDS_IN_MSEC_LONG (((LONG_MAX) - 999) / 1000)
struct poll_ctx {
nfds_t nfds;
int event_count;
struct pollfd *fds;
};
static void *poll_init(void)
{
struct poll_ctx *pc;
struct pollfd *fds;
pc = (struct poll_ctx *)calloc(1, sizeof(struct poll_ctx));
if (!pc) {
loge("malloc poll_ctx failed!\n");
return NULL;
}
fds = (struct pollfd *)calloc(POLL_MAX_FD, sizeof(struct pollfd));
if (!fds) {
loge("malloc pollfd failed!\n");
return NULL;
}
pc->fds = fds;
return pc;
}
static void poll_deinit(void *ctx)
{
struct poll_ctx *pc = (struct poll_ctx *)ctx;
if (!ctx) {
return;
}
free(pc->fds);
free(pc);
}
static int poll_add(struct gevent_base *eb, struct gevent *e)
{
struct poll_ctx *pc = (struct poll_ctx *)eb->ctx;
pc->fds[0].fd = e->evfd;
if (e->flags & EVENT_READ)
pc->fds[0].events |= POLLIN;
if (e->flags & EVENT_WRITE)
pc->fds[0].events |= POLLOUT;
if (e->flags & EVENT_EXCEPT)
pc->fds[0].events |= POLLERR;
return 0;
}
static int poll_del(struct gevent_base *eb, struct gevent *e)
{
// struct poll_ctx *pc = eb->base;
return 0;
}
static int poll_dispatch(struct gevent_base *eb, struct timeval *tv)
{
struct poll_ctx *pc = (struct poll_ctx *)eb->ctx;
int i, n;
int flags;
int timeout = -1;
if (tv != NULL) {
if (tv->tv_usec > 1000000 || tv->tv_sec > MAX_SECONDS_IN_MSEC_LONG)
timeout = -1;
else
timeout = (tv->tv_sec * 1000) + ((tv->tv_usec + 999) / 1000);
} else {
timeout = -1;
}
n = poll(pc->fds, pc->nfds, timeout);
if (-1 == n) {
loge("errno=%d %s\n", errno, strerror(errno));
return -1;
}
if (0 == n) {
loge("poll timeout\n");
return 0;
}
for (i = 0; i < n; i++) {
if (pc->fds[i].revents & POLLIN)
flags |= EVENT_READ;
if (pc->fds[i].revents & POLLOUT)
flags |= EVENT_WRITE;
if (pc->fds[i].revents & (POLLERR|POLLHUP|POLLNVAL))
flags |= EVENT_EXCEPT;
pc->fds[i].revents = 0;
}
return 0;
}
struct gevent_ops pollops = {
.init = poll_init,
.deinit = poll_deinit,
.add = poll_add,
.del = poll_del,
.dispatch = poll_dispatch,
};