diff options
-rw-r--r-- | lib/tevent/tevent.c | 62 | ||||
-rw-r--r-- | lib/tevent/tevent.h | 6 |
2 files changed, 68 insertions, 0 deletions
diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c index e9b6b7d055..a9e18c349d 100644 --- a/lib/tevent/tevent.c +++ b/lib/tevent/tevent.c @@ -450,6 +450,68 @@ done: } /* + 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 */ int _tevent_loop_wait(struct tevent_context *ev, const char *location) diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index bb36f39739..4a3f51ae5e 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 |