tevent: don't allow nested tevent_loop_once() anymore
authorStefan Metzmacher <metze@samba.org>
Thu, 12 Mar 2009 08:51:33 +0000 (09:51 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 12 Mar 2009 11:14:18 +0000 (12:14 +0100)
Incompatible caller should use tevent_loop_allow_nesting()
function.

metze

tevent/tevent.c
tevent/tevent.h
tevent/tevent_internal.h

index d7db303d879038f3e15994a116759a17b9cabc89..a6bac6097d72f148f1442e552be890e87a61afd8 100644 (file)
@@ -59,6 +59,7 @@
 */
 #include "replace.h"
 #include "system/filesys.h"
+#define TEVENT_DEPRECATED 1
 #include "tevent.h"
 #include "tevent_internal.h"
 #include "tevent_util.h"
@@ -368,12 +369,46 @@ struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
                                   handler_name, location);
 }
 
+void tevent_loop_allow_nesting(struct tevent_context *ev)
+{
+       ev->nesting.allowed = true;
+}
+
+static void tevent_abort_nesting(struct tevent_context *ev, const char *location)
+{
+       const char *reason;
+
+       reason = talloc_asprintf(NULL, "tevent_loop_once() nesting at %s",
+                                location);
+       if (!reason) {
+               reason = "tevent_loop_once() nesting";
+       }
+
+       tevent_abort(ev, reason);
+}
+
 /*
   do a single event loop using the events defined in ev 
 */
 int _tevent_loop_once(struct tevent_context *ev, const char *location)
 {
-       return ev->ops->loop_once(ev, location);
+       int ret;
+
+       ev->nesting.level++;
+
+       if (ev->nesting.level > 1) {
+               if (!ev->nesting.allowed) {
+                       tevent_abort_nesting(ev, location);
+                       errno = ELOOP;
+                       return -1;
+               }
+       }
+
+       ret = ev->ops->loop_once(ev, location);
+
+       ev->nesting.level--;
+
+       return ret;
 }
 
 /*
index 1870f695b5702a71325fbfbc83f25858ac1a9e7d..67946279476d75babc241364716a1d675bcd7209 100644 (file)
@@ -301,6 +301,17 @@ void tevent_queue_stop(struct tevent_queue *queue);
 
 size_t tevent_queue_length(struct tevent_queue *queue);
 
+#ifdef TEVENT_DEPRECATED
+#ifndef _DEPRECATED_
+#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 )
+#define _DEPRECATED_ __attribute__ ((deprecated))
+#else
+#define _DEPRECATED_
+#endif
+#endif
+void tevent_loop_allow_nesting(struct tevent_context *ev) _DEPRECATED_;
+#endif
+
 #ifdef TEVENT_COMPAT_DEFINES
 
 #define event_context  tevent_context
index 151a34fc425f2cf890ab2035ab75160ba489608f..475d00661a0c82f4d04df0579a98333e5827b514 100644 (file)
@@ -233,6 +233,12 @@ struct tevent_context {
 
        /* debugging operations */
        struct tevent_debug_ops debug_ops;
+
+       /* info about the nesting status */
+       struct {
+               bool allowed;
+               uint32_t level;
+       } nesting;
 };