dsdb:repl_meta_data: allow CONTROL_DBCHECK_FIX_LINK_DN_NAME to by pass rename
[Samba.git] / lib / tevent / tevent_immediate.c
blobef7d8a566c0a6e8e1ccb6a0b08bd4af44cde5c5f
1 /*
2 Unix SMB/CIFS implementation.
4 common events code for immediate events
6 Copyright (C) Stefan Metzmacher 2009
8 ** NOTE! The following LGPL license applies to the tevent
9 ** library. This does NOT imply that all of Samba is released
10 ** under the LGPL
12 This library is free software; you can redistribute it and/or
13 modify it under the terms of the GNU Lesser General Public
14 License as published by the Free Software Foundation; either
15 version 3 of the License, or (at your option) any later version.
17 This library is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 Lesser General Public License for more details.
22 You should have received a copy of the GNU Lesser General Public
23 License along with this library; if not, see <http://www.gnu.org/licenses/>.
26 #include "replace.h"
27 #include "tevent.h"
28 #include "tevent_internal.h"
29 #include "tevent_util.h"
31 static void tevent_common_immediate_cancel(struct tevent_immediate *im)
33 const char *create_location = im->create_location;
34 bool busy = im->busy;
36 if (im->destroyed) {
37 tevent_abort(im->event_ctx, "tevent_immediate use after free");
38 return;
41 if (!im->event_ctx) {
42 return;
45 if (im->handler_name != NULL) {
46 tevent_debug(im->event_ctx, TEVENT_DEBUG_TRACE,
47 "Cancel immediate event %p \"%s\"\n",
48 im, im->handler_name);
51 /* let the backend free im->additional_data */
52 if (im->cancel_fn) {
53 im->cancel_fn(im);
56 DLIST_REMOVE(im->event_ctx->immediate_events, im);
58 *im = (struct tevent_immediate) {
59 .create_location = create_location,
60 .busy = busy,
63 if (!busy) {
64 talloc_set_destructor(im, NULL);
69 destroy an immediate event
71 static int tevent_common_immediate_destructor(struct tevent_immediate *im)
73 if (im->destroyed) {
74 tevent_common_check_double_free(im,
75 "tevent_immediate double free");
76 goto done;
79 tevent_common_immediate_cancel(im);
81 im->destroyed = true;
83 done:
84 if (im->busy) {
85 return -1;
88 return 0;
92 * schedule an immediate event on
94 void tevent_common_schedule_immediate(struct tevent_immediate *im,
95 struct tevent_context *ev,
96 tevent_immediate_handler_t handler,
97 void *private_data,
98 const char *handler_name,
99 const char *location)
101 const char *create_location = im->create_location;
102 bool busy = im->busy;
103 struct tevent_wrapper_glue *glue = im->wrapper;
105 tevent_common_immediate_cancel(im);
107 if (!handler) {
108 return;
111 *im = (struct tevent_immediate) {
112 .event_ctx = ev,
113 .wrapper = glue,
114 .handler = handler,
115 .private_data = private_data,
116 .handler_name = handler_name,
117 .create_location = create_location,
118 .schedule_location = location,
119 .busy = busy,
122 DLIST_ADD_END(ev->immediate_events, im);
123 talloc_set_destructor(im, tevent_common_immediate_destructor);
125 tevent_debug(ev, TEVENT_DEBUG_TRACE,
126 "Schedule immediate event \"%s\": %p\n",
127 handler_name, im);
130 int tevent_common_invoke_immediate_handler(struct tevent_immediate *im,
131 bool *removed)
133 struct tevent_context *handler_ev = im->event_ctx;
134 struct tevent_context *ev = im->event_ctx;
135 struct tevent_immediate cur = *im;
137 if (removed != NULL) {
138 *removed = false;
141 tevent_debug(ev, TEVENT_DEBUG_TRACE,
142 "Run immediate event \"%s\": %p\n",
143 im->handler_name, im);
146 * remember the handler and then clear the event
147 * the handler might reschedule the event
150 im->busy = true;
151 im->handler_name = NULL;
152 tevent_common_immediate_cancel(im);
153 if (cur.wrapper != NULL) {
154 handler_ev = cur.wrapper->wrap_ev;
156 tevent_wrapper_push_use_internal(handler_ev, cur.wrapper);
157 cur.wrapper->ops->before_immediate_handler(
158 cur.wrapper->wrap_ev,
159 cur.wrapper->private_state,
160 cur.wrapper->main_ev,
162 cur.handler_name,
163 cur.schedule_location);
165 cur.handler(handler_ev, im, cur.private_data);
166 if (cur.wrapper != NULL) {
167 cur.wrapper->ops->after_immediate_handler(
168 cur.wrapper->wrap_ev,
169 cur.wrapper->private_state,
170 cur.wrapper->main_ev,
172 cur.handler_name,
173 cur.schedule_location);
174 tevent_wrapper_pop_use_internal(handler_ev, cur.wrapper);
176 im->busy = false;
178 if (im->destroyed) {
179 talloc_set_destructor(im, NULL);
180 TALLOC_FREE(im);
181 if (removed != NULL) {
182 *removed = true;
186 return 0;
190 trigger the first immediate event and return true
191 if no event was triggered return false
193 bool tevent_common_loop_immediate(struct tevent_context *ev)
195 struct tevent_immediate *im = ev->immediate_events;
196 int ret;
198 if (!im) {
199 return false;
202 ret = tevent_common_invoke_immediate_handler(im, NULL);
203 if (ret != 0) {
204 tevent_abort(ev, "tevent_common_invoke_immediate_handler() failed");
207 return true;