48#include <condition_variable>
52#include <unordered_map>
59#define MAX_MESSAGES 100
60#define MAX_MESSAGES_FOR_NOT_EXISTING_RECV 10
61#define MOD_NAME "[messaging] "
74 responder() : received_response(
nullptr) {}
78 static void receive_response(
void *s,
struct response *r) {
79 (*((shared_ptr<responder> *) s))->receive_response_real(r);
81 void receive_response_real(
struct response *r) {
82 unique_lock<mutex> lk(
lock);
83 received_response = r;
89 condition_variable cv;
100 struct pair_msg_path *mp = (
struct pair_msg_path *) m;
128 char *
item, *save_ptr;
129 tmp = path = strdup(const_path);
130 struct module *receiver = root;
131 shared_ptr<struct responder> responder;
134 msg->send_response = responder::receive_response;
135 responder = shared_ptr<struct responder>(
new struct responder());
136 msg->priv_data =
new shared_ptr<struct responder>(responder);
139 pthread_mutex_lock(&receiver->
lock);
141 while ((
item = strtok_r(path,
".", &save_ptr))) {
143 struct module *old_receiver = receiver;
145 if (strcmp(
item,
"root") == 0)
153 printf(
"Receiver %s does not exist.\n", const_path);
157 printf(
"Dropping some old messages for %s (queue full).\n", const_path);
162 struct pair_msg_path *saved_message = (
struct pair_msg_path *)
163 malloc(
sizeof(
struct pair_msg_path) + strlen(const_path + (
item - tmp)) + 1);
164 saved_message->msg =
msg;
165 strcpy(saved_message->path, const_path + (
item - tmp));
168 pthread_mutex_unlock(&old_receiver->
lock);
174 unique_lock<mutex> lk(responder->lock);
175 if (timeout_ms == -1) {
177 "non-existent recv. Please report!\n");
178 responder->cv.wait(lk, [responder]{
return responder->received_response != NULL;});
180 responder->cv.wait_for(lk, std::chrono::milliseconds(timeout_ms), [responder]{
return responder->received_response != NULL;});
182 if (responder->received_response) {
183 struct response *resp = responder->received_response;
184 responder->received_response = NULL;
191 pthread_mutex_unlock(&old_receiver->
lock);
197 pthread_mutex_lock(&receiver->
lock);
198 pthread_mutex_unlock(&old_receiver->
lock);
211 printf(
"Dropping some messages for %s - queue full.\n", const_path);
221 pthread_mutex_unlock(&receiver->
lock);
226 unique_lock<mutex> lk(responder->lock);
227 if (timeout_ms == -1) {
230 "module without msg notifier. Please report!\n");
232 responder->cv.wait(lk, [responder]{
return responder->received_response != NULL;});
234 responder->cv.wait_for(lk, std::chrono::milliseconds(timeout_ms), [responder]{
return responder->received_response != NULL;});
236 if (responder->received_response) {
237 struct response *resp = responder->received_response;
238 responder->received_response = NULL;
325 if (
msg->send_response) {
326 msg->send_response(
msg->priv_data, r);
332 if (
msg->data_deleter) {
336 if (
msg->priv_data) {
337 delete (shared_ptr<struct responder> *)
msg->priv_data;
356 resp->
text[0] =
'\0';
375 const static unordered_map<int, const char *>
mapping = {
const char unsigned int flags
static const struct codec_param mapping[AC_COUNT]
void log_msg(int level, const char *format,...)
#define LOG_LEVEL_WARNING
less severe errors
struct module * get_matching_child(struct module *node, const char *const_path)
void simple_linked_list_append(struct simple_linked_list *l, void *data)
void * simple_linked_list_it_next(void **i)
bool simple_linked_list_remove(struct simple_linked_list *l, void *item)
int simple_linked_list_size(struct simple_linked_list *l)
void * simple_linked_list_pop(struct simple_linked_list *l)
void * simple_linked_list_it_init(struct simple_linked_list *l)
void free_message(struct message *msg, struct response *r)
struct response * new_response(int status, const char *text)
struct response * send_message_sync(struct module *root, const char *const_path, struct message *msg, int timeout_ms, int flags)
Sends message without waiting for response.
void module_store_message(struct module *node, struct message *m)
void free_message_for_child(void *m, struct response *r)
int response_get_status(struct response *r)
struct response * send_message_to_receiver(struct module *receiver, struct message *msg)
struct response * send_message(struct module *root, const char *const_path, struct message *msg)
Sends message without waiting for response.
struct message * new_message(size_t len)
static struct response * send_message_common(struct module *root, const char *const_path, struct message *msg, bool sync, int timeout_ms, int flags)
struct message * check_message(struct module *mod)
void free_response(struct response *r)
const char * response_status_to_text(int status)
const char * response_get_text(struct response *r)
void module_check_undelivered_messages(struct module *node)
Sends message with waiting for response.
#define MAX_MESSAGES_FOR_NOT_EXISTING_RECV
#define SEND_MESSAGE_FLAG_QUIET
do not print error messages on console (recv not found/queue full)
#define RESPONSE_NO_CONTENT
#define RESPONSE_NOT_IMPL
#define RESPONSE_REQ_TIMEOUT
#define SEND_MESSAGE_FLAG_NO_STORE
if receiver doesn't exist, doesn't store it and retur 404 instead
#define RESPONSE_BAD_REQUEST
#define RESPONSE_INT_SERV_ERR
#define RESPONSE_ACCEPTED
#define RESPONSE_NOT_FOUND
class generic_lock_guard< pthread_mutex_t, pthread_mutex_lock, pthread_mutex_unlock > pthread_mutex_guard
struct simple_linked_list * msg_queue
notify_t new_message
if set, notifies module that new message is in queue, receiver lock is hold during the call
pthread_mutex_t msg_queue_lock
struct simple_linked_list * msg_queue_children
messages for childern that were not delivered