#define _CTDB_H
#include <sys/types.h>
#include <stdint.h>
+#include <stdbool.h>
#include <tdb.h>
/* All *_send() functions are guaranteed to be non-blocking and fully
*
* When the lock is released, data is freed too, so make sure to copy the data
* before that.
+ *
+ * This returns true on success, and req will be non-NULL if a request was
+ * actually sent, otherwise callback will have already been called.
*/
-struct ctdb_request *
+bool
ctdb_readrecordlock_send(struct ctdb_db *ctdb_db, TDB_DATA key,
+ struct ctdb_request **req,
ctdb_callback_t callback, void *private_data);
struct ctdb_lock *ctdb_readrecordlock_recv(struct ctdb_db *ctdb_db,
struct ctdb_request *handle,
ctdb_attachdb_send((ctdb), (name), (persistent), (tdb_flags), \
ctdb_sendcb((cb), (cbdata)), (cbdata))
-#define ctdb_readrecordlock_send(ctdb_db, key, cb, cbdata) \
- ctdb_readrecordlock_send((ctdb_db), (key), \
+#define ctdb_readrecordlock_send(ctdb_db, key, reqp, cb, cbdata) \
+ ctdb_readrecordlock_send((ctdb_db), (key), (reqp), \
ctdb_sendcb((cb), (cbdata)), (cbdata))
#define ctdb_set_message_handler_send(ctdb, srvid, handler, cb, cbdata) \
goto fail;
ctdb->outq = NULL;
ctdb->doneq = NULL;
- ctdb->immediateq = NULL;
ctdb->in = NULL;
ctdb->message_handlers = NULL;
+ ctdb->next_id = 0;
+ ctdb->broken = false;
memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_UNIX;
if (io_elem_finished(ctdb->outq->io)) {
struct ctdb_request *done = ctdb->outq;
DLIST_REMOVE(ctdb->outq, done);
- DLIST_ADD_END(ctdb->doneq, done,
- struct ctdb_request);
+ /* We add at the head: any dead ones
+ * sit and end. */
+ DLIST_ADD(ctdb->doneq, done);
}
}
}
}
}
- while (ctdb->immediateq) {
- struct ctdb_request *imm = ctdb->immediateq;
- imm->callback(ctdb, imm, imm->priv_data);
- DLIST_REMOVE(ctdb->immediateq, imm);
- }
-
return 0;
}
pkt->flags = 0;
pkt->datalen = extra;
memcpy(pkt->data, extra_data, extra);
- DLIST_ADD_END(ctdb->outq, req, struct ctdb_request);
+ DLIST_ADD(ctdb->outq, req);
return req;
}
/* Retransmit the same request again (we lost race). */
io_elem_reset(req->io);
- DLIST_ADD_END(ctdb->outq, req, struct ctdb_request);
+ DLIST_ADD(ctdb->outq, req);
return;
}
-struct ctdb_request *
+bool
ctdb_readrecordlock_send(struct ctdb_db *ctdb_db, TDB_DATA key,
+ struct ctdb_request **reqp,
ctdb_callback_t callback, void *cbdata)
{
struct ctdb_request *req;
req->extra_destructor = destroy_lock;
if (try_readrecordlock(lock)) {
- /* Already got it: prepare for immediate callback. */
- DLIST_ADD_END(ctdb_db->ctdb->immediateq,
- req, struct ctdb_request);
- return req;
+ *reqp = NULL;
+ callback(ctdb_db->ctdb, req, cbdata);
+ return true;
}
/* We store the original callback in the lock, and use our own. */
req->hdr.call->keylen = key.dsize;
req->hdr.call->calldatalen = 0;
memcpy(req->hdr.call->data, key.dptr, key.dsize);
- DLIST_ADD_END(ctdb_db->ctdb->outq, req, struct ctdb_request);
- return req;
+ DLIST_ADD(ctdb_db->ctdb->outq, req);
+ *reqp = req;
+ return true;
}
int ctdb_writerecord(struct ctdb_lock *lock, TDB_DATA data)
struct ctdb_request *outq;
/* Finished outgoings (awaiting response) */
struct ctdb_request *doneq;
- /* Successful sync requests, waiting for next service. */
- struct ctdb_request *immediateq;
/* Current incoming. */
struct io_elem *in;
/* Guess at a good reqid to try next. */
}
/* Put ourselves in list of handlers. */
- DLIST_ADD_END(ctdb->message_handlers, info,
- struct message_handler_info);
+ DLIST_ADD(ctdb->message_handlers, info);
/* Keep safe from destructor */
req->extra = NULL;
return 0;
exit(10);
}
- handle = ctdb_readrecordlock_send(ctdb_db_context, key, rrl_cb,
- ctdb_db_context);
- if (handle == NULL) {
+ if (!ctdb_readrecordlock_send(ctdb_db_context, key, &handle,
+ rrl_cb, ctdb_db_context)) {
printf("Failed to send READRECORDLOCK\n");
exit(10);
}
-
+ if (handle) {
+ printf("READRECORDLOCK is async\n");
+ }
for (;;) {
pfd.events = ctdb_which_events(ctdb_connection);