qd_connector_t *qd_dispatch_configure_connector(qd_dispatch_t *qd, qd_entity_t *entity) { qd_connection_manager_t *cm = qd->connection_manager; qd_connector_t *ct = qd_server_connector(qd->server); if (ct && load_server_config(qd, &ct->config, entity, false) == QD_ERROR_NONE) { DEQ_ITEM_INIT(ct); DEQ_INSERT_TAIL(cm->connectors, ct); log_config(cm->log_source, &ct->config, "Connector"); // // Add the first item to the ct->conn_info_list // The initial connection information and any backup connection information is stored in the conn_info_list // qd_failover_item_t *item = NEW(qd_failover_item_t); ZERO(item); item->scheme = 0; item->host = strdup(ct->config.host); item->port = strdup(ct->config.port); item->hostname = 0; int hplen = strlen(item->host) + strlen(item->port) + 2; item->host_port = malloc(hplen); snprintf(item->host_port, hplen, "%s:%s", item->host , item->port); DEQ_INSERT_TAIL(ct->conn_info_list, item); return ct; } qd_log(cm->log_source, QD_LOG_ERROR, "Unable to create connector: %s", qd_error_message()); qd_connector_decref(ct); return 0; }
qdr_auto_link_t *qdr_route_add_auto_link_CT(qdr_core_t *core, qd_iterator_t *name, qd_parsed_field_t *addr_field, qd_direction_t dir, int phase, qd_parsed_field_t *container_field, qd_parsed_field_t *connection_field, qd_parsed_field_t *external_addr) { qdr_auto_link_t *al = new_qdr_auto_link_t(); // // Set up the auto_link structure // ZERO(al); al->identity = qdr_identifier(core); al->name = name ? (char*) qd_iterator_copy(name) : 0; al->dir = dir; al->phase = phase; al->state = QDR_AUTO_LINK_STATE_INACTIVE; al->external_addr = external_addr ? (char*) qd_iterator_copy(qd_parse_raw(external_addr)) : 0; // // Find or create an address for the auto_link destination // qd_iterator_t *iter = qd_parse_raw(addr_field); qd_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH); qd_iterator_annotate_phase(iter, (char) phase + '0'); qd_hash_retrieve(core->addr_hash, iter, (void*) &al->addr); if (!al->addr) { al->addr = qdr_address_CT(core, qdr_treatment_for_address_CT(core, 0, iter, 0, 0)); DEQ_INSERT_TAIL(core->addrs, al->addr); qd_hash_insert(core->addr_hash, iter, al->addr, &al->addr->hash_handle); } al->addr->ref_count++; // // Find or create a connection identifier structure for this auto_link // if (container_field || connection_field) { al->conn_id = qdr_route_declare_id_CT(core, qd_parse_raw(container_field), qd_parse_raw(connection_field)); DEQ_INSERT_TAIL_N(REF, al->conn_id->auto_link_refs, al); qdr_connection_ref_t * cref = DEQ_HEAD(al->conn_id->connection_refs); while (cref) { qdr_auto_link_activate_CT(core, al, cref->conn); cref = DEQ_NEXT(cref); } } // // Add the auto_link to the core list // DEQ_INSERT_TAIL(core->auto_links, al); return al; }
qdr_link_route_t *qdr_route_add_link_route_CT(qdr_core_t *core, qd_iterator_t *name, qd_parsed_field_t *prefix_field, qd_parsed_field_t *container_field, qd_parsed_field_t *connection_field, qd_address_treatment_t treatment, qd_direction_t dir) { qdr_link_route_t *lr = new_qdr_link_route_t(); // // Set up the link_route structure // ZERO(lr); lr->identity = qdr_identifier(core); lr->name = name ? (char*) qd_iterator_copy(name) : 0; lr->dir = dir; lr->treatment = treatment; // // Find or create an address for link-attach routing // qd_iterator_t *iter = qd_parse_raw(prefix_field); qd_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH); qd_iterator_annotate_prefix(iter, dir == QD_INCOMING ? 'C' : 'D'); qd_hash_retrieve(core->addr_hash, iter, (void*) &lr->addr); if (!lr->addr) { lr->addr = qdr_address_CT(core, treatment); DEQ_INSERT_TAIL(core->addrs, lr->addr); qd_hash_insert(core->addr_hash, iter, lr->addr, &lr->addr->hash_handle); } lr->addr->ref_count++; // // Find or create a connection identifier structure for this link route // if (container_field || connection_field) { lr->conn_id = qdr_route_declare_id_CT(core, qd_parse_raw(container_field), qd_parse_raw(connection_field)); DEQ_INSERT_TAIL_N(REF, lr->conn_id->link_route_refs, lr); qdr_connection_ref_t * cref = DEQ_HEAD(lr->conn_id->connection_refs); while (cref) { qdr_link_route_activate_CT(core, lr, cref->conn); cref = DEQ_NEXT(cref); } } // // Add the link route to the core list // DEQ_INSERT_TAIL(core->link_routes, lr); return lr; }
void dx_dealloc(dx_alloc_type_desc_t *desc, dx_alloc_pool_t **tpool, void *p) { item_t *item = ((item_t*) p) - 1; int idx; // // If this is the thread's first pass through here, allocate the // thread-local pool for this type. // if (*tpool == 0) { *tpool = NEW(dx_alloc_pool_t); DEQ_INIT((*tpool)->free_list); } dx_alloc_pool_t *pool = *tpool; DEQ_INSERT_TAIL(pool->free_list, item); if (DEQ_SIZE(pool->free_list) <= desc->config->local_free_list_max) return; // // We've exceeded the maximum size of the local free list. A batch must be // rebalanced back to the global list. // sys_mutex_lock(desc->lock); desc->stats->batches_rebalanced_to_global++; desc->stats->held_by_threads -= desc->config->transfer_batch_size; for (idx = 0; idx < desc->config->transfer_batch_size; idx++) { item = DEQ_HEAD(pool->free_list); DEQ_REMOVE_HEAD(pool->free_list); DEQ_INSERT_TAIL(desc->global_pool->free_list, item); } // // If there's a global_free_list size limit, remove items until the limit is // not exceeded. // if (desc->config->global_free_list_max != 0) { while (DEQ_SIZE(desc->global_pool->free_list) > desc->config->global_free_list_max) { item = DEQ_HEAD(desc->global_pool->free_list); DEQ_REMOVE_HEAD(desc->global_pool->free_list); free(item); desc->stats->total_free_to_heap++; } } sys_mutex_unlock(desc->lock); }
qd_listener_t *qd_dispatch_configure_listener(qd_dispatch_t *qd, qd_entity_t *entity) { qd_connection_manager_t *cm = qd->connection_manager; qd_listener_t *li = qd_server_listener(qd->server); if (!li || load_server_config(qd, &li->config, entity, true) != QD_ERROR_NONE) { qd_log(cm->log_source, QD_LOG_ERROR, "Unable to create listener: %s", qd_error_message()); qd_listener_decref(li); return 0; } char *fol = qd_entity_opt_string(entity, "failoverList", 0); if (fol) { li->config.failover_list = qd_failover_list(fol); free(fol); if (li->config.failover_list == 0) { qd_log(cm->log_source, QD_LOG_ERROR, "Unable to create listener, bad failover list: %s", qd_error_message()); qd_listener_decref(li); return 0; } } else { li->config.failover_list = 0; } DEQ_ITEM_INIT(li); DEQ_INSERT_TAIL(cm->listeners, li); log_config(cm->log_source, &li->config, "Listener"); return li; }
qd_config_connector_t *qd_dispatch_configure_connector(qd_dispatch_t *qd, qd_entity_t *entity) { qd_error_clear(); qd_connection_manager_t *cm = qd->connection_manager; qd_config_connector_t *cc = NEW(qd_config_connector_t); ZERO(cc); cc->is_connector = true; qd_config_ssl_profile_t *ssl_profile = 0; if (load_server_config(qd, &cc->configuration, entity, &ssl_profile) != QD_ERROR_NONE) { qd_log(cm->log_source, QD_LOG_ERROR, "Unable to create config connector: %s", qd_error_message()); qd_config_connector_free(qd->connection_manager, cc); return 0; } cc->ssl_profile = ssl_profile; DEQ_ITEM_INIT(cc); DEQ_INSERT_TAIL(cm->config_connectors, cc); qd_log(cm->log_source, QD_LOG_INFO, "Configured Connector: %s:%s proto=%s, role=%s %s%s", cc->configuration.host, cc->configuration.port, cc->configuration.protocol_family ? cc->configuration.protocol_family : "any", cc->configuration.role, cc->ssl_profile ? ", sslProfile=":"", cc->ssl_profile ? cc->ssl_profile->name:""); return cc; }
qdr_field_t *qdr_field_from_iter(qd_iterator_t *iter) { if (!iter) return 0; qdr_field_t *field = new_qdr_field_t(); qd_buffer_t *buf; int remaining; int length; ZERO(field); qd_iterator_reset(iter); remaining = qd_iterator_remaining(iter); length = remaining; while (remaining) { buf = qd_buffer(); size_t cap = qd_buffer_capacity(buf); int copied = qd_iterator_ncopy(iter, qd_buffer_cursor(buf), cap); qd_buffer_insert(buf, copied); DEQ_INSERT_TAIL(field->buffers, buf); remaining = qd_iterator_remaining(iter); } field->iterator = qd_iterator_buffer(DEQ_HEAD(field->buffers), 0, length, ITER_VIEW_ALL); return field; }
static void push_event(action_t action, const char *type, void *object) { if (!event_lock) return; /* Unit tests don't call qd_entity_cache_initialize */ sys_mutex_lock(event_lock); entity_event_t *event = entity_event(action, type, object); DEQ_INSERT_TAIL(event_list, event); sys_mutex_unlock(event_lock); }
static char* test_insufficient_check_depth(void *context) { nx_allocator_initialize(nx_allocator_default_config()); pn_message_t *pn_msg = pn_message(); pn_message_set_address(pn_msg, "test_addr_2"); nx_buffer_t *buf = nx_allocate_buffer(); size_t size = nx_buffer_capacity(buf); int result = pn_message_encode(pn_msg, (char*) nx_buffer_cursor(buf), &size); if (result != 0) return "Error in pn_message_encode"; nx_buffer_insert(buf, size); nx_message_t *msg = nx_allocate_message(); DEQ_INSERT_TAIL(msg->buffers, buf); int valid = nx_message_check(msg, NX_DEPTH_DELIVERY_ANNOTATIONS); if (!valid) return "nx_message_check returns 'invalid'"; nx_field_iterator_t *iter = nx_message_field_to(msg); if (iter) return "Expected no iterator for the 'to' field"; nx_free_message(msg); nx_allocator_finalize(); return 0; }
void qdr_action_enqueue(qdr_core_t *core, qdr_action_t *action) { sys_mutex_lock(core->action_lock); DEQ_INSERT_TAIL(core->action_list, action); sys_cond_signal(core->action_cond); sys_mutex_unlock(core->action_lock); }
void qd_log_impl(qd_log_source_t *source, qd_log_level_t level, const char *file, int line, const char *fmt, ...) { if (!qd_log_enabled(source, level)) return; qd_log_entry_t *entry = new_qd_log_entry_t(); DEQ_ITEM_INIT(entry); entry->module = source->module; entry->level = level; entry->file = file ? strdup(file) : 0; entry->line = line; time(&entry->time); va_list ap; va_start(ap, fmt); vsnprintf(entry->text, TEXT_MAX, fmt, ap); va_end(ap); write_log(source, entry); // Bounded buffer of log entries, keep most recent. sys_mutex_lock(log_lock); DEQ_INSERT_TAIL(entries, entry); if (DEQ_SIZE(entries) > LIST_MAX) qd_log_entry_free_lh(DEQ_HEAD(entries)); sys_mutex_unlock(log_lock); }
qd_config_ssl_profile_t *qd_dispatch_configure_ssl_profile(qd_dispatch_t *qd, qd_entity_t *entity) { qd_error_clear(); qd_connection_manager_t *cm = qd->connection_manager; qd_config_ssl_profile_t *ssl_profile = NEW(qd_config_ssl_profile_t); DEQ_ITEM_INIT(ssl_profile); DEQ_INSERT_TAIL(cm->config_ssl_profiles, ssl_profile); ssl_profile->name = qd_entity_opt_string(entity, "name", 0); CHECK(); ssl_profile->ssl_certificate_file = qd_entity_opt_string(entity, "certFile", 0); CHECK(); ssl_profile->ssl_private_key_file = qd_entity_opt_string(entity, "keyFile", 0); CHECK(); ssl_profile->ssl_password = qd_entity_opt_string(entity, "password", 0); CHECK(); ssl_profile->ssl_trusted_certificate_db = qd_entity_opt_string(entity, "certDb", 0); CHECK(); ssl_profile->ssl_trusted_certificates = qd_entity_opt_string(entity, "trustedCerts", 0); CHECK(); ssl_profile->ssl_uid_format = qd_entity_opt_string(entity, "uidFormat", 0); CHECK(); ssl_profile->ssl_display_name_file = qd_entity_opt_string(entity, "displayNameFile", 0); CHECK(); sys_atomic_init(&ssl_profile->ref_count, 0); qd_log(cm->log_source, QD_LOG_INFO, "Created SSL Profile with name %s ", ssl_profile->name); return ssl_profile; error: qd_log(cm->log_source, QD_LOG_ERROR, "Unable to create ssl profile: %s", qd_error_message()); qd_config_ssl_profile_free(cm, ssl_profile); return 0; }
unsigned int qd_buffer_list_clone(qd_buffer_list_t *dst, const qd_buffer_list_t *src) { uint32_t len = 0; DEQ_INIT(*dst); qd_buffer_t *buf = DEQ_HEAD(*src); while (buf) { size_t to_copy = qd_buffer_size(buf); unsigned char *src = qd_buffer_base(buf); len += to_copy; while (to_copy) { qd_buffer_t *newbuf = qd_buffer(); size_t count = qd_buffer_capacity(newbuf); // default buffer capacity may have changed, // so don't assume it will fit: if (count > to_copy) count = to_copy; memcpy(qd_buffer_cursor(newbuf), src, count); qd_buffer_insert(newbuf, count); DEQ_INSERT_TAIL(*dst, newbuf); src += count; to_copy -= count; } buf = DEQ_NEXT(buf); } return len; }
static hash_item_t *hash_internal_insert(hash_t *h, nx_field_iterator_t *key, int *error) { unsigned long idx = hash_function(key) & h->bucket_mask; hash_item_t *item = DEQ_HEAD(h->buckets[idx].items); *error = 0; while (item) { if (nx_field_iterator_equal(key, item->key)) break; item = item->next; } if (item) { *error = -1; return 0; } item = new_hash_item_t(); if (!item) { *error = -2; return 0; } DEQ_ITEM_INIT(item); item->key = nx_field_iterator_copy(key); DEQ_INSERT_TAIL(h->buckets[idx].items, item); h->size++; return item; }
void qdr_add_delivery_ref_CT(qdr_delivery_ref_list_t *list, qdr_delivery_t *dlv) { qdr_delivery_ref_t *ref = new_qdr_delivery_ref_t(); DEQ_ITEM_INIT(ref); ref->dlv = dlv; DEQ_INSERT_TAIL(*list, ref); }
static char* test_receive_from_messenger(void *context) { nx_allocator_initialize(nx_allocator_default_config()); pn_message_t *pn_msg = pn_message(); pn_message_set_address(pn_msg, "test_addr_1"); nx_buffer_t *buf = nx_allocate_buffer(); size_t size = nx_buffer_capacity(buf); int result = pn_message_encode(pn_msg, (char*) nx_buffer_cursor(buf), &size); if (result != 0) return "Error in pn_message_encode"; nx_buffer_insert(buf, size); nx_message_t *msg = nx_allocate_message(); DEQ_INSERT_TAIL(msg->buffers, buf); int valid = nx_message_check(msg, NX_DEPTH_ALL); if (!valid) return "nx_message_check returns 'invalid'"; nx_field_iterator_t *iter = nx_message_field_to(msg); if (iter == 0) return "Expected an iterator for the 'to' field"; if (!nx_field_iterator_equal(iter, (unsigned char*) "test_addr_1")) return "Mismatched 'to' field contents"; pn_message_free(pn_msg); nx_free_message(msg); nx_allocator_finalize(); return 0; }
void qdr_add_connection_ref(qdr_connection_ref_list_t *ref_list, qdr_connection_t *conn) { qdr_connection_ref_t *ref = new_qdr_connection_ref_t(); DEQ_ITEM_INIT(ref); ref->conn = conn; DEQ_INSERT_TAIL(*ref_list, ref); }
static log_sink_t* log_sink_lh(const char* name) { log_sink_t* sink = find_log_sink_lh(name); if (sink) sink->refcount++; else { sink = NEW(log_sink_t); *sink = (log_sink_t){ 1, strdup(name), }; if (strcmp(name, SINK_STDERR) == 0) { sink->file = stderr; } else if (strcmp(name, SINK_SYSLOG) == 0) { openlog(0, 0, LOG_DAEMON); sink->syslog = true; } else { sink->file = fopen(name, "w"); if (!sink->file) { char msg[TEXT_MAX]; snprintf(msg, sizeof(msg), "Failed to open log file '%s'", name); perror(msg); exit(1); } } DEQ_INSERT_TAIL(sink_list, sink); } return sink; }
qdr_address_t *qdr_add_mobile_address_CT(qdr_core_t *core, const char *prefix, const char *address, qd_address_treatment_t treatment, bool edge) { char addr_string_stack[1000]; char *addr_string = addr_string_stack; bool allocated = false; qdr_address_t *addr = 0; qd_iterator_t *iter = 0; size_t len = strlen(prefix) + strlen(address) + 3; if (len > sizeof(addr_string_stack)) { allocated = true; addr_string = (char*) malloc(len); } snprintf(addr_string, len, "%s%s%s", edge ? "H" : "M0", prefix, address); iter = qd_iterator_string(addr_string, ITER_VIEW_ALL); qd_hash_retrieve(core->addr_hash, iter, (void**) &addr); if (!addr) { addr = qdr_address_CT(core, treatment, 0); if (addr) { qd_hash_insert(core->addr_hash, iter, addr, &addr->hash_handle); DEQ_INSERT_TAIL(core->addrs, addr); } } qd_iterator_free(iter); if (allocated) free(addr_string); return addr; }
qd_config_listener_t *qd_dispatch_configure_listener(qd_dispatch_t *qd, qd_entity_t *entity) { qd_error_clear(); qd_connection_manager_t *cm = qd->connection_manager; qd_config_listener_t *cl = NEW(qd_config_listener_t); cl->is_connector = false; cl->state = QD_BIND_NONE; cl->listener = 0; qd_config_ssl_profile_t *ssl_profile = 0; if (load_server_config(qd, &cl->configuration, entity, &ssl_profile) != QD_ERROR_NONE) { qd_log(cm->log_source, QD_LOG_ERROR, "Unable to create config listener: %s", qd_error_message()); qd_config_listener_free(qd->connection_manager, cl); return 0; } cl->ssl_profile = ssl_profile; DEQ_ITEM_INIT(cl); DEQ_INSERT_TAIL(cm->config_listeners, cl); qd_log(cm->log_source, QD_LOG_INFO, "Configured Listener: %s:%s proto=%s, role=%s%s%s", cl->configuration.host, cl->configuration.port, cl->configuration.protocol_family ? cl->configuration.protocol_family : "any", cl->configuration.role, cl->ssl_profile ? ", sslProfile=":"", cl->ssl_profile ? cl->ssl_profile->name:""); return cl; }
qdr_field_t *qdr_field(const char *text) { size_t length = text ? strlen(text) : 0; size_t ilength = length; if (length == 0) return 0; qdr_field_t *field = new_qdr_field_t(); qd_buffer_t *buf; ZERO(field); while (length > 0) { buf = qd_buffer(); size_t cap = qd_buffer_capacity(buf); size_t copy = length > cap ? cap : length; memcpy(qd_buffer_cursor(buf), text, copy); qd_buffer_insert(buf, copy); length -= copy; text += copy; DEQ_INSERT_TAIL(field->buffers, buf); } field->iterator = qd_iterator_buffer(DEQ_HEAD(field->buffers), 0, ilength, ITER_VIEW_ALL); return field; }
static void dx_alloc_init(dx_alloc_type_desc_t *desc) { sys_mutex_lock(init_lock); desc->total_size = desc->type_size; if (desc->additional_size) desc->total_size += *desc->additional_size; //dx_log("ALLOC", LOG_TRACE, "Initialized Allocator - type=%s type-size=%d total-size=%d", // desc->type_name, desc->type_size, desc->total_size); if (!desc->global_pool) { if (desc->config == 0) desc->config = desc->total_size > 256 ? &dx_alloc_default_config_big : &dx_alloc_default_config_small; assert (desc->config->local_free_list_max >= desc->config->transfer_batch_size); desc->global_pool = NEW(dx_alloc_pool_t); DEQ_INIT(desc->global_pool->free_list); desc->lock = sys_mutex(); desc->stats = NEW(dx_alloc_stats_t); memset(desc->stats, 0, sizeof(dx_alloc_stats_t)); } item_t *type_item = NEW(item_t); DEQ_ITEM_INIT(type_item); type_item->desc = desc; DEQ_INSERT_TAIL(type_list, type_item); sys_mutex_unlock(init_lock); }
void qdr_add_node_ref(qdr_router_ref_list_t *ref_list, qdr_node_t *rnode) { qdr_router_ref_t *ref = new_qdr_router_ref_t(); DEQ_ITEM_INIT(ref); ref->router = rnode; rnode->ref_count++; DEQ_INSERT_TAIL(*ref_list, ref); }
void qdr_agent_enqueue_response_CT(qdr_core_t *core, qdr_query_t *query) { sys_mutex_lock(core->query_lock); DEQ_INSERT_TAIL(core->outgoing_query_list, query); bool notify = DEQ_SIZE(core->outgoing_query_list) == 1; sys_mutex_unlock(core->query_lock); if (notify) qd_timer_schedule(core->agent_timer, 0); }
/** * Create a new hash segment and insert it at the end of the linked list */ static void qd_insert_hash_segment(qd_iterator_t *iter, uint32_t *hash, int segment_length) { qd_hash_segment_t *hash_segment = qd_iterator_hash_segment(); // While storing the segment, don't include the hash of the separator in the segment but do include it in the overall hash. hash_segment->hash = *hash; hash_segment->segment_length = segment_length; DEQ_INSERT_TAIL(iter->hash_segments, hash_segment); }
void qdr_add_link_ref(qdr_link_ref_list_t *ref_list, qdr_link_t *link, int cls) { if (link->ref[cls] != 0) return; qdr_link_ref_t *ref = new_qdr_link_ref_t(); DEQ_ITEM_INIT(ref); ref->link = link; link->ref[cls] = ref; DEQ_INSERT_TAIL(*ref_list, ref); }
static void allocate_batch(work_queue_t *w) { int i; work_item_t *batch = NEW_ARRAY(work_item_t, BATCH_SIZE); if (!batch) return; memset(batch, 0, sizeof(work_item_t) * BATCH_SIZE); for (i = 0; i < BATCH_SIZE; i++) DEQ_INSERT_TAIL(w->free_list, &batch[i]); }
void qdr_post_general_work_CT(qdr_core_t *core, qdr_general_work_t *work) { bool notify; sys_mutex_lock(core->work_lock); DEQ_ITEM_INIT(work); DEQ_INSERT_TAIL(core->work_list, work); notify = DEQ_SIZE(core->work_list) == 1; sys_mutex_unlock(core->work_lock); if (notify) qd_timer_schedule(core->work_timer, 0); }
static void qdr_subscribe_CT(qdr_core_t *core, qdr_action_t *action, bool discard) { qdr_field_t *address = action->args.io.address; qdr_subscription_t *sub = action->args.io.subscription; if (!discard) { char aclass = action->args.io.address_class; char phase = action->args.io.address_phase; qdr_address_t *addr = 0; char *astring = (char*) qd_field_iterator_copy(address->iterator); qd_log(core->log, QD_LOG_INFO, "In-process subscription %c/%s", aclass, astring); free(astring); qd_address_iterator_override_prefix(address->iterator, aclass); if (aclass == 'M') qd_address_iterator_set_phase(address->iterator, phase); qd_address_iterator_reset_view(address->iterator, ITER_VIEW_ADDRESS_HASH); qd_hash_retrieve(core->addr_hash, address->iterator, (void**) &addr); if (!addr) { addr = qdr_address_CT(core, action->args.io.treatment); qd_hash_insert(core->addr_hash, address->iterator, addr, &addr->hash_handle); DEQ_ITEM_INIT(addr); DEQ_INSERT_TAIL(core->addrs, addr); } sub->addr = addr; DEQ_ITEM_INIT(sub); DEQ_INSERT_TAIL(addr->subscriptions, sub); qdr_addr_start_inlinks_CT(core, addr); } else free(sub); qdr_field_free(address); }
/// Caller must hold the log_source_lock static qd_log_source_t *qd_log_source_lh(const char *module) { qd_log_source_t *log_source = lookup_log_source_lh(module); if (!log_source) { log_source = NEW(qd_log_source_t); memset(log_source, 0, sizeof(qd_log_source_t)); DEQ_ITEM_INIT(log_source); log_source->module = (char*) malloc(strlen(module) + 1); strcpy(log_source->module, module); qd_log_source_defaults(log_source); DEQ_INSERT_TAIL(source_list, log_source); } return log_source; }