forked from gozfree/gear-lib
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathselect.c
More file actions
126 lines (113 loc) · 2.9 KB
/
Copy pathselect.c
File metadata and controls
126 lines (113 loc) · 2.9 KB
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
122
123
124
125
126
/*****************************************************************************
* Copyright (C) 2014-2015
* file: select.c
* author: gozfree <gozfree@163.com>
* created: 2015-04-27 00:59
* updated: 2015-07-12 00:41
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/select.h>
#include <libmacro.h>
#include <liblog.h>
#include "libgevent.h"
#define SELECT_MAX_FD 1024
struct select_ctx {
int nfds; /* Highest fd in fd set */
fd_set *rfds;
fd_set *wfds;
fd_set *efds;
};
static void *select_init(void)
{
struct select_ctx *sc = CALLOC(1, struct select_ctx);
if (!sc) {
loge("malloc select_ctx failed!\n");
return NULL;
}
fd_set *rfds = CALLOC(1, fd_set);
fd_set *wfds = CALLOC(1, fd_set);
fd_set *efds = CALLOC(1, fd_set);
if (!rfds || !wfds || !efds) {
loge("malloc fd_set failed!\n");
return NULL;
}
sc->rfds = rfds;
sc->wfds = wfds;
sc->efds = efds;
return sc;
}
static void select_deinit(void *ctx)
{
struct select_ctx *sc = (struct select_ctx *)ctx;
if (!ctx) {
return;
}
free(sc->rfds);
free(sc->wfds);
free(sc->efds);
free(sc);
}
static int select_add(struct gevent_base *eb, struct gevent *e)
{
struct select_ctx *sc = (struct select_ctx *)eb->ctx;
FD_ZERO(sc->rfds);
FD_ZERO(sc->wfds);
FD_ZERO(sc->efds);
if (sc->nfds < e->evfd) {
sc->nfds = e->evfd;
}
if (e->flags & EVENT_READ)
FD_SET(e->evfd, sc->rfds);
if (e->flags & EVENT_WRITE)
FD_SET(e->evfd, sc->wfds);
if (e->flags & EVENT_EXCEPT)
FD_SET(e->evfd, sc->efds);
return 0;
}
static int select_del(struct gevent_base *eb, struct gevent *e)
{
struct select_ctx *sc = (struct select_ctx *)eb->ctx;
if (sc->rfds)
FD_CLR(e->evfd, sc->rfds);
if (sc->wfds)
FD_CLR(e->evfd, sc->wfds);
if (sc->efds)
FD_CLR(e->evfd, sc->efds);
return 0;
}
static int select_dispatch(struct gevent_base *eb, struct timeval *tv)
{
int i, n;
int flags;
struct select_ctx *sc = (struct select_ctx *)eb->ctx;
int nfds = sc->nfds + 1;
n = select(nfds, sc->rfds, sc->wfds, sc->efds, tv);
if (-1 == n) {
loge("errno=%d %s\n", errno, strerror(errno));
return -1;
}
if (0 == n) {
loge("select timeout\n");
return 0;
}
for (i = 0; i < nfds; i++) {
if (FD_ISSET(i, sc->rfds))
flags |= EVENT_READ;
if (FD_ISSET(i, sc->wfds))
flags |= EVENT_WRITE;
if (FD_ISSET(i, sc->efds))
flags |= EVENT_EXCEPT;
}
return 0;
}
struct gevent_ops selectops = {
.init = select_init,
.deinit = select_deinit,
.add = select_add,
.del = select_del,
.dispatch = select_dispatch,
};