Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 514 lines (437 sloc) 15.08 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
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) {
709c21c Bufferevent support for openssl.
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));
a773df5 @fancycode Fix a segfault when freeing SSL bufferevents in an unusual order
fancycode 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);
211 bufferevent_suspend_read(underlying, BEV_SUSPEND_FILT_READ);
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) {
225 /* Yes, there is also a decref in bufferevent_decref.
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);
ac27eb8 Correct logic on disabling underlying bufferevents when disabling a f…
Nick Mathewson authored
241 bufferevent_unsuspend_read(bevf->underlying,
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);
258 bufferevent_unsuspend_read(bevf->underlying,
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);
272 bufferevent_suspend_read(bevf->underlying,
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.