forked from cminyard/ser2net
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathselector.h
184 lines (158 loc) · 6.83 KB
/
selector.h
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
* selector.h
*
* MontaVista IPMI interface code for timers and file waiting.
*
* Author: MontaVista Software, Inc.
* Corey Minyard <[email protected]>
*
* Copyright 2002,2003 MontaVista Software Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef SELECTOR
#define SELECTOR
#include <sys/time.h> /* For timeval */
#ifdef __cplusplus
extern "C" {
#endif
/* The main data structure used by the selector. */
struct selector_s;
typedef struct selector_s selector_t;
/* You have to create a selector before you can use it. */
/* Create a selector for use with threads. You have to pass in the
lock functions and a signal used to wake waiting threads. */
typedef struct sel_lock_s sel_lock_t;
int sel_alloc_selector_thread(selector_t **new_selector, int wake_sig,
sel_lock_t *(*sel_lock_alloc)(void *cb_data),
void (*sel_lock_free)(sel_lock_t *),
void (*sel_lock)(sel_lock_t *),
void (*sel_unlock)(sel_lock_t *),
void *cb_data);
/* Create a selector for use in a single-threaded environment. No
need for locks or wakeups. This just call the above call with
NULL for all the values. */
int sel_alloc_selector_nothread(selector_t **new_selector);
/* Used to destroy a selector. */
int sel_free_selector(selector_t *new_selector);
/* A function to call when select sees something on a file
descriptor. */
typedef void (*sel_fd_handler_t)(int fd, void *data);
/* Set the handlers for a file descriptor. The "data" parameter is
not used, it is just passed to the exception handlers. The done
handler (if non-NULL) will be called when the data is removed or
replaced. */
typedef void (*sel_fd_cleared_cb)(int fd, void *data);
int sel_set_fd_handlers(selector_t *sel,
int fd,
void *data,
sel_fd_handler_t read_handler,
sel_fd_handler_t write_handler,
sel_fd_handler_t except_handler,
sel_fd_cleared_cb done);
/* Remove the handlers for a file descriptor. This will also disable
the handling of all I/O for the fd. Note that when this returns,
some other thread may be in a handler. To avoid races with
clearing the data (SMP only), you should provide a done handler in
the set routine; it will be called when the registered handler is
sure to not be called again. */
void sel_clear_fd_handlers(selector_t *sel,
int fd);
/* Turn on and off handling for I/O from a file descriptor. */
#define SEL_FD_HANDLER_ENABLED 0
#define SEL_FD_HANDLER_DISABLED 1
void sel_set_fd_read_handler(selector_t *sel, int fd, int state);
void sel_set_fd_write_handler(selector_t *sel, int fd, int state);
void sel_set_fd_except_handler(selector_t *sel, int fd, int state);
struct sel_timer_s;
typedef struct sel_timer_s sel_timer_t;
typedef void (*sel_timeout_handler_t)(selector_t *sel,
sel_timer_t *timer,
void *data);
int sel_alloc_timer(selector_t *sel,
sel_timeout_handler_t handler,
void *user_data,
sel_timer_t **new_timer);
int sel_free_timer(sel_timer_t *timer);
int sel_start_timer(sel_timer_t *timer,
struct timeval *timeout);
int sel_stop_timer(sel_timer_t *timer);
int sel_stop_timer_with_done(sel_timer_t *timer,
sel_timeout_handler_t done_handler,
void *cb_data);
/* Use this for times provided to sel_start_time() */
void sel_get_monotonic_time(struct timeval *tv);
typedef struct sel_runner_s sel_runner_t;
typedef void (*sel_runner_func_t)(sel_runner_t *runner, void *cb_data);
int sel_alloc_runner(selector_t *sel, sel_runner_t **new_runner);
int sel_free_runner(sel_runner_t *runner);
int sel_run(sel_runner_t *runner, sel_runner_func_t func, void *cb_data);
/* For multi-threaded programs, you will need to wake the selector
thread if you add a timer to the top of the heap or change the fd
mask. This code should send a signal to the thread that calls
sel-select_loop. The user will have to allocate the signal, set
the handlers, etc. The thread_id and cb_data are just the values
passed into sel_select_loop(). */
typedef void (*sel_send_sig_cb)(long thread_id, void *cb_data);
/*
* This is the select interface for program. All handlers on timers and
* fds will get chances to be called.
* return >0 if sel_select did something (ran a timer or fd)
* 0 if timeout
* <0 if error (errno will be set)
* The timeout is a relative timeout (just like normal select() on
* *nix).
*/
int sel_select(selector_t *sel,
sel_send_sig_cb send_sig,
long thread_id,
void *cb_data,
struct timeval *timeout);
/* This is the main loop for the program. If NULL is passed in to
send_sig, then the signal sender is not used. If this encounters
an unrecoverable problem with select(), it will return the errno.
Otherwise it will loop forever. */
int sel_select_loop(selector_t *sel,
sel_send_sig_cb send_sig,
long thread_id,
void *cb_data);
typedef void (*ipmi_sel_add_read_fds_cb)(selector_t *sel,
int *num_fds,
fd_set *fdset,
struct timeval *timeout,
int *timeout_invalid,
void *cb_data);
typedef void (*ipmi_sel_check_read_fds_cb)(selector_t *sel,
fd_set *fds,
void *cb_data);
typedef void (*ipmi_sel_check_timeout_cb)(selector_t *sel,
void *cb_data);
void ipmi_sel_set_read_fds_handler(selector_t *sel,
ipmi_sel_add_read_fds_cb add,
ipmi_sel_check_read_fds_cb handle,
ipmi_sel_check_timeout_cb timeout,
void *cb_data);
#ifdef __cplusplus
}
#endif
#endif /* SELECTOR */