1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-08 21:18:16 +03:00

Eventscripts: remove the horrible horrible circular reference between state and callback since these two structures do not even share the same parent talloc context.

Instead, tie them together via referencing a permanent linked list hung off the ctdb structure.

(This used to be ctdb commit a95c02da6c67dc4bd8716b75318a4188301df6f9)
This commit is contained in:
Ronnie Sahlberg 2012-02-22 17:38:12 +11:00
parent 94b7a84cb1
commit 93ec9c589c
2 changed files with 22 additions and 7 deletions

View File

@ -486,6 +486,9 @@ struct ctdb_context {
/* if we are a child process, do we have a domain socket to send controls on */
bool can_send_controls;
/* list of event script callback functions that are active */
struct event_script_callback *script_callbacks;
};
struct ctdb_db_context {

View File

@ -26,6 +26,7 @@
#include "../include/ctdb_private.h"
#include "lib/tevent/tevent.h"
#include "../common/rb_tree.h"
#include "lib/util/dlinklist.h"
static void ctdb_event_script_timeout(struct event_context *ev, struct timed_event *te, struct timeval t, void *p);
@ -41,7 +42,8 @@ static void sigterm(int sig)
/* This is attached to the event script state. */
struct event_script_callback {
struct ctdb_event_script_state *state;
struct event_script_callback *next, *prev;
struct ctdb_context *ctdb;
/* Warning: this can free us! */
void (*fn)(struct ctdb_context *, int, void *);
@ -611,8 +613,18 @@ static int event_script_destructor(struct ctdb_event_script_state *state)
}
/* This is allowed to free us; talloc will prevent double free anyway,
* but beware if you call this outside the destructor! */
callback = state->callback;
* but beware if you call this outside the destructor!
* the callback hangs off a different context so we walk the list
* of "active" callbacks until we find the one state points to.
* if we cant find it it means the callback has been removed.
*/
for (callback = state->ctdb->script_callbacks; callback != NULL; callback = callback->next) {
if (callback == state->callback) {
break;
}
}
state->callback = NULL;
if (callback) {
/* Make sure destructor doesn't free itself! */
@ -669,8 +681,7 @@ static bool check_options(enum ctdb_eventscript_call call, const char *options)
static int remove_callback(struct event_script_callback *callback)
{
/* Detach ourselves from the running script state */
callback->state->callback = NULL;
DLIST_REMOVE(callback->ctdb->script_callbacks, callback);
return 0;
}
@ -694,9 +705,10 @@ static int ctdb_event_script_callback_v(struct ctdb_context *ctdb,
/* The callback isn't done if the context is freed. */
state->callback = talloc(mem_ctx, struct event_script_callback);
CTDB_NO_MEMORY(ctdb, state->callback);
DLIST_ADD(ctdb->script_callbacks, state->callback);
talloc_set_destructor(state->callback, remove_callback);
state->callback->state = state;
state->callback->fn = callback;
state->callback->ctdb = ctdb;
state->callback->fn = callback;
state->callback->private_data = private_data;
state->ctdb = ctdb;