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

change the api for managing callbacks to controls so that isntead of

passing it as a parameter we set the callback function explicitely from 
the caller if the ..._send() function returned a valid state pointer.

(This used to be ctdb commit aa939570662786455f63299b62c99882cff29d42)
This commit is contained in:
Ronnie Sahlberg 2007-08-24 10:42:06 +10:00
parent 1da9c03b1f
commit 495a6403da
4 changed files with 51 additions and 73 deletions

View File

@ -665,22 +665,6 @@ int ctdb_fetch(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
}
struct ctdb_client_control_state {
struct ctdb_context *ctdb;
uint32_t reqid;
int32_t status;
TDB_DATA outdata;
enum control_state state;
char *errormsg;
struct ctdb_req_control *c;
/* if we have a callback registered for the completion (or failure) of
this control
if a callback is used, it MUST talloc_free the cb_data passed to it
*/
control_callback callback;
void *cb_private;
};
/*
called when a control completes or timesout to invoke the callback
@ -690,10 +674,7 @@ static void invoke_control_callback(struct event_context *ev, struct timed_event
struct timeval t, void *private_data)
{
struct ctdb_client_control_state *state;
struct ctdb_control_cb_data *cb_data;
struct ctdb_context *ctdb;
control_callback callback;
void *cb_private;
TALLOC_CTX *tmp_ctx = talloc_new(NULL);
int ret;
@ -701,29 +682,12 @@ static void invoke_control_callback(struct event_context *ev, struct timed_event
talloc_steal(tmp_ctx, state);
ctdb = state->ctdb;
callback = state->callback;
cb_private = state->cb_private;
cb_data = talloc_zero(tmp_ctx, struct ctdb_control_cb_data);
if (cb_data == NULL) {
talloc_free(tmp_ctx);
CTDB_NO_MEMORY_VOID(ctdb, cb_data);
}
ret = ctdb_control_recv(ctdb, state, state,
&state->outdata,
&state->status,
&state->errormsg);
cb_data->state = state->state;
cb_data->vnn = state->c->hdr.destnode;
ret = ctdb_control_recv(ctdb, state, cb_data,
&cb_data->outdata,
&cb_data->status,
&cb_data->errormsg);
/* we dont check ret since we expect that ctdb_control_recv can fail
for example if the control timedout
state is always talloc_free()'d inside ctdb_control_recv
*/
callback(cb_data, cb_private);
talloc_free(tmp_ctx);
}
@ -770,7 +734,7 @@ static void ctdb_client_reply_control(struct ctdb_context *ctdb,
/* if we had a callback registered for this control, pull the response
and call the callback.
*/
if (state->callback) {
if (state->async.fn) {
event_add_timed(ctdb->ev, state, timeval_zero(), invoke_control_callback, state);
}
}
@ -799,7 +763,7 @@ static void control_timeout_func(struct event_context *ev, struct timed_event *t
/* if we had a callback registered for this control, pull the response
and call the callback.
*/
if (state->callback) {
if (state->async.fn) {
event_add_timed(state->ctdb->ev, state, timeval_zero(), invoke_control_callback, state);
}
}
@ -810,8 +774,7 @@ struct ctdb_client_control_state *ctdb_control_send(struct ctdb_context *ctdb,
uint32_t opcode, uint32_t flags, TDB_DATA data,
TALLOC_CTX *mem_ctx, TDB_DATA *outdata,
struct timeval *timeout,
char **errormsg,
control_callback callback, void *cb_private)
char **errormsg)
{
struct ctdb_client_control_state *state;
size_t len;
@ -834,8 +797,6 @@ struct ctdb_client_control_state *ctdb_control_send(struct ctdb_context *ctdb,
state->reqid = ctdb_reqid_new(ctdb, state);
state->state = CTDB_CONTROL_WAIT;
state->errormsg = NULL;
state->callback = callback;
state->cb_private = cb_private;
talloc_set_destructor(state, ctdb_control_destructor);
@ -892,8 +853,12 @@ int ctdb_control_recv(struct ctdb_context *ctdb,
while (state->state == CTDB_CONTROL_WAIT) {
event_loop_once(ctdb->ev);
}
if (state->state != CTDB_CONTROL_DONE) {
DEBUG(0,(__location__ " ctdb_control_recv failed\n"));
if (state->async.fn) {
state->async.fn(state);
}
talloc_free(state);
return -1;
}
@ -903,11 +868,13 @@ int ctdb_control_recv(struct ctdb_context *ctdb,
if (errormsg) {
(*errormsg) = talloc_move(mem_ctx, &state->errormsg);
}
if (state->async.fn) {
state->async.fn(state);
}
talloc_free(state);
return -1;
}
if (outdata) {
*outdata = state->outdata;
outdata->dptr = talloc_memdup(mem_ctx, outdata->dptr, outdata->dsize);
@ -918,6 +885,10 @@ int ctdb_control_recv(struct ctdb_context *ctdb,
}
if (state->async.fn) {
state->async.fn(state);
}
talloc_free(state);
return 0;
}
@ -939,8 +910,7 @@ int ctdb_control(struct ctdb_context *ctdb, uint32_t destnode, uint64_t srvid,
state = ctdb_control_send(ctdb, destnode, srvid, opcode,
flags, data, mem_ctx, outdata,
timeout, errormsg,
NULL, NULL);
timeout, errormsg);
return ctdb_control_recv(ctdb, state, mem_ctx, outdata, status,
errormsg);
}
@ -1066,8 +1036,7 @@ ctdb_ctrl_getrecmode_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct
{
return ctdb_control_send(ctdb, destnode, 0,
CTDB_CONTROL_GET_RECMODE, 0, tdb_null,
mem_ctx, NULL, &timeout, NULL,
NULL, NULL);
mem_ctx, NULL, &timeout, NULL);
}
int ctdb_ctrl_getrecmode_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmode)
@ -1129,13 +1098,11 @@ int ctdb_ctrl_setrecmode(struct ctdb_context *ctdb, struct timeval timeout, uint
*/
struct ctdb_client_control_state *
ctdb_ctrl_getrecmaster_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx,
struct timeval timeout, uint32_t destnode,
control_callback callback, void *cb_private)
struct timeval timeout, uint32_t destnode)
{
return ctdb_control_send(ctdb, destnode, 0,
CTDB_CONTROL_GET_RECMASTER, 0, tdb_null,
mem_ctx, NULL, &timeout, NULL,
callback, cb_private);
mem_ctx, NULL, &timeout, NULL);
}
int ctdb_ctrl_getrecmaster_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmaster)
@ -1160,7 +1127,7 @@ int ctdb_ctrl_getrecmaster(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struc
{
struct ctdb_client_control_state *state;
state = ctdb_ctrl_getrecmaster_send(ctdb, mem_ctx, timeout, destnode, NULL, NULL);
state = ctdb_ctrl_getrecmaster_send(ctdb, mem_ctx, timeout, destnode);
return ctdb_ctrl_getrecmaster_recv(ctdb, mem_ctx, state, recmaster);
}

View File

@ -98,15 +98,24 @@ struct ctdb_call_info {
enum control_state {CTDB_CONTROL_WAIT, CTDB_CONTROL_DONE, CTDB_CONTROL_ERROR, CTDB_CONTROL_TIMEOUT};
struct ctdb_control_cb_data {
enum control_state state;
uint32_t vnn;
struct ctdb_client_control_state {
struct ctdb_context *ctdb;
uint32_t reqid;
int32_t status;
TDB_DATA outdata;
enum control_state state;
char *errormsg;
};
struct ctdb_req_control *c;
typedef int (*control_callback)(struct ctdb_control_cb_data *cb_data, void *cb_private);
/* if we have a callback registered for the completion (or failure) of
this control
if a callback is used, it MUST talloc_free the cb_data passed to it
*/
struct {
void (*fn)(struct ctdb_client_control_state *);
void *private;
} async;
};
struct event_context;
@ -340,7 +349,7 @@ int ctdb_ctrl_setmonmode(struct ctdb_context *ctdb, struct timeval timeout, uint
*/
int ctdb_ctrl_getrecmaster(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmaster);
struct ctdb_client_control_state *ctdb_ctrl_getrecmaster_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, control_callback callback, void *cb_private);
struct ctdb_client_control_state *ctdb_ctrl_getrecmaster_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode);
int ctdb_ctrl_getrecmaster_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmaster);

