#include <common/futex.hpp>
#include <common/hashtable/utils.hpp>
#include <common/macros.hpp>
+#include <common/pthread-lock.hpp>
#include <common/sessiond-comm/sessiond-comm.hpp>
#include <common/unix.hpp>
#include <common/urcu.hpp>
trigger_list =
caa_container_of(node, struct lttng_channel_trigger_list, channel_triggers_ht_node);
- return !!((channel_key->key == trigger_list->channel_key.key) &&
- (channel_key->domain == trigger_list->channel_key.domain));
+ return !((channel_key->key != trigger_list->channel_key.key) ||
+ (channel_key->domain != trigger_list->channel_key.domain));
}
static int match_session_trigger_list(struct cds_lfht_node *node, const void *key)
sample = caa_container_of(node, struct channel_state_sample, channel_state_ht_node);
- return !!((channel_key->key == sample->key.key) &&
- (channel_key->domain == sample->key.domain));
+ return !((channel_key->key != sample->key.key) ||
+ (channel_key->domain != sample->key.domain));
}
static int match_channel_info(struct cds_lfht_node *node, const void *key)
channel_info = caa_container_of(node, struct channel_info, channels_ht_node);
- return !!((channel_key->key == channel_info->key.key) &&
- (channel_key->domain == channel_info->key.domain));
+ return !((channel_key->key != channel_info->key.key) ||
+ (channel_key->domain != channel_info->key.domain));
}
static int match_trigger(struct cds_lfht_node *node, const void *key)
{
struct cds_lfht_iter iter;
struct cds_lfht_node *node;
- lttng::urcu::read_lock_guard read_lock_guard;
+ const lttng::urcu::read_lock_guard read_lock_guard;
cds_lfht_lookup(
state->sessions_ht, hash_session_info_id(id), match_session_info, &id, &iter);
static unsigned long hash_channel_key(struct channel_key *key)
{
- unsigned long key_hash = hash_key_u64(&key->key, lttng_ht_seed);
- unsigned long domain_hash =
+ const unsigned long key_hash = hash_key_u64(&key->key, lttng_ht_seed);
+ const unsigned long domain_hash =
hash_key_ulong((void *) (unsigned long) key->domain, lttng_ht_seed);
return key_hash ^ domain_hash;
}
lttng_session_trigger_list_destroy(session_info->trigger_list);
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
cds_lfht_del(session_info->sessions_ht, &session_info->sessions_ht_node);
free(session_info->name);
lttng_trace_archive_location_put(session_info->last_state_sample.rotation.location);
static void session_info_add_channel(struct session_info *session_info,
struct channel_info *channel_info)
{
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
cds_lfht_add(session_info->channel_infos_ht,
hash_channel_key(&channel_info->key),
&channel_info->session_info_channels_ht_node);
static void session_info_remove_channel(struct session_info *session_info,
struct channel_info *channel_info)
{
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
cds_lfht_del(session_info->channel_infos_ht, &channel_info->session_info_channels_ht_node);
}
lttng_condition_put(list->condition);
if (list->notification_trigger_clients_ht) {
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
cds_lfht_del(list->notification_trigger_clients_ht,
&list->notification_trigger_clients_ht_node);
notification_client_list_create(struct notification_thread_state *state,
const struct lttng_condition *condition)
{
- struct notification_client *client;
- struct cds_lfht_iter iter;
struct notification_client_list *client_list;
client_list = zmalloc<notification_client_list>();
*/
client_list->condition = lttng_condition_copy(condition);
- {
- /* Build a list of clients to which this new condition applies. */
- lttng::urcu::read_lock_guard read_lock;
-
- cds_lfht_for_each_entry (
- state->client_socket_ht, &iter, client, client_socket_ht_node) {
- struct notification_client_list_element *client_list_element;
-
- if (!condition_applies_to_client(condition, client)) {
- continue;
- }
+ for (auto *client : lttng::urcu::lfht_iteration_adapter<
+ notification_client,
+ decltype(notification_client::client_socket_ht_node),
+ ¬ification_client::client_socket_ht_node>(*state->client_socket_ht)) {
+ struct notification_client_list_element *client_list_element;
- client_list_element = zmalloc<notification_client_list_element>();
- if (!client_list_element) {
- goto error_put_client_list;
- }
+ if (!condition_applies_to_client(condition, client)) {
+ continue;
+ }
- CDS_INIT_LIST_HEAD(&client_list_element->node);
- client_list_element->client = client;
- cds_list_add(&client_list_element->node, &client_list->clients_list);
+ client_list_element = zmalloc<notification_client_list_element>();
+ if (!client_list_element) {
+ goto error_put_client_list;
}
+
+ CDS_INIT_LIST_HEAD(&client_list_element->node);
+ client_list_element->client = client;
+ cds_list_add(&client_list_element->node, &client_list->clients_list);
}
client_list->notification_trigger_clients_ht = state->notification_trigger_clients_ht;
* Add the client list to the global list of client list.
*/
{
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
cds_lfht_add_unique(state->notification_trigger_clients_ht,
lttng_condition_hash(client_list->condition),
struct cds_lfht_iter iter;
struct notification_client_list *list = nullptr;
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
cds_lfht_lookup(state->notification_trigger_clients_ht,
lttng_condition_hash(condition),
match_client_list_condition,
struct channel_info *channel_info = nullptr;
struct channel_key *channel_key = nullptr;
struct channel_state_sample *last_sample = nullptr;
- struct lttng_channel_trigger_list *channel_trigger_list = nullptr;
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
/* Find the channel associated with the condition. */
- cds_lfht_for_each_entry (
- state->channel_triggers_ht, &iter, channel_trigger_list, channel_triggers_ht_node) {
+ for (auto *channel_trigger_list : lttng::urcu::lfht_iteration_adapter<
+ lttng_channel_trigger_list,
+ decltype(lttng_channel_trigger_list::channel_triggers_ht_node),
+ <tng_channel_trigger_list::channel_triggers_ht_node>(
+ *state->channel_triggers_ht)) {
struct lttng_trigger_list_element *element;
cds_list_for_each_entry (element, &channel_trigger_list->list, node) {
/* Publish the list through the session_triggers_ht. */
{
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
cds_lfht_add(session_triggers_ht,
hash_key_str(session_name, lttng_ht_seed),
&list->session_triggers_ht_node);
cds_list_del(&trigger_list_element->node);
free(trigger_list_element);
}
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
/* Unpublish the list from the session_triggers_ht. */
cds_lfht_del(list->session_triggers_ht, &list->session_triggers_ht_node);
call_rcu(&list->rcu_node, free_session_trigger_list_rcu);
{
int trigger_count = 0;
struct lttng_session_trigger_list *session_trigger_list = nullptr;
- struct lttng_trigger_ht_element *trigger_ht_element = nullptr;
- struct cds_lfht_iter iter;
session_trigger_list =
lttng_session_trigger_list_create(session_name, state->session_triggers_ht);
- {
- /* Add all triggers applying to the session named 'session_name'. */
- lttng::urcu::read_lock_guard read_lock;
-
- cds_lfht_for_each_entry (state->triggers_ht, &iter, trigger_ht_element, node) {
- int ret;
-
- if (!trigger_applies_to_session(trigger_ht_element->trigger,
- session_name)) {
- continue;
- }
-
- ret = lttng_session_trigger_list_add(session_trigger_list,
- trigger_ht_element->trigger);
- if (ret) {
- goto error;
- }
+ for (auto *trigger_ht_element :
+ lttng::urcu::lfht_iteration_adapter<lttng_trigger_ht_element,
+ decltype(lttng_trigger_ht_element::node),
+ <tng_trigger_ht_element::node>(
+ *state->triggers_ht)) {
+ if (!trigger_applies_to_session(trigger_ht_element->trigger, session_name)) {
+ continue;
+ }
- trigger_count++;
+ const auto ret = lttng_session_trigger_list_add(session_trigger_list,
+ trigger_ht_element->trigger);
+ if (ret) {
+ goto error;
}
+
+ trigger_count++;
}
DBG("Found %i triggers that apply to newly created session", trigger_count);
struct session_info *session = nullptr;
struct lttng_session_trigger_list *trigger_list;
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
trigger_list = lttng_session_trigger_list_build(state, name);
if (!trigger_list) {
goto error;
.domain = channel_domain,
};
struct lttng_channel_trigger_list *channel_trigger_list = nullptr;
- struct lttng_trigger_ht_element *trigger_ht_element = nullptr;
int trigger_count = 0;
- struct cds_lfht_iter iter;
struct session_info *session_info = nullptr;
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
DBG("Adding channel: channel name = `%s`, session id = %" PRIu64 ", channel key = %" PRIu64
", domain = %s",
}
/* Build a list of all triggers applying to the new channel. */
- cds_lfht_for_each_entry (state->triggers_ht, &iter, trigger_ht_element, node) {
+ for (auto *trigger_ht_element :
+ lttng::urcu::lfht_iteration_adapter<lttng_trigger_ht_element,
+ decltype(lttng_trigger_ht_element::node),
+ <tng_trigger_ht_element::node>(
+ *state->triggers_ht)) {
struct lttng_trigger_list_element *new_element;
if (!trigger_applies_to_channel(trigger_ht_element->trigger, new_channel_info)) {
channel_key,
lttng_domain_type_str(domain));
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
cds_lfht_lookup(state->channel_triggers_ht,
hash_channel_key(&key),
struct lttng_credentials session_creds;
struct session_state_sample new_session_state;
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
session_info = get_session_info_by_id(state, session_id);
if (!session_info) {
{
int ret = 0;
enum lttng_error_code cmd_result = LTTNG_OK;
- struct cds_lfht_iter iter;
- struct lttng_trigger_ht_element *trigger_ht_element;
struct lttng_triggers *local_triggers = nullptr;
const struct lttng_credentials *creds;
- lttng::urcu::read_lock_guard read_lock;
-
local_triggers = lttng_triggers_create();
if (!local_triggers) {
/* Not a fatal error. */
goto end;
}
- cds_lfht_for_each_entry (state->triggers_ht, &iter, trigger_ht_element, node) {
+ for (auto *trigger_ht_element :
+ lttng::urcu::lfht_iteration_adapter<lttng_trigger_ht_element,
+ decltype(lttng_trigger_ht_element::node),
+ <tng_trigger_ht_element::node>(
+ *state->triggers_ht)) {
/*
* Only return the triggers to which the client has access.
* The root user has visibility over all triggers.
enum lttng_error_code *_cmd_result)
{
int ret = -1;
- struct cds_lfht_iter iter;
- struct lttng_trigger_ht_element *trigger_ht_element;
enum lttng_error_code cmd_result = LTTNG_ERR_TRIGGER_NOT_FOUND;
const char *trigger_name;
uid_t trigger_owner_uid;
- {
- lttng::urcu::read_lock_guard read_lock;
-
- cds_lfht_for_each_entry (state->triggers_ht, &iter, trigger_ht_element, node) {
- if (lttng_trigger_is_equal(trigger, trigger_ht_element->trigger)) {
- /* Take one reference on the return trigger. */
- *registered_trigger = trigger_ht_element->trigger;
- lttng_trigger_get(*registered_trigger);
- ret = 0;
- cmd_result = LTTNG_OK;
- goto end;
- }
+ for (auto *trigger_ht_element :
+ lttng::urcu::lfht_iteration_adapter<lttng_trigger_ht_element,
+ decltype(lttng_trigger_ht_element::node),
+ <tng_trigger_ht_element::node>(
+ *state->triggers_ht)) {
+ if (lttng_trigger_is_equal(trigger, trigger_ht_element->trigger)) {
+ /* Take one reference on the return trigger. */
+ *registered_trigger = trigger_ht_element->trigger;
+ lttng_trigger_get(*registered_trigger);
+ ret = 0;
+ cmd_result = LTTNG_OK;
+ goto end;
}
}
{
int ret = 0;
struct cds_lfht_node *node;
- struct cds_lfht_iter iter;
- struct channel_info *channel;
-
- ASSERT_RCU_READ_LOCKED();
- cds_lfht_for_each_entry (state->channels_ht, &iter, channel, channels_ht_node) {
+ for (auto *channel :
+ lttng::urcu::lfht_iteration_adapter<channel_info,
+ decltype(channel_info::channels_ht_node),
+ &channel_info::channels_ht_node>(
+ *state->channels_ht)) {
struct lttng_trigger_list_element *trigger_list_element;
struct lttng_channel_trigger_list *trigger_list;
struct cds_lfht_iter lookup_iter;
{
bool is_notify = false;
const struct lttng_action *action = lttng_trigger_get_const_action(trigger);
- const struct lttng_action *inner_action;
enum lttng_action_type action_type;
LTTNG_ASSERT(action);
goto end;
}
- for_each_action_const (inner_action, action) {
+ for (auto inner_action : lttng::ctl::const_action_list_view(action)) {
if (lttng_action_get_type(inner_action) == LTTNG_ACTION_TYPE_NOTIFY) {
is_notify = true;
goto end;
enum action_executor_status executor_status;
const uint64_t trigger_tracer_token = state->trigger_id.next_tracer_token++;
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
/* Set the trigger's tracer token. */
lttng_trigger_set_tracer_token(trigger, trigger_tracer_token);
static void teardown_tracer_notifier(struct notification_thread_state *state,
const struct lttng_trigger *trigger)
{
- struct cds_lfht_iter iter;
- struct notification_trigger_tokens_ht_element *trigger_tokens_ht_element;
-
- {
- lttng::urcu::read_lock_guard read_lock;
-
- cds_lfht_for_each_entry (
- state->trigger_tokens_ht, &iter, trigger_tokens_ht_element, node) {
- if (!lttng_trigger_is_equal(trigger, trigger_tokens_ht_element->trigger)) {
- continue;
- }
+ for (auto *trigger_tokens_ht_element : lttng::urcu::lfht_iteration_adapter<
+ notification_trigger_tokens_ht_element,
+ decltype(notification_trigger_tokens_ht_element::node),
+ ¬ification_trigger_tokens_ht_element::node>(*state->trigger_tokens_ht)) {
+ if (!lttng_trigger_is_equal(trigger, trigger_tokens_ht_element->trigger)) {
+ continue;
+ }
- event_notifier_error_accounting_unregister_event_notifier(
- trigger_tokens_ht_element->trigger);
+ event_notifier_error_accounting_unregister_event_notifier(
+ trigger_tokens_ht_element->trigger);
- /* TODO talk to all app and remove it */
- DBG("Removed trigger from tokens_ht");
- cds_lfht_del(state->trigger_tokens_ht, &trigger_tokens_ht_element->node);
+ /* TODO talk to all app and remove it */
+ DBG("Removed trigger from tokens_ht");
+ cds_lfht_del(state->trigger_tokens_ht, &trigger_tokens_ht_element->node);
- call_rcu(&trigger_tokens_ht_element->rcu_node,
- free_notification_trigger_tokens_ht_element_rcu);
+ call_rcu(&trigger_tokens_ht_element->rcu_node,
+ free_notification_trigger_tokens_ht_element_rcu);
- break;
- }
+ break;
}
}
const struct lttng_condition *condition = lttng_trigger_get_const_condition(trigger);
enum lttng_error_code cmd_reply;
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
cds_lfht_lookup(
state->triggers_ht, lttng_condition_hash(condition), match_trigger, trigger, &iter);
switch (get_condition_binding_object(condition)) {
case LTTNG_OBJECT_TYPE_CHANNEL:
{
- struct lttng_channel_trigger_list *trigger_list;
-
/*
* Remove trigger from channel_triggers_ht.
*
*
* Iterate on all lists since we don't know the target channels' keys.
*/
- cds_lfht_for_each_entry (
- state->channel_triggers_ht, &iter, trigger_list, channel_triggers_ht_node) {
+ for (auto *trigger_list : lttng::urcu::lfht_iteration_adapter<
+ lttng_channel_trigger_list,
+ decltype(lttng_channel_trigger_list::channel_triggers_ht_node),
+ <tng_channel_trigger_list::channel_triggers_ht_node>(
+ *state->channel_triggers_ht)) {
struct lttng_trigger_list_element *trigger_element, *tmp;
cds_list_for_each_entry_safe (
return 0;
}
-static int pop_cmd_queue(struct notification_thread_handle *handle,
- struct notification_thread_command **cmd)
+static notification_thread_command *pop_cmd_queue(notification_thread_handle *handle)
{
- int ret;
- uint64_t counter;
+ const lttng::pthread::lock_guard queue_lock(handle->cmd_queue.lock);
- pthread_mutex_lock(&handle->cmd_queue.lock);
- ret = lttng_read(handle->cmd_queue.event_fd, &counter, sizeof(counter));
- if (ret != sizeof(counter)) {
- ret = -1;
- goto error_unlock;
+ uint64_t counter;
+ const auto read_ret = lttng_read(handle->cmd_queue.event_fd, &counter, sizeof(counter));
+ if (read_ret != sizeof(counter)) {
+ if (read_ret < 0) {
+ LTTNG_THROW_POSIX("Failed to read counter value from event_fd", errno);
+ } else {
+ LTTNG_THROW_ERROR(lttng::format(
+ "Failed to read counter value from event_fd because of a truncated read: ret={}, expected read size={}",
+ read_ret,
+ sizeof(counter)));
+ }
}
- *cmd = cds_list_first_entry(
+ auto command = cds_list_first_entry(
&handle->cmd_queue.list, struct notification_thread_command, cmd_list_node);
- cds_list_del(&((*cmd)->cmd_list_node));
- ret = 0;
-
-error_unlock:
- pthread_mutex_unlock(&handle->cmd_queue.lock);
- return ret;
+ cds_list_del(&((command)->cmd_list_node));
+ return command;
}
/* Returns 0 on success, 1 on exit requested, negative value on error. */
struct notification_thread_state *state)
{
int ret;
- struct notification_thread_command *cmd;
+ struct notification_thread_command *cmd = nullptr;
- ret = pop_cmd_queue(handle, &cmd);
- if (ret) {
+ try {
+ cmd = pop_cmd_queue(handle);
+ } catch (const std::exception& ex) {
+ ERR("Failed to get next notification thread command: %s", ex.what());
goto error;
}
cmd->parameters.client_communication_update.id;
struct notification_client *client;
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
client = get_client_from_id(client_id, state);
if (!client) {
if (ret) {
goto error_unlock;
}
+
end:
- if (cmd->is_async) {
- free(cmd);
- cmd = nullptr;
- } else {
- lttng_waiter_wake_up(&cmd->reply_waiter);
+ if (cmd) {
+ if (cmd->is_async) {
+ delete cmd;
+ cmd = nullptr;
+ } else {
+ cmd->command_completed_waker->wake();
+ }
}
+
return ret;
+
error_unlock:
/* Wake-up and return a fatal error to the calling thread. */
- lttng_waiter_wake_up(&cmd->reply_waiter);
cmd->reply_code = LTTNG_ERR_FATAL;
+
error:
- /* Indicate a fatal error to the caller. */
- return -1;
+ ret = -1;
+ goto end;
}
static int socket_set_non_blocking(int socket)
DBG("Added new notification channel client socket (%i) to poll set", client->socket);
{
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
cds_lfht_add(state->client_socket_ht,
hash_client_socket(client->socket),
int ret = 0;
struct notification_client *client;
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
DBG("Closing client connection (socket fd = %i)", client_socket);
client = get_client_from_socket(client_socket, state);
int handle_notification_thread_client_disconnect_all(struct notification_thread_state *state)
{
- struct cds_lfht_iter iter;
- struct notification_client *client;
bool error_encoutered = false;
DBG("Closing all client connections");
- {
- lttng::urcu::read_lock_guard read_lock;
-
- cds_lfht_for_each_entry (
- state->client_socket_ht, &iter, client, client_socket_ht_node) {
- int ret;
+ for (auto *client : lttng::urcu::lfht_iteration_adapter<
+ notification_client,
+ decltype(notification_client::client_socket_ht_node),
+ ¬ification_client::client_socket_ht_node>(*state->client_socket_ht)) {
+ int ret;
- ret = notification_thread_client_disconnect(client, state);
- if (ret) {
- error_encoutered = true;
- }
+ ret = notification_thread_client_disconnect(client, state);
+ if (ret) {
+ error_encoutered = true;
}
}
int handle_notification_thread_trigger_unregister_all(struct notification_thread_state *state)
{
bool error_occurred = false;
- struct cds_lfht_iter iter;
- struct lttng_trigger_ht_element *trigger_ht_element;
- lttng::urcu::read_lock_guard read_lock;
- cds_lfht_for_each_entry (state->triggers_ht, &iter, trigger_ht_element, node) {
- int ret = handle_notification_thread_command_unregister_trigger(
+ for (auto *trigger_ht_element :
+ lttng::urcu::lfht_iteration_adapter<lttng_trigger_ht_element,
+ decltype(lttng_trigger_ht_element::node),
+ <tng_trigger_ht_element::node>(
+ *state->triggers_ht)) {
+ const int ret = handle_notification_thread_command_unregister_trigger(
state, trigger_ht_element->trigger, nullptr);
if (ret) {
error_occurred = true;
}
}
+
return error_occurred ? -1 : 0;
}
ssize_t recv_ret;
size_t offset;
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
client = get_client_from_socket(socket, state);
if (!client) {
/* Internal error, abort. */
struct notification_client *client;
enum client_transmission_status transmission_status;
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
client = get_client_from_socket(socket, state);
if (!client) {
/* Internal error, abort. */
unsigned int capture_count = 0;
/* Find triggers associated with this token. */
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
cds_lfht_lookup(state->trigger_tokens_ht,
hash_key_u64(¬ification->tracer_token, lttng_ht_seed),
match_trigger_token,
struct lttng_credentials channel_creds = {};
struct lttng_credentials session_creds = {};
struct session_info *session;
- lttng::urcu::read_lock_guard read_lock;
+ const lttng::urcu::read_lock_guard read_lock;
/*
* The monitoring pipe only holds messages smaller than PIPE_BUF,