root/src/eventer/eventer.h

Revision dd70a5f3aa29668a783b4e0da5cee3a1d3aab102, 7.6 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 1 month ago)

some starter support for SOCK_CLOEXEC and O_CLOEXEC

  • 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 } *eventer_fd_opset_t;
77
78 typedef struct _event *eventer_t;
79
80 #include "eventer/eventer_POSIX_fd_opset.h"
81 #include "eventer/eventer_SSL_fd_opset.h"
82
83 typedef int (*eventer_func_t)
84             (eventer_t e, int mask, void *closure, struct timeval *tv);
85
86 struct _event {
87   eventer_func_t      callback;
88   struct timeval      whence;
89   int                 fd;
90   int                 mask;
91   eventer_fd_opset_t  opset;
92   void               *opset_ctx;
93   void *closure;
94 };
95
96 API_EXPORT(eventer_t) eventer_alloc();
97 API_EXPORT(void)      eventer_free(eventer_t);
98 API_EXPORT(int)       eventer_timecompare(const void *a, const void *b);
99 API_EXPORT(int)       eventer_name_callback(const char *name, eventer_func_t f);
100 API_EXPORT(const char *)
101                       eventer_name_for_callback(eventer_func_t f);
102 API_EXPORT(eventer_func_t)
103                       eventer_callback_for_name(const char *name);
104
105 /* These values are set on initialization and are safe to use
106  * on any platform.  They will be set to zero on platforms that
107  * do not support them.  As such, you can always bit-or them.
108  */
109 API_EXPORT(int) NE_SOCK_CLOEXEC;
110 API_EXPORT(int) NE_O_CLOEXEC;
111
112 typedef struct _eventer_impl {
113   const char         *name;
114   int               (*init)();
115   int               (*propset)(const char *key, const char *value);
116   void              (*add)(eventer_t e);
117   eventer_t         (*remove)(eventer_t e);
118   void              (*update)(eventer_t e, int newmask);
119   eventer_t         (*remove_fd)(int fd);
120   eventer_t         (*find_fd)(int fd);
121   void              (*trigger)(eventer_t e, int mask);
122   int               (*loop)();
123   void              (*foreach_fdevent)(void (*f)(eventer_t, void *), void *);
124   struct timeval    max_sleeptime;
125   int               maxfds;
126   struct {
127     eventer_t e;
128     pthread_t executor;
129     noit_spinlock_t lock;
130   }                 *master_fds;
131 } *eventer_impl_t;
132
133 /* This is the "chosen one" */
134 #ifndef _EVENTER_C
135 extern
136 #endif
137 eventer_impl_t __eventer;
138 noit_log_stream_t eventer_err;
139 noit_log_stream_t eventer_deb;
140
141 API_EXPORT(int) eventer_choose(const char *name);
142
143 #define eventer_propset       __eventer->propset
144 #define eventer_init          __eventer->init
145 #define eventer_add           __eventer->add
146 #define eventer_remove        __eventer->remove
147 #define eventer_update        __eventer->update
148 #define eventer_remove_fd     __eventer->remove_fd
149 #define eventer_find_fd       __eventer->find_fd
150 #define eventer_loop          __eventer->loop
151 #define eventer_trigger       __eventer->trigger
152 #define eventer_max_sleeptime __eventer->max_sleeptime
153 #define eventer_foreach_fdevent  __eventer->foreach_fdevent
154
155 extern eventer_impl_t registered_eventers[];
156
157 #include "eventer/eventer_jobq.h"
158
159 API_EXPORT(eventer_jobq_t *) eventer_default_backq();
160 API_EXPORT(int) eventer_impl_propset(const char *key, const char *value);
161 API_EXPORT(int) eventer_impl_init();
162 API_EXPORT(void) eventer_add_asynch(eventer_jobq_t *q, eventer_t e);
163 API_EXPORT(void) eventer_add_timed(eventer_t e);
164 API_EXPORT(eventer_t) eventer_remove_timed(eventer_t e);
165 API_EXPORT(void) eventer_update_timed(eventer_t e, int mask);
166 API_EXPORT(void) eventer_dispatch_timed(struct timeval *now,
167                                         struct timeval *next);
168 API_EXPORT(void)
169   eventer_foreach_timedevent (void (*f)(eventer_t e, void *), void *closure);
170 API_EXPORT(void) eventer_dispatch_recurrent(struct timeval *now);
171 API_EXPORT(eventer_t) eventer_remove_recurrent(eventer_t e);
172 API_EXPORT(void) eventer_add_recurrent(eventer_t e);
173 API_EXPORT(int) eventer_get_epoch(struct timeval *epoch);
174
175 /* Helpers to schedule timed events */
176 #define eventer_add_at(func, cl, t) do { \
177   eventer_t e = eventer_alloc(); \
178   e->whence = t; \
179   e->mask = EVENTER_TIMER; \
180   e->callback = func; \
181   e->closure = cl; \
182   eventer_add(e); \
183 } while(0)
184 #define eventer_add_in(func, cl, t) do { \
185   struct timeval __now; \
186   eventer_t e = eventer_alloc(); \
187   gettimeofday(&__now, NULL); \
188   add_timeval(__now, t, &e->whence); \
189   e->mask = EVENTER_TIMER; \
190   e->callback = func; \
191   e->closure = cl; \
192   eventer_add(e); \
193 } while(0)
194 #define eventer_add_in_s_us(func, cl, s, us) do { \
195   struct timeval __now, diff = { s, us }; \
196   eventer_t e = eventer_alloc(); \
197   gettimeofday(&__now, NULL); \
198   add_timeval(__now, diff, &e->whence); \
199   e->mask = EVENTER_TIMER; \
200   e->callback = func; \
201   e->closure = cl; \
202   eventer_add(e); \
203 } while(0)
204
205 /* Helpers to set sockets non-blocking / blocking */
206 API_EXPORT(int) eventer_set_fd_nonblocking(int fd);
207 API_EXPORT(int) eventer_set_fd_blocking(int fd);
208
209 #endif
Note: See TracBrowser for help on using the browser.