root/src/eventer/eventer.h

Revision aa91f4eac14396cf1481ec845de3940816d846af, 8.3 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 6 months ago)

allow eventer callback names to be more expressive

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  *       notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  *       copyright notice, this list of conditions and the following
13  *       disclaimer in the documentation and/or other materials provided
14  *       with the distribution.
15  *     * Neither the name OmniTI Computer Consulting, Inc. nor the names
16  *       of its contributors may be used to endorse or promote products
17  *       derived from this software without specific prior written
18  *       permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #ifndef _EVENTER_EVENTER_H
34 #define _EVENTER_EVENTER_H
35
36 #include "noit_defines.h"
37 #include "utils/noit_log.h"
38 #include "utils/noit_atomic.h"
39 #include <sys/time.h>
40 #include <sys/socket.h>
41
42 #define EVENTER_READ             0x01
43 #define EVENTER_WRITE            0x02
44 #define EVENTER_EXCEPTION        0x04
45 #define EVENTER_TIMER            0x08
46 #define EVENTER_ASYNCH_WORK      0x10
47 #define EVENTER_ASYNCH_CLEANUP   0x20
48 #define EVENTER_ASYNCH           (EVENTER_ASYNCH_WORK | EVENTER_ASYNCH_CLEANUP)
49 #define EVENTER_RECURRENT        0x80
50 #define EVENTER_EVIL_BRUTAL     0x100
51 #define EVENTER_CANCEL_DEFERRED 0x200
52 #define EVENTER_CANCEL_ASYNCH   0x400
53 #define EVENTER_CANCEL          (EVENTER_CANCEL_DEFERRED|EVENTER_CANCEL_ASYNCH)
54
55 #define EVENTER_DEFAULT_ASYNCH_ABORT EVENTER_EVIL_BRUTAL
56
57 /* All of these functions act like their POSIX couterparts with two
58  * additional arguments.  The first is the mask they require to be active
59  * to make progress in the event of an EAGAIN.  The second is a closure
60  * which is the event itself.
61  */
62 typedef int (*eventer_fd_accept_t)
63             (int, struct sockaddr *, socklen_t *, int *mask, void *closure);
64 typedef int (*eventer_fd_read_t)
65             (int, void *, size_t, int *mask, void *closure);
66 typedef int (*eventer_fd_write_t)
67             (int, const void *, size_t, int *mask, void *closure);
68 typedef int (*eventer_fd_close_t)
69             (int, int *mask, void *closure);
70
71 typedef struct _fd_opset {
72   eventer_fd_accept_t accept;
73   eventer_fd_read_t   read;
74   eventer_fd_write_t  write;
75   eventer_fd_close_t  close;
76   const char *name;
77 } *eventer_fd_opset_t;
78
79 typedef struct _event *eventer_t;
80
81 #include "eventer/eventer_POSIX_fd_opset.h"
82 #include "eventer/eventer_SSL_fd_opset.h"
83
84 typedef int (*eventer_func_t)
85             (eventer_t e, int mask, void *closure, struct timeval *tv);
86
87 struct _event {
88   eventer_func_t      callback;
89   struct timeval      whence;
90   int                 fd;
91   int                 mask;
92   eventer_fd_opset_t  opset;
93   void               *opset_ctx;
94   void *closure;
95 };
96
97 API_EXPORT(eventer_t) eventer_alloc();
98 API_EXPORT(void)      eventer_free(eventer_t);
99 API_EXPORT(int)       eventer_timecompare(const void *a, const void *b);
100 API_EXPORT(int)       eventer_name_callback(const char *name, eventer_func_t f);
101 API_EXPORT(int)       eventer_name_callback_ext(const char *name,
102                                                 eventer_func_t f,
103                                                 void (*fn)(char *,int,eventer_t,void *),
104                                                 void *);
105 API_EXPORT(const char *)
106                       eventer_name_for_callback(eventer_func_t f);
107 API_EXPORT(const char *)
108                       eventer_name_for_callback_e(eventer_func_t, eventer_t);
109 API_EXPORT(eventer_func_t)
110                       eventer_callback_for_name(const char *name);
111
112 /* These values are set on initialization and are safe to use
113  * on any platform.  They will be set to zero on platforms that
114  * do not support them.  As such, you can always bit-or them.
115  */
116 API_EXPORT(int) NE_SOCK_CLOEXEC;
117 API_EXPORT(int) NE_O_CLOEXEC;
118
119 typedef struct _eventer_impl {
120   const char         *name;
121   int               (*init)();
122   int               (*propset)(const char *key, const char *value);
123   void              (*add)(eventer_t e);
124   eventer_t         (*remove)(eventer_t e);
125   void              (*update)(eventer_t e, int newmask);
126   eventer_t         (*remove_fd)(int fd);
127   eventer_t         (*find_fd)(int fd);
128   void              (*trigger)(eventer_t e, int mask);
129   int               (*loop)();
130   void              (*foreach_fdevent)(void (*f)(eventer_t, void *), void *);
131   void              (*wakeup)();
132   struct timeval    max_sleeptime;
133   int               maxfds;
134   struct {
135     eventer_t e;
136     pthread_t executor;
137     noit_spinlock_t lock;
138   }                 *master_fds;
139 } *eventer_impl_t;
140
141 /* This is the "chosen one" */
142 #ifndef _EVENTER_C
143 extern
144 #endif
145 eventer_impl_t __eventer;
146 noit_log_stream_t eventer_err;
147 noit_log_stream_t eventer_deb;
148
149 API_EXPORT(int) eventer_choose(const char *name);
150
151 #define eventer_propset       __eventer->propset
152 #define eventer_init          __eventer->init
153 #define eventer_add           __eventer->add
154 #define eventer_remove        __eventer->remove
155 #define eventer_update        __eventer->update
156 #define eventer_remove_fd     __eventer->remove_fd
157 #define eventer_find_fd       __eventer->find_fd
158 #define eventer_loop          __eventer->loop
159 #define eventer_trigger       __eventer->trigger
160 #define eventer_max_sleeptime __eventer->max_sleeptime
161 #define eventer_foreach_fdevent  __eventer->foreach_fdevent
162 #define eventer_wakeup        __eventer->wakeup
163
164 extern eventer_impl_t registered_eventers[];
165
166 #if defined(__MACH__)
167 typedef u_int64_t eventer_hrtime_t;
168 #elif defined(linux) || defined(__linux) || defined(__linux__)
169 typedef long long unsigned int eventer_hrtime_t;
170 #else
171 typedef hrtime_t eventer_hrtime_t;
172 #endif
173 API_EXPORT(eventer_hrtime_t) eventer_gethrtime(void);
174
175 #include "eventer/eventer_jobq.h"
176
177 API_EXPORT(eventer_jobq_t *) eventer_default_backq();
178 API_EXPORT(int) eventer_impl_propset(const char *key, const char *value);
179 API_EXPORT(int) eventer_impl_init();
180 API_EXPORT(void) eventer_add_asynch(eventer_jobq_t *q, eventer_t e);
181 API_EXPORT(void) eventer_add_timed(eventer_t e);
182 API_EXPORT(eventer_t) eventer_remove_timed(eventer_t e);
183 API_EXPORT(void) eventer_update_timed(eventer_t e, int mask);
184 API_EXPORT(void) eventer_dispatch_timed(struct timeval *now,
185                                         struct timeval *next);
186 API_EXPORT(void)
187   eventer_foreach_timedevent (void (*f)(eventer_t e, void *), void *closure);
188 API_EXPORT(void) eventer_dispatch_recurrent(struct timeval *now);
189 API_EXPORT(eventer_t) eventer_remove_recurrent(eventer_t e);
190 API_EXPORT(void) eventer_add_recurrent(eventer_t e);
191 API_EXPORT(int) eventer_get_epoch(struct timeval *epoch);
192
193 /* Helpers to schedule timed events */
194 #define eventer_add_at(func, cl, t) do { \
195   eventer_t e = eventer_alloc(); \
196   e->whence = t; \
197   e->mask = EVENTER_TIMER; \
198   e->callback = func; \
199   e->closure = cl; \
200   eventer_add(e); \
201 } while(0)
202 #define eventer_add_in(func, cl, t) do { \
203   struct timeval __now; \
204   eventer_t e = eventer_alloc(); \
205   gettimeofday(&__now, NULL); \
206   add_timeval(__now, t, &e->whence); \
207   e->mask = EVENTER_TIMER; \
208   e->callback = func; \
209   e->closure = cl; \
210   eventer_add(e); \
211 } while(0)
212 #define eventer_add_in_s_us(func, cl, s, us) do { \
213   struct timeval __now, diff = { s, us }; \
214   eventer_t e = eventer_alloc(); \
215   gettimeofday(&__now, NULL); \
216   add_timeval(__now, diff, &e->whence); \
217   e->mask = EVENTER_TIMER; \
218   e->callback = func; \
219   e->closure = cl; \
220   eventer_add(e); \
221 } while(0)
222
223 /* Helpers to set sockets non-blocking / blocking */
224 API_EXPORT(int) eventer_set_fd_nonblocking(int fd);
225 API_EXPORT(int) eventer_set_fd_blocking(int fd);
226
227 #endif
Note: See TracBrowser for help on using the browser.