tevent: add tevent_loop_until()
authorStefan Metzmacher <metze@samba.org>
Thu, 12 Mar 2009 09:35:23 +0000 (10:35 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 12 Mar 2009 13:21:26 +0000 (14:21 +0100)
This is only a hack for samba4 and should not be used
in new code.

metze

tevent/tevent.c
tevent/tevent.h

index e9b6b7d055899d8f767dfcb18f803a463a74fbdd..a9e18c349d7a55052e93d2d58138cec8cc396d8e 100644 (file)
@@ -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
 */
index bb36f39739587e03d58a5ec00c75fbe741eb5d62..4a3f51ae5eedb4fe90e253845c240118bf63910a 100644 (file)
@@ -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