summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2009-03-12 10:23:30 +0100
committerStefan Metzmacher <metze@samba.org>2009-03-12 14:21:26 +0100
commit7142ef49bdc5fe731c9140641e8e938ee999327d (patch)
treeae46a42c2bbafd310f7dd0d2c74455175b1d69c8
parenta3d5d8378c8edb6baa9ab42b02cee4711a58840b (diff)
downloadsamba-7142ef49bdc5fe731c9140641e8e938ee999327d.tar.gz
samba-7142ef49bdc5fe731c9140641e8e938ee999327d.tar.bz2
samba-7142ef49bdc5fe731c9140641e8e938ee999327d.zip
tevent: add tevent_loop_set_nesting_hook()
This is an ugly hack to let the s4 server work arround some bugs related to nested events and uid changing. metze
-rw-r--r--lib/tevent/tevent.c40
-rw-r--r--lib/tevent/tevent.h9
-rw-r--r--lib/tevent/tevent_internal.h2
3 files changed, 50 insertions, 1 deletions
diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c
index a6bac6097d..e9b6b7d055 100644
--- a/lib/tevent/tevent.c
+++ b/lib/tevent/tevent.c
@@ -374,6 +374,14 @@ void tevent_loop_allow_nesting(struct tevent_context *ev)
ev->nesting.allowed = true;
}
+void tevent_loop_set_nesting_hook(struct tevent_context *ev,
+ tevent_nesting_hook hook,
+ void *private_data)
+{
+ ev->nesting.hook_fn = hook;
+ ev->nesting.hook_private = private_data;
+}
+
static void tevent_abort_nesting(struct tevent_context *ev, const char *location)
{
const char *reason;
@@ -393,6 +401,7 @@ static void tevent_abort_nesting(struct tevent_context *ev, const char *location
int _tevent_loop_once(struct tevent_context *ev, const char *location)
{
int ret;
+ void *nesting_stack_ptr = NULL;
ev->nesting.level++;
@@ -402,12 +411,41 @@ int _tevent_loop_once(struct tevent_context *ev, const char *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;
+ }
+ }
}
ret = ev->ops->loop_once(ev, location);
- ev->nesting.level--;
+ 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;
}
diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h
index 6794627947..bb36f39739 100644
--- a/lib/tevent/tevent.h
+++ b/lib/tevent/tevent.h
@@ -301,6 +301,12 @@ void tevent_queue_stop(struct tevent_queue *queue);
size_t tevent_queue_length(struct tevent_queue *queue);
+typedef int (*tevent_nesting_hook)(struct tevent_context *ev,
+ void *private_data,
+ uint32_t level,
+ bool begin,
+ void *stack_ptr,
+ const char *location);
#ifdef TEVENT_DEPRECATED
#ifndef _DEPRECATED_
#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 )
@@ -310,6 +316,9 @@ size_t tevent_queue_length(struct tevent_queue *queue);
#endif
#endif
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_;
#endif
#ifdef TEVENT_COMPAT_DEFINES
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index 475d00661a..f10485398f 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -238,6 +238,8 @@ struct tevent_context {
struct {
bool allowed;
uint32_t level;
+ tevent_nesting_hook hook_fn;
+ void *hook_private;
} nesting;
};