root/src/eventer/eventer.h

Revision 09ecd288337978ca01c842684ec58b4bad68ce6e, 7.4 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 3 years ago)

This patch does a lot, all refs #351

  • fix up the test harness to support noitd restarts and
    expected crashes
  • Add different cancellation methodologies to the jobq implemntation
    • "evil_brutal" which is the old siglongjmp way.
    • "cancel_deferred" which uses pthread_cancel w/ CANCEL_DEFERRED
    • "cancel_asynch" which uses pthread_cancel w/ CANCEL_ASYNCHRONOUS
  • Add a game over scenario is the cooperative cancellation mechanisms
    don't work and end up exhausting all the threads in a pool.
  • Reduce the minimum check period set via REST to 1s to enable better
    testing. NOTE: maybe this should be much smaller even.
  • Change the thread pool system to spawn as new jobs are queued.
    This isn't automatic demand-driven sizing, but rather we don't
    start the (N) threads until (N) events arrive (not necessarily
    concurrently).
  • Added a test_abort module that runs different types of faux workloads
    to assist in testing the functional correctness of each method.
    Workloads include, variable work time, variable method of cancellation
    type and interruptable (nanosleep) and uninterruptable (compute).
  • Added fairly thorough tests for each method under each workload
    condition. Tested on darwin (finding cancel_asynch to not work well).
    Needs testing on other platforms.
  • 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_CANCEL_DEFERRED
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
106 typedef struct _eventer_impl {
107   const char         *name;
108   int               (*init)();
109   int               (*propset)(const char *key, const char *value);
110   void              (*add)(eventer_t e);
111   eventer_t         (*remove)(eventer_t e);
112   void              (*update)(eventer_t e, int newmask);
113   eventer_t         (*remove_fd)(int fd);
114   eventer_t         (*find_fd)(int fd);
115   void              (*trigger)(eventer_t e, int mask);
116   int               (*loop)();
117   void              (*foreach_fdevent)(void (*f)(eventer_t, void *), void *);
118   struct timeval    max_sleeptime;
119   int               maxfds;
120   struct {
121     eventer_t e;
122     pthread_t executor;
123     noit_spinlock_t lock;
124   }                 *master_fds;
125 } *eventer_impl_t;
126
127 /* This is the "chosen one" */
128 #ifndef _EVENTER_C
129 extern
130 #endif
131 eventer_impl_t __eventer;
132 noit_log_stream_t eventer_err;
133 noit_log_stream_t eventer_deb;
134
135 API_EXPORT(int) eventer_choose(const char *name);
136
137 #define eventer_propset       __eventer->propset
138 #define eventer_init          __eventer->init
139 #define eventer_add           __eventer->add
140 #define eventer_remove        __eventer->remove
141 #define eventer_update        __eventer->update
142 #define eventer_remove_fd     __eventer->remove_fd
143 #define eventer_find_fd       __eventer->find_fd
144 #define eventer_loop          __eventer->loop
145 #define eventer_trigger       __eventer->trigger
146 #define eventer_max_sleeptime __eventer->max_sleeptime
147 #define eventer_foreach_fdevent  __eventer->foreach_fdevent
148
149 extern eventer_impl_t registered_eventers[];
150
151 #include "eventer/eventer_jobq.h"
152
153 API_EXPORT(eventer_jobq_t *) eventer_default_backq();
154 API_EXPORT(int) eventer_impl_propset(const char *key, const char *value);
155 API_EXPORT(int) eventer_impl_init();
156 API_EXPORT(void) eventer_add_asynch(eventer_jobq_t *q, eventer_t e);
157 API_EXPORT(void) eventer_add_timed(eventer_t e);
158 API_EXPORT(eventer_t) eventer_remove_timed(eventer_t e);
159 API_EXPORT(void) eventer_update_timed(eventer_t e, int mask);
160 API_EXPORT(void) eventer_dispatch_timed(struct timeval *now,
161                                         struct timeval *next);
162 API_EXPORT(void)
163   eventer_foreach_timedevent (void (*f)(eventer_t e, void *), void *closure);
164 API_EXPORT(void) eventer_dispatch_recurrent(struct timeval *now);
165 API_EXPORT(eventer_t) eventer_remove_recurrent(eventer_t e);
166 API_EXPORT(void) eventer_add_recurrent(eventer_t e);
167 API_EXPORT(int) eventer_get_epoch(struct timeval *epoch);
168
169 /* Helpers to schedule timed events */
170 #define eventer_add_at(func, cl, t) do { \
171   eventer_t e = eventer_alloc(); \
172   e->whence = t; \
173   e->mask = EVENTER_TIMER; \
174   e->callback = func; \
175   e->closure = cl; \
176   eventer_add(e); \
177 } while(0)
178 #define eventer_add_in(func, cl, t) do { \
179   struct timeval __now; \
180   eventer_t e = eventer_alloc(); \
181   gettimeofday(&__now, NULL); \
182   add_timeval(__now, t, &e->whence); \
183   e->mask = EVENTER_TIMER; \
184   e->callback = func; \
185   e->closure = cl; \
186   eventer_add(e); \
187 } while(0)
188 #define eventer_add_in_s_us(func, cl, s, us) do { \
189   struct timeval __now, diff = { s, us }; \
190   eventer_t e = eventer_alloc(); \
191   gettimeofday(&__now, NULL); \
192   add_timeval(__now, diff, &e->whence); \
193   e->mask = EVENTER_TIMER; \
194   e->callback = func; \
195   e->closure = cl; \
196   eventer_add(e); \
197 } while(0)
198
199 /* Helpers to set sockets non-blocking / blocking */
200 API_EXPORT(int) eventer_set_fd_nonblocking(int fd);
201 API_EXPORT(int) eventer_set_fd_blocking(int fd);
202
203 #endif
Note: See TracBrowser for help on using the browser.