View File

@ -861,8 +861,7 @@ ctdb_control_send(struct ctdb_context *ctdb,
uint32_t opcode, uint32_t flags, TDB_DATA data,
TALLOC_CTX *mem_ctx, TDB_DATA *outdata,
struct timeval *timeout,
char **errormsg,
control_callback callback, void *cb_private);
char **errormsg);

View File

@ -1209,9 +1209,9 @@ struct verify_recmaster_data {
enum monitor_result status;
};
static int verify_recmaster_callback(struct ctdb_control_cb_data *cb_data, void *cb_private)
static void verify_recmaster_callback(struct ctdb_client_control_state *state)
{
struct verify_recmaster_data *rmdata = talloc_get_type(cb_private, struct verify_recmaster_data);
struct verify_recmaster_data *rmdata = talloc_get_type(state->async.private, struct verify_recmaster_data);
/* one more node has responded with recmaster data*/
@ -1220,22 +1220,22 @@ static int verify_recmaster_callback(struct ctdb_control_cb_data *cb_data, void
/* if we failed to get the recmaster, then return an error and let
the main loop try again.
*/
if (cb_data->state != CTDB_CONTROL_DONE) {
if (state->state != CTDB_CONTROL_DONE) {
if (rmdata->status == MONITOR_OK) {
rmdata->status = MONITOR_FAILED;
}
return 0;
return;
}
/* if we got a response, then the recmaster will be stored in the
status field
*/
if (cb_data->status != rmdata->vnn) {
DEBUG(0,("Node %d does not agree we are the recmaster. Need a new recmaster election\n",cb_data->vnn));
if (state->status != rmdata->vnn) {
DEBUG(0,("Node %d does not agree we are the recmaster. Need a new recmaster election\n", state->c->hdr.destnode));
rmdata->status = MONITOR_ELECTION_NEEDED;
}
return 0;
return;
}
@ -1262,8 +1262,7 @@ static enum monitor_result verify_recmaster(struct ctdb_context *ctdb, struct ct
}
state = ctdb_ctrl_getrecmaster_send(ctdb, mem_ctx,
CONTROL_TIMEOUT(),
nodemap->nodes[j].vnn,
verify_recmaster_callback, rmdata);
nodemap->nodes[j].vnn);
if (state == NULL) {
/* we failed to send the control, treat this as
an error and try again next iteration
@ -1273,6 +1272,10 @@ static enum monitor_result verify_recmaster(struct ctdb_context *ctdb, struct ct
return MONITOR_FAILED;
}
/* set up the callback functions */
state->async.fn = verify_recmaster_callback;
state->async.private = rmdata;
/* one more control to wait for to complete */
rmdata->count++;
}