From cb388882cf20a8bc8f20f1230bc22d1caff283dd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 12 Mar 2009 10:35:23 +0100 Subject: [PATCH] tevent: add tevent_loop_until() This is only a hack for samba4 and should not be used in new code. metze --- lib/tevent/tevent.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ lib/tevent/tevent.h | 6 +++++ 2 files changed, 68 insertions(+) diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c index e9b6b7d0558..a9e18c349d7 100644 --- a/lib/tevent/tevent.c +++ b/lib/tevent/tevent.c @@ -449,6 +449,68 @@ done: return ret; } +/* + this is a performance optimization for the samba4 nested event loop problems +*/ +int _tevent_loop_until(struct tevent_context *ev, + bool (*finished)(void *private_data), + void *private_data, + const char *location) +{ + int ret; + void *nesting_stack_ptr = NULL; + + ev->nesting.level++; + + if (ev->nesting.level > 1) { + if (!ev->nesting.allowed) { + tevent_abort_nesting(ev, location); + errno = ELOOP; + return -1; + } + if (ev->nesting.hook_fn) { + int ret2; + ret2 = ev->nesting.hook_fn(ev, + ev->nesting.hook_private, + ev->nesting.level, + true, + (void *)&nesting_stack_ptr, + location); + if (ret2 != 0) { + ret = ret2; + goto done; + } + } + } + + while (!finished(private_data)) { + ret = ev->ops->loop_once(ev, location); + if (ret != 0) { + break; + } + } + + if (ev->nesting.level > 1) { + if (ev->nesting.hook_fn) { + int ret2; + ret2 = ev->nesting.hook_fn(ev, + ev->nesting.hook_private, + ev->nesting.level, + false, + (void *)&nesting_stack_ptr, + location); + if (ret2 != 0) { + ret = ret2; + goto done; + } + } + } + +done: + ev->nesting.level--; + return ret; +} + /* return on failure or (with 0) if all fd events are removed */ diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index bb36f397395..4a3f51ae5ee 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -319,6 +319,12 @@ void tevent_loop_allow_nesting(struct tevent_context *ev) _DEPRECATED_; void tevent_loop_set_nesting_hook(struct tevent_context *ev, tevent_nesting_hook hook, void *private_data) _DEPRECATED_; +int _tevent_loop_until(struct tevent_context *ev, + bool (*finished)(void *private_data), + void *private_data, + const char *location) _DEPRECATED_; +#define tevent_loop_until(ev, finished, private_data) \ + _tevent_loop_until(ev, finished, private_data, __location__) #endif #ifdef TEVENT_COMPAT_DEFINES -- 2.34.1