Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 514 lines (437 sloc) 15.088 kB
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
1 /*
e49e289 Update copyright notices to 2012
Nick Mathewson authored
2 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
eda27f9 Update copyright notices, add some missing license statements
Nick Mathewson authored
3 * Copyright (c) 2002-2006 Niels Provos <provos@citi.umich.edu>
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
ded0a09 @kev009 Add evconfig-private to remaining files
kev009 authored
29 #include "evconfig-private.h"
30
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
31 #include <sys/types.h>
32
ec347b9 Move event-config.h to include/event2
Nick Mathewson authored
33 #include "event2/event-config.h"
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
34
68120d9 Convert event-config.h macros to avoid reserved identifiers
Nick Mathewson authored
35 #ifdef EVENT__HAVE_SYS_TIME_H
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
36 #include <sys/time.h>
37 #endif
38
39 #include <errno.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
68120d9 Convert event-config.h macros to avoid reserved identifiers
Nick Mathewson authored
43 #ifdef EVENT__HAVE_STDARG_H
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
44 #include <stdarg.h>
45 #endif
46
9f560bf Use "_WIN32", not WIN32: it's standard and we don't need to fake it
Nick Mathewson authored
47 #ifdef _WIN32
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
48 #include <winsock2.h>
49 #endif
50
51 #include "event2/util.h"
52 #include "event2/bufferevent.h"
53 #include "event2/buffer.h"
54 #include "event2/bufferevent_struct.h"
55 #include "event2/event.h"
56 #include "log-internal.h"
57 #include "mm-internal.h"
58 #include "bufferevent-internal.h"
59 #include "util-internal.h"
60
61 /* prototypes */
62 static int be_filter_enable(struct bufferevent *, short);
63 static int be_filter_disable(struct bufferevent *, short);
64 static void be_filter_destruct(struct bufferevent *);
65
66 static void be_filter_readcb(struct bufferevent *, void *);
67 static void be_filter_writecb(struct bufferevent *, void *);
5232cfa Consistently say "eventcb" instead of "errorcb"
Nick Mathewson authored
68 static void be_filter_eventcb(struct bufferevent *, short, void *);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
69 static int be_filter_flush(struct bufferevent *bufev,
70 short iotype, enum bufferevent_flush_mode mode);
31d89f2 Add a "ctrl" mechanism to bufferevents for property access.
Nick Mathewson authored
71 static int be_filter_ctrl(struct bufferevent *, enum bufferevent_ctrl_op, union bufferevent_ctrl_data *);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
72
73 static void bufferevent_filtered_outbuf_cb(struct evbuffer *buf,
f1b1bad Make the new evbuffer callbacks use a new struct-based interface.
Nick Mathewson authored
74 const struct evbuffer_cb_info *info, void *arg);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
75
76 struct bufferevent_filtered {
1becc4c Refactor new elements of bufferevent into bufferevent_private structure
Nick Mathewson authored
77 struct bufferevent_private bev;
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
78
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
79 /** The bufferevent that we read/write filtered data from/to. */
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
80 struct bufferevent *underlying;
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
81 /** A callback on our outbuf to notice when somebody adds data */
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
82 struct evbuffer_cb_entry *outbuf_cb;
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
83 /** True iff we have received an EOF callback from the underlying
84 * bufferevent. */
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
85 unsigned got_eof;
86
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
87 /** Function to free context when we're done. */
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
88 void (*free_context)(void *);
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
89 /** Input filter */
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
90 bufferevent_filter_cb process_in;
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
91 /** Output filter */
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
92 bufferevent_filter_cb process_out;
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
93 /** User-supplied argument to the filters. */
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
94 void *context;
95 };
96
23085c9 Add a linked-pair abstraction to bufferevents.
Nick Mathewson authored
97 const struct bufferevent_ops bufferevent_ops_filter = {
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
98 "filter",
657d1b6 Set mem_offset for every bufferevent type
Nick Mathewson authored
99 evutil_offsetof(struct bufferevent_filtered, bev.bev),
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
100 be_filter_enable,
101 be_filter_disable,
102 be_filter_destruct,
cb9da0b Fix all identifiers with names beginning with underscore.
Nick Mathewson authored
103 bufferevent_generic_adj_timeouts_,
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
104 be_filter_flush,
31d89f2 Add a "ctrl" mechanism to bufferevents for property access.
Nick Mathewson authored
105 be_filter_ctrl,
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
106 };
107
108 /* Given a bufferevent that's really the bev filter of a bufferevent_filtered,
109 * return that bufferevent_filtered. Returns NULL otherwise.*/
110 static inline struct bufferevent_filtered *
111 upcast(struct bufferevent *bev)
112 {
113 struct bufferevent_filtered *bev_f;
114 if (bev->be_ops != &bufferevent_ops_filter)
115 return NULL;
116 bev_f = (void*)( ((char*)bev) -
1becc4c Refactor new elements of bufferevent into bufferevent_private structure
Nick Mathewson authored
117 evutil_offsetof(struct bufferevent_filtered, bev.bev));
2e36dbe Use EVUTIL_ASSERT() consistently instead of assert.
Nick Mathewson authored
118 EVUTIL_ASSERT(bev_f->bev.bev.be_ops == &bufferevent_ops_filter);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
119 return bev_f;
120 }
121
1becc4c Refactor new elements of bufferevent into bufferevent_private structure
Nick Mathewson authored
122 #define downcast(bev_f) (&(bev_f)->bev.bev)
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
123
124 /** Return 1 iff bevf's underlying bufferevent's output buffer is at or
125 * over its high watermark such that we should not write to it in a given
126 * flush mode. */
127 static int
128 be_underlying_writebuf_full(struct bufferevent_filtered *bevf,
129 enum bufferevent_flush_mode state)
130 {
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
131 struct bufferevent *u = bevf->underlying;
132 return state == BEV_NORMAL &&
133 u->wm_write.high &&
134 evbuffer_get_length(u->output) >= u->wm_write.high;
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
135 }
136
137 /** Return 1 if our input buffer is at or over its high watermark such that we
138 * should not write to it in a given flush mode. */
139 static int
140 be_readbuf_full(struct bufferevent_filtered *bevf,
141 enum bufferevent_flush_mode state)
142 {
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
143 struct bufferevent *bufev = downcast(bevf);
144 return state == BEV_NORMAL &&
145 bufev->wm_read.high &&
146 evbuffer_get_length(bufev->input) >= bufev->wm_read.high;
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
147 }
148
149
150 /* Filter to use when we're created with a NULL filter. */
151 static enum bufferevent_filter_result
0b22ca1 Use ev_ssize_t in place of ssize_t *everywhere*.
Nick Mathewson authored
152 be_null_filter(struct evbuffer *src, struct evbuffer *dst, ev_ssize_t lim,
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
153 enum bufferevent_flush_mode state, void *ctx)
154 {
155 (void)state;
ac36f40 oops; coding too quickly on nil-filter patch. Caught by niels.
Nick Mathewson authored
156 if (evbuffer_remove_buffer(src, dst, lim) == 0)
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
157 return BEV_OK;
158 else
159 return BEV_ERROR;
160 }
161
162 struct bufferevent *
163 bufferevent_filter_new(struct bufferevent *underlying,
164 bufferevent_filter_cb input_filter,
165 bufferevent_filter_cb output_filter,
b73ad7b Treat the bitwise OR of two enum values as an int.
Nick Mathewson authored
166 int options,
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
167 void (*free_context)(void *),
168 void *ctx)
169 {
170 struct bufferevent_filtered *bufev_f;
b73ad7b Treat the bitwise OR of two enum values as an int.
Nick Mathewson authored
171 int tmp_options = options & ~BEV_OPT_THREADSAFE;
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
172
ac27eb8 Correct logic on disabling underlying bufferevents when disabling a f…
Nick Mathewson authored
173 if (!underlying)
174 return NULL;
175
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
176 if (!input_filter)
177 input_filter = be_null_filter;
178 if (!output_filter)
179 output_filter = be_null_filter;
180
181 bufev_f = mm_calloc(1, sizeof(struct bufferevent_filtered));
182 if (!bufev_f)
183 return NULL;
184
8ac3c4c Have all visible internal function names end with an underscore.
Nick Mathewson authored
185 if (bufferevent_init_common_(&bufev_f->bev, underlying->ev_base,
915193e Locking support for bufferevents.
Nick Mathewson authored
186 &bufferevent_ops_filter, tmp_options) < 0) {
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
187 mm_free(bufev_f);
188 return NULL;
189 }
915193e Locking support for bufferevents.
Nick Mathewson authored
190 if (options & BEV_OPT_THREADSAFE) {
8ac3c4c Have all visible internal function names end with an underscore.
Nick Mathewson authored
191 bufferevent_enable_locking_(downcast(bufev_f), NULL);
915193e Locking support for bufferevents.
Nick Mathewson authored
192 }
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
193
194 bufev_f->underlying = underlying;
f1bc125 Improve robustness for refcounting
Nick Mathewson authored
195
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
196 bufev_f->process_in = input_filter;
197 bufev_f->process_out = output_filter;
198 bufev_f->free_context = free_context;
199 bufev_f->context = ctx;
200
201 bufferevent_setcb(bufev_f->underlying,
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
202 be_filter_readcb, be_filter_writecb, be_filter_eventcb, bufev_f);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
203
1becc4c Refactor new elements of bufferevent into bufferevent_private structure
Nick Mathewson authored
204 bufev_f->outbuf_cb = evbuffer_add_cb(downcast(bufev_f)->output,
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
205 bufferevent_filtered_outbuf_cb, bufev_f);
206
cb9da0b Fix all identifiers with names beginning with underscore.
Nick Mathewson authored
207 bufferevent_init_generic_timeout_cbs_(downcast(bufev_f));
8ac3c4c Have all visible internal function names end with an underscore.
Nick Mathewson authored
208 bufferevent_incref_(underlying);
34574db Add a generic mechanism to implement timeouts in bufferevents.
Nick Mathewson authored
209
ac27eb8 Correct logic on disabling underlying bufferevents when disabling a f…
Nick Mathewson authored
210 bufferevent_enable(underlying, EV_READ|EV_WRITE);
8ac3c4c Have all visible internal function names end with an underscore.
Nick Mathewson authored
211 bufferevent_suspend_read_(underlying, BEV_SUSPEND_FILT_READ);
ac27eb8 Correct logic on disabling underlying bufferevents when disabling a f…
Nick Mathewson authored
212
1becc4c Refactor new elements of bufferevent into bufferevent_private structure
Nick Mathewson authored
213 return downcast(bufev_f);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
214 }
215
216 static void
217 be_filter_destruct(struct bufferevent *bev)
218 {
219 struct bufferevent_filtered *bevf = upcast(bev);
2e36dbe Use EVUTIL_ASSERT() consistently instead of assert.
Nick Mathewson authored
220 EVUTIL_ASSERT(bevf);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
221 if (bevf->free_context)
222 bevf->free_context(bevf->context);
223
f1bc125 Improve robustness for refcounting
Nick Mathewson authored
224 if (bevf->bev.options & BEV_OPT_CLOSE_ON_FREE) {
8ac3c4c Have all visible internal function names end with an underscore.
Nick Mathewson authored
225 /* Yes, there is also a decref in bufferevent_decref_.
f1bc125 Improve robustness for refcounting
Nick Mathewson authored
226 * That decref corresponds to the incref when we set
227 * underlying for the first time. This decref is an
228 * extra one to remove the last reference.
229 */
230 if (BEV_UPCAST(bevf->underlying)->refcnt < 2) {
231 event_warnx("BEV_OPT_CLOSE_ON_FREE set on an "
232 "bufferevent with too few references");
233 } else {
234 bufferevent_free(bevf->underlying);
235 }
ac27eb8 Correct logic on disabling underlying bufferevents when disabling a f…
Nick Mathewson authored
236 } else {
237 if (bevf->underlying) {
1ac5b23 Only clear underlying callbacks when the user hasn't reset them.
Nick Mathewson authored
238 if (bevf->underlying->errorcb == be_filter_eventcb)
239 bufferevent_setcb(bevf->underlying,
240 NULL, NULL, NULL, NULL);
8ac3c4c Have all visible internal function names end with an underscore.
Nick Mathewson authored
241 bufferevent_unsuspend_read_(bevf->underlying,
ac27eb8 Correct logic on disabling underlying bufferevents when disabling a f…
Nick Mathewson authored
242 BEV_SUSPEND_FILT_READ);
243 }
f1bc125 Improve robustness for refcounting
Nick Mathewson authored
244 }
34574db Add a generic mechanism to implement timeouts in bufferevents.
Nick Mathewson authored
245
cb9da0b Fix all identifiers with names beginning with underscore.
Nick Mathewson authored
246 bufferevent_del_generic_timeout_cbs_(bev);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
247 }
248
249 static int
250 be_filter_enable(struct bufferevent *bev, short event)
251 {
252 struct bufferevent_filtered *bevf = upcast(bev);
d328829 Provide consistent, tested semantics for bufferevent timeouts
Nick Mathewson authored
253 if (event & EV_WRITE)
254 BEV_RESET_GENERIC_WRITE_TIMEOUT(bev);
ac27eb8 Correct logic on disabling underlying bufferevents when disabling a f…
Nick Mathewson authored
255
256 if (event & EV_READ) {
257 BEV_RESET_GENERIC_READ_TIMEOUT(bev);
8ac3c4c Have all visible internal function names end with an underscore.
Nick Mathewson authored
258 bufferevent_unsuspend_read_(bevf->underlying,
ac27eb8 Correct logic on disabling underlying bufferevents when disabling a f…
Nick Mathewson authored
259 BEV_SUSPEND_FILT_READ);
260 }
261 return 0;
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
262 }
263
264 static int
265 be_filter_disable(struct bufferevent *bev, short event)
266 {
267 struct bufferevent_filtered *bevf = upcast(bev);
d328829 Provide consistent, tested semantics for bufferevent timeouts
Nick Mathewson authored
268 if (event & EV_WRITE)
269 BEV_DEL_GENERIC_WRITE_TIMEOUT(bev);
ac27eb8 Correct logic on disabling underlying bufferevents when disabling a f…
Nick Mathewson authored
270 if (event & EV_READ) {
271 BEV_DEL_GENERIC_READ_TIMEOUT(bev);
8ac3c4c Have all visible internal function names end with an underscore.
Nick Mathewson authored
272 bufferevent_suspend_read_(bevf->underlying,
ac27eb8 Correct logic on disabling underlying bufferevents when disabling a f…
Nick Mathewson authored
273 BEV_SUSPEND_FILT_READ);
274 }
275 return 0;
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
276 }
277
278 static enum bufferevent_filter_result
279 be_filter_process_input(struct bufferevent_filtered *bevf,
280 enum bufferevent_flush_mode state,
281 int *processed_out)
282 {
283 enum bufferevent_filter_result res;
1becc4c Refactor new elements of bufferevent into bufferevent_private structure
Nick Mathewson authored
284 struct bufferevent *bev = downcast(bevf);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
285
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
286 if (state == BEV_NORMAL) {
287 /* If we're in 'normal' mode, don't urge data on the filter
288 * unless we're reading data and under our high-water mark.*/
289 if (!(bev->enabled & EV_READ) ||
290 be_readbuf_full(bevf, state))
291 return BEV_OK;
292 }
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
293
294 do {
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
295 ev_ssize_t limit = -1;
296 if (state == BEV_NORMAL && bev->wm_read.high)
297 limit = bev->wm_read.high -
298 evbuffer_get_length(bev->input);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
299
300 res = bevf->process_in(bevf->underlying->input,
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
301 bev->input, limit, state, bevf->context);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
302
303 if (res == BEV_OK)
304 *processed_out = 1;
305 } while (res == BEV_OK &&
1becc4c Refactor new elements of bufferevent into bufferevent_private structure
Nick Mathewson authored
306 (bev->enabled & EV_READ) &&
a8f6d96 Actually stop using EVBUFFER_LENGTH/DATA, and move them to buffer_com…
Nick Mathewson authored
307 evbuffer_get_length(bevf->underlying->input) &&
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
308 !be_readbuf_full(bevf, state));
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
309
34574db Add a generic mechanism to implement timeouts in bufferevents.
Nick Mathewson authored
310 if (*processed_out)
311 BEV_RESET_GENERIC_READ_TIMEOUT(bev);
312
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
313 return res;
314 }
315
316
317 static enum bufferevent_filter_result
318 be_filter_process_output(struct bufferevent_filtered *bevf,
319 enum bufferevent_flush_mode state,
320 int *processed_out)
321 {
a62283a Always hold a reference to a bufferevent when calling its callbacks.
Nick Mathewson authored
322 /* Requires references and lock: might call writecb */
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
323 enum bufferevent_filter_result res = BEV_OK;
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
324 struct bufferevent *bufev = downcast(bevf);
325 int again = 0;
326
327 if (state == BEV_NORMAL) {
328 /* If we're in 'normal' mode, don't urge data on the
329 * filter unless we're writing data, and the underlying
330 * bufferevent is accepting data, and we have data to
331 * give the filter. If we're in 'flush' or 'finish',
332 * call the filter no matter what. */
333 if (!(bufev->enabled & EV_WRITE) ||
334 be_underlying_writebuf_full(bevf, state) ||
335 !evbuffer_get_length(bufev->output))
336 return BEV_OK;
337 }
338
339 /* disable the callback that calls this function
340 when the user adds to the output buffer. */
341 evbuffer_cb_set_flags(bufev->output, bevf->outbuf_cb, 0);
342
343 do {
344 int processed = 0;
345 again = 0;
346
347 do {
348 ev_ssize_t limit = -1;
349 if (state == BEV_NORMAL &&
350 bevf->underlying->wm_write.high)
351 limit = bevf->underlying->wm_write.high -
352 evbuffer_get_length(bevf->underlying->output);
353
354 res = bevf->process_out(downcast(bevf)->output,
355 bevf->underlying->output,
356 limit,
357 state,
358 bevf->context);
359
360 if (res == BEV_OK)
361 processed = *processed_out = 1;
362 } while (/* Stop if the filter wasn't successful...*/
363 res == BEV_OK &&
364 /* Or if we aren't writing any more. */
365 (bufev->enabled & EV_WRITE) &&
366 /* Of if we have nothing more to write and we are
367 * not flushing. */
368 evbuffer_get_length(bufev->output) &&
369 /* Or if we have filled the underlying output buffer. */
370 !be_underlying_writebuf_full(bevf,state));
371
372 if (processed &&
373 evbuffer_get_length(bufev->output) <= bufev->wm_write.low) {
374 /* call the write callback.*/
cb9da0b Fix all identifiers with names beginning with underscore.
Nick Mathewson authored
375 bufferevent_run_writecb_(bufev);
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
376
377 if (res == BEV_OK &&
378 (bufev->enabled & EV_WRITE) &&
379 evbuffer_get_length(bufev->output) &&
380 !be_underlying_writebuf_full(bevf, state)) {
381 again = 1;
382 }
383 }
384 } while (again);
385
386 /* reenable the outbuf_cb */
387 evbuffer_cb_set_flags(bufev->output,bevf->outbuf_cb,
388 EVBUFFER_CB_ENABLED);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
389
34574db Add a generic mechanism to implement timeouts in bufferevents.
Nick Mathewson authored
390 if (*processed_out)
391 BEV_RESET_GENERIC_WRITE_TIMEOUT(bufev);
392
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
393 return res;
394 }
395
396 /* Called when the size of our outbuf changes. */
397 static void
398 bufferevent_filtered_outbuf_cb(struct evbuffer *buf,
f1b1bad Make the new evbuffer callbacks use a new struct-based interface.
Nick Mathewson authored
399 const struct evbuffer_cb_info *cbinfo, void *arg)
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
400 {
401 struct bufferevent_filtered *bevf = arg;
a62283a Always hold a reference to a bufferevent when calling its callbacks.
Nick Mathewson authored
402 struct bufferevent *bev = downcast(bevf);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
403
f1b1bad Make the new evbuffer callbacks use a new struct-based interface.
Nick Mathewson authored
404 if (cbinfo->n_added) {
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
405 int processed_any = 0;
406 /* Somebody added more data to the output buffer. Try to
407 * process it, if we should. */
cb9da0b Fix all identifiers with names beginning with underscore.
Nick Mathewson authored
408 bufferevent_incref_and_lock_(bev);
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
409 be_filter_process_output(bevf, BEV_NORMAL, &processed_any);
cb9da0b Fix all identifiers with names beginning with underscore.
Nick Mathewson authored
410 bufferevent_decref_and_unlock_(bev);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
411 }
412 }
413
414 /* Called when the underlying socket has read. */
415 static void
416 be_filter_readcb(struct bufferevent *underlying, void *_me)
417 {
418 struct bufferevent_filtered *bevf = _me;
419 enum bufferevent_filter_result res;
420 enum bufferevent_flush_mode state;
421 struct bufferevent *bufev = downcast(bevf);
422 int processed_any = 0;
423
cb9da0b Fix all identifiers with names beginning with underscore.
Nick Mathewson authored
424 bufferevent_incref_and_lock_(bufev);
a62283a Always hold a reference to a bufferevent when calling its callbacks.
Nick Mathewson authored
425
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
426 if (bevf->got_eof)
427 state = BEV_FINISHED;
428 else
429 state = BEV_NORMAL;
430
7bcace2 Fix some irix compilation warnings spotted by Kevin Bowling
Nick Mathewson authored
431 /* XXXX use return value */
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
432 res = be_filter_process_input(bevf, state, &processed_any);
65707d7 add some (void) casts for unused variables
Sebastian Hahn authored
433 (void)res;
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
434
a62283a Always hold a reference to a bufferevent when calling its callbacks.
Nick Mathewson authored
435 /* XXX This should be in process_input, not here. There are
436 * other places that can call process-input, and they should
437 * force readcb calls as needed. */
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
438 if (processed_any &&
2e8eeea Fix crash bugs when a bufferevent's eventcb is not set.
Nick Mathewson authored
439 evbuffer_get_length(bufev->input) >= bufev->wm_read.low)
cb9da0b Fix all identifiers with names beginning with underscore.
Nick Mathewson authored
440 bufferevent_run_readcb_(bufev);
a62283a Always hold a reference to a bufferevent when calling its callbacks.
Nick Mathewson authored
441
cb9da0b Fix all identifiers with names beginning with underscore.
Nick Mathewson authored
442 bufferevent_decref_and_unlock_(bufev);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
443 }
444
445 /* Called when the underlying socket has drained enough that we can write to
446 it. */
447 static void
448 be_filter_writecb(struct bufferevent *underlying, void *_me)
449 {
450 struct bufferevent_filtered *bevf = _me;
a62283a Always hold a reference to a bufferevent when calling its callbacks.
Nick Mathewson authored
451 struct bufferevent *bev = downcast(bevf);
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
452 int processed_any = 0;
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
453
cb9da0b Fix all identifiers with names beginning with underscore.
Nick Mathewson authored
454 bufferevent_incref_and_lock_(bev);
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
455 be_filter_process_output(bevf, BEV_NORMAL, &processed_any);
cb9da0b Fix all identifiers with names beginning with underscore.
Nick Mathewson authored
456 bufferevent_decref_and_unlock_(bev);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
457 }
458
459 /* Called when the underlying socket has given us an error */
460 static void
5232cfa Consistently say "eventcb" instead of "errorcb"
Nick Mathewson authored
461 be_filter_eventcb(struct bufferevent *underlying, short what, void *_me)
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
462 {
463 struct bufferevent_filtered *bevf = _me;
1becc4c Refactor new elements of bufferevent into bufferevent_private structure
Nick Mathewson authored
464 struct bufferevent *bev = downcast(bevf);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
465
cb9da0b Fix all identifiers with names beginning with underscore.
Nick Mathewson authored
466 bufferevent_incref_and_lock_(bev);
5232cfa Consistently say "eventcb" instead of "errorcb"
Nick Mathewson authored
467 /* All we can really to is tell our own eventcb. */
cb9da0b Fix all identifiers with names beginning with underscore.
Nick Mathewson authored
468 bufferevent_run_eventcb_(bev, what);
469 bufferevent_decref_and_unlock_(bev);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
470 }
471
472 static int
473 be_filter_flush(struct bufferevent *bufev,
474 short iotype, enum bufferevent_flush_mode mode)
475 {
476 struct bufferevent_filtered *bevf = upcast(bufev);
477 int processed_any = 0;
2e36dbe Use EVUTIL_ASSERT() consistently instead of assert.
Nick Mathewson authored
478 EVUTIL_ASSERT(bevf);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
479
cb9da0b Fix all identifiers with names beginning with underscore.
Nick Mathewson authored
480 bufferevent_incref_and_lock_(bufev);
a62283a Always hold a reference to a bufferevent when calling its callbacks.
Nick Mathewson authored
481
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
482 if (iotype & EV_READ) {
483 be_filter_process_input(bevf, mode, &processed_any);
484 }
485 if (iotype & EV_WRITE) {
486 be_filter_process_output(bevf, mode, &processed_any);
487 }
e5bbd40 Clean up formatting: use tabs, not 8-spaces, to indent.
Nick Mathewson authored
488 /* XXX check the return value? */
489 /* XXX does this want to recursively call lower-level flushes? */
490 bufferevent_flush(bevf->underlying, iotype, mode);
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
491
cb9da0b Fix all identifiers with names beginning with underscore.
Nick Mathewson authored
492 bufferevent_decref_and_unlock_(bufev);
a62283a Always hold a reference to a bufferevent when calling its callbacks.
Nick Mathewson authored
493
ea4b872 checkpoint work on big bufferevent refactoring
Nick Mathewson authored
494 return processed_any;
495 }
31d89f2 Add a "ctrl" mechanism to bufferevents for property access.
Nick Mathewson authored
496
497 static int
498 be_filter_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op,
499 union bufferevent_ctrl_data *data)
500 {
501 struct bufferevent_filtered *bevf;
4faeaea Clean up formatting: function/keyword spacing consistency.
Nick Mathewson authored
502 switch (op) {
31d89f2 Add a "ctrl" mechanism to bufferevents for property access.
Nick Mathewson authored
503 case BEV_CTRL_GET_UNDERLYING:
504 bevf = upcast(bev);
505 data->ptr = bevf->underlying;
506 return 0;
507 case BEV_CTRL_GET_FD:
508 case BEV_CTRL_SET_FD:
e6af35d Correctly terminate IO on an async bufferevent on bufferevent_free
Nick Mathewson authored
509 case BEV_CTRL_CANCEL_ALL:
31d89f2 Add a "ctrl" mechanism to bufferevents for property access.
Nick Mathewson authored
510 default:
511 return -1;
512 }
513 }
Something went wrong with that request. Please try again.