1 #include "libctdb_private.h"
6 #include <ctdb_protocol.h>
10 /* Remove type-safety macros. */
11 #undef ctdb_set_message_handler_send
12 #undef ctdb_set_message_handler_recv
13 #undef ctdb_remove_message_handler_send
15 struct message_handler_info {
16 struct message_handler_info *next, *prev;
19 ctdb_message_fn_t handler;
23 void deliver_message(struct ctdb_connection *ctdb, struct ctdb_req_header *hdr)
25 struct message_handler_info *i;
26 struct ctdb_req_message *msg = (struct ctdb_req_message *)hdr;
30 data.dptr = msg->data;
31 data.dsize = msg->datalen;
33 for (i = ctdb->message_handlers; i; i = i->next) {
34 if (i->srvid == msg->srvid) {
35 i->handler(ctdb, msg->srvid, data, i->private_data);
40 DEBUG(ctdb, LOG_WARNING,
41 "ctdb_service: messsage for unregistered srvid %llu",
46 bool ctdb_set_message_handler_recv(struct ctdb_connection *ctdb,
47 struct ctdb_request *req)
49 struct message_handler_info *info = req->extra;
50 struct ctdb_reply_control *reply;
52 reply = unpack_reply_control(ctdb, req, CTDB_CONTROL_REGISTER_SRVID);
56 if (reply->status != 0) {
57 DEBUG(ctdb, LOG_WARNING,
58 "ctdb_set_message_handler_recv: status %i",
63 /* Put ourselves in list of handlers. */
64 DLIST_ADD(ctdb->message_handlers, info);
65 /* Keep safe from destructor */
70 static void free_info(struct ctdb_connection *ctdb, struct ctdb_request *req)
76 ctdb_set_message_handler_send(struct ctdb_connection *ctdb, uint64_t srvid,
77 ctdb_message_fn_t handler,
78 ctdb_callback_t callback, void *private_data)
80 struct message_handler_info *info;
81 struct ctdb_request *req;
83 info = malloc(sizeof(*info));
86 "ctdb_set_message_handler_send: allocating info");
90 req = new_ctdb_control_request(ctdb, CTDB_CONTROL_REGISTER_SRVID,
91 CTDB_CURRENT_NODE, NULL, 0,
92 callback, private_data);
95 "ctdb_set_message_handler_send: allocating request");
100 req->extra_destructor = free_info;
101 req->hdr.control->srvid = srvid;
104 info->handler = handler;
105 info->private_data = private_data;
107 DEBUG(ctdb, LOG_DEBUG,
108 "ctdb_set_message_handler_send: sending request %u for id %llu",
109 req->hdr.hdr->reqid, srvid);
113 bool ctdb_send_message(struct ctdb_connection *ctdb,
114 uint32_t pnn, uint64_t srvid,
117 struct ctdb_request *req;
118 struct ctdb_req_message *pkt;
120 /* We just discard it once it's finished: no reply. */
121 req = new_ctdb_request(offsetof(struct ctdb_req_message, data) + data.dsize,
122 ctdb_cancel_callback, NULL);
124 DEBUG(ctdb, LOG_ERR, "ctdb_set_message: allocating message");
128 io_elem_init_req_header(req->io,
129 CTDB_REQ_MESSAGE, pnn, new_reqid(ctdb));
131 pkt = req->hdr.message;
133 pkt->datalen = data.dsize;
134 memcpy(pkt->data, data.dptr, data.dsize);
135 DLIST_ADD_END(ctdb->outq, req, struct ctdb_request);