#include <assert.h>
#include <common/error.h>
+#include <common/event-expr-to-bytecode.h>
#include <common/macros.h>
#include <inttypes.h>
#include <lttng/condition/condition-internal.h>
+#include <lttng/event-rule/event-rule-internal.h>
#include <lttng/condition/event-rule-internal.h>
#include <lttng/condition/event-rule.h>
#include <lttng/event-expr-internal.h>
#include <lttng/event-expr.h>
-#include <lttng/event-rule/event-rule-internal.h>
+#include <lttng/lttng-error.h>
#include <stdbool.h>
#include <stdint.h>
+#include <vendor/msgpack/msgpack.h>
#define IS_EVENT_RULE_CONDITION(condition) \
(lttng_condition_get_type(condition) == \
return ret;
}
+static
+struct lttng_capture_descriptor *
+lttng_condition_event_rule_get_internal_capture_descriptor_at_index(
+ const struct lttng_condition *condition, unsigned int index)
+{
+ const struct lttng_condition_event_rule *event_rule_cond =
+ container_of(condition,
+ const struct lttng_condition_event_rule,
+ parent);
+ struct lttng_capture_descriptor *desc = NULL;
+ unsigned int count;
+ enum lttng_condition_status status;
+
+ if (!condition || !IS_EVENT_RULE_CONDITION(condition)) {
+ goto end;
+ }
+
+ status = lttng_condition_event_rule_get_capture_descriptor_count(
+ condition, &count);
+ if (status != LTTNG_CONDITION_STATUS_OK) {
+ goto end;
+ }
+
+ if (index >= count) {
+ goto end;
+ }
+
+ desc = lttng_dynamic_pointer_array_get_pointer(
+ &event_rule_cond->capture_descriptors, index);
+end:
+ return desc;
+}
+
static int lttng_condition_event_rule_serialize(
const struct lttng_condition *condition,
struct lttng_payload *payload)
{
int ret;
struct lttng_condition_event_rule *event_rule;
+ enum lttng_condition_status status;
/* Used for iteration and communication (size matters). */
uint32_t i, capture_descr_count;
goto end;
}
- capture_descr_count = lttng_dynamic_pointer_array_get_count(
- &event_rule->capture_descriptors);
+ status = lttng_condition_event_rule_get_capture_descriptor_count(
+ condition, &capture_descr_count);
+ if (status != LTTNG_CONDITION_STATUS_OK) {
+ ret = -1;
+ goto end;
+ };
+
DBG("Serializing event rule condition's capture descriptor count: %" PRIu32,
capture_descr_count);
ret = lttng_dynamic_buffer_append(&payload->buffer, &capture_descr_count,
}
for (i = 0; i < capture_descr_count; i++) {
- const struct lttng_event_expr *expr =
- lttng_dynamic_pointer_array_get_pointer(
- &event_rule->capture_descriptors, i);
+ const struct lttng_capture_descriptor *desc =
+ lttng_condition_event_rule_get_internal_capture_descriptor_at_index(
+ condition, i);
DBG("Serializing event rule condition's capture descriptor %" PRIu32,
i);
- ret = serialize_event_expr(expr, payload);
+ ret = serialize_event_expr(desc->event_expression, payload);
if (ret) {
goto end;
}
static
bool capture_descriptors_are_equal(
- const struct lttng_condition_event_rule *condition_a,
- const struct lttng_condition_event_rule *condition_b)
+ const struct lttng_condition *condition_a,
+ const struct lttng_condition *condition_b)
{
bool is_equal = true;
- size_t capture_descr_count_a;
- size_t capture_descr_count_b;
+ unsigned int capture_descr_count_a;
+ unsigned int capture_descr_count_b;
size_t i;
+ enum lttng_condition_status status;
+
+ status = lttng_condition_event_rule_get_capture_descriptor_count(
+ condition_a, &capture_descr_count_a);
+ if (status != LTTNG_CONDITION_STATUS_OK) {
+ goto not_equal;
+ }
- capture_descr_count_a = lttng_dynamic_pointer_array_get_count(
- &condition_a->capture_descriptors);
- capture_descr_count_b = lttng_dynamic_pointer_array_get_count(
- &condition_b->capture_descriptors);
+ status = lttng_condition_event_rule_get_capture_descriptor_count(
+ condition_b, &capture_descr_count_b);
+ if (status != LTTNG_CONDITION_STATUS_OK) {
+ goto not_equal;
+ }
if (capture_descr_count_a != capture_descr_count_b) {
goto not_equal;
for (i = 0; i < capture_descr_count_a; i++) {
const struct lttng_event_expr *expr_a =
- lttng_dynamic_pointer_array_get_pointer(
- &condition_a->capture_descriptors,
+ lttng_condition_event_rule_get_capture_descriptor_at_index(
+ condition_a,
i);
const struct lttng_event_expr *expr_b =
- lttng_dynamic_pointer_array_get_pointer(
- &condition_b->capture_descriptors,
+ lttng_condition_event_rule_get_capture_descriptor_at_index(
+ condition_b,
i);
if (!lttng_event_expr_is_equal(expr_a, expr_b)) {
goto end;
}
- is_equal = capture_descriptors_are_equal(a, b);
+ is_equal = capture_descriptors_are_equal(_a, _b);
end:
return is_equal;
}
static
-void destroy_event_expr(void *ptr)
+void destroy_capture_descriptor(void *ptr)
{
- lttng_event_expr_destroy(ptr);
+ struct lttng_capture_descriptor *desc =
+ (struct lttng_capture_descriptor *) ptr;
+
+ lttng_event_expr_destroy(desc->event_expression);
+ free(desc->bytecode);
+ free(desc);
}
struct lttng_condition *lttng_condition_event_rule_create(
rule = NULL;
lttng_dynamic_pointer_array_init(&condition->capture_descriptors,
- destroy_event_expr);
+ destroy_capture_descriptor);
parent = &condition->parent;
end:
/* Capture descriptors. */
for (i = 0; i < capture_descr_count; i++) {
+ enum lttng_condition_status status;
struct lttng_event_expr *expr = event_expr_from_payload(
view, &offset);
- enum lttng_condition_status status;
if (!expr) {
goto error;
struct lttng_condition_event_rule *event_rule_cond =
container_of(condition,
struct lttng_condition_event_rule, parent);
+ struct lttng_capture_descriptor *descriptor = NULL;
/* Only accept l-values. */
if (!condition || !IS_EVENT_RULE_CONDITION(condition) || !expr ||
goto end;
}
+ descriptor = malloc(sizeof(*descriptor));
+ if (descriptor == NULL) {
+ status = LTTNG_CONDITION_STATUS_ERROR;
+ goto end;
+ }
+
+ descriptor->event_expression = expr;
+ descriptor->bytecode = NULL;
+
ret = lttng_dynamic_pointer_array_add_pointer(
- &event_rule_cond->capture_descriptors, expr);
+ &event_rule_cond->capture_descriptors, descriptor);
if (ret) {
status = LTTNG_CONDITION_STATUS_ERROR;
goto end;
}
+ /* Ownership is transfered to the internal capture_descriptors array */
+ descriptor = NULL;
end:
+ free(descriptor);
return status;
}
lttng_condition_event_rule_get_capture_descriptor_at_index(
const struct lttng_condition *condition, unsigned int index)
{
- const struct lttng_condition_event_rule *event_rule_cond =
- container_of(condition,
- const struct lttng_condition_event_rule,
- parent);
const struct lttng_event_expr *expr = NULL;
+ const struct lttng_capture_descriptor *desc = NULL;
- if (!condition || !IS_EVENT_RULE_CONDITION(condition) ||
- index >= lttng_dynamic_pointer_array_get_count(
- &event_rule_cond->capture_descriptors)) {
+ desc = lttng_condition_event_rule_get_internal_capture_descriptor_at_index(
+ condition, index);
+ if (desc == NULL) {
goto end;
}
-
- expr = lttng_dynamic_pointer_array_get_pointer(
- &event_rule_cond->capture_descriptors, index);
+ expr = desc->event_expression;
end:
return expr;
end:
return status;
}
+
+LTTNG_HIDDEN
+enum lttng_error_code
+lttng_condition_event_rule_generate_capture_descriptor_bytecode(
+ struct lttng_condition *condition)
+{
+ enum lttng_error_code ret;
+ enum lttng_condition_status status;
+ unsigned int capture_count, i;
+
+ if (!condition || !IS_EVENT_RULE_CONDITION(condition)) {
+ ret = LTTNG_ERR_FATAL;
+ goto end;
+ }
+
+ status = lttng_condition_event_rule_get_capture_descriptor_count(
+ condition, &capture_count);
+ if (status != LTTNG_CONDITION_STATUS_OK) {
+ ret = LTTNG_ERR_FATAL;
+ goto end;
+ }
+
+ for (i = 0; i < capture_count; i++) {
+ struct lttng_capture_descriptor *local_capture_desc =
+ lttng_condition_event_rule_get_internal_capture_descriptor_at_index(
+ condition, i);
+
+ if (local_capture_desc == NULL) {
+ ret = LTTNG_ERR_FATAL;
+ goto end;
+ }
+
+ /* Generate the bytecode. */
+ status = lttng_event_expr_to_bytecode(
+ local_capture_desc->event_expression,
+ &local_capture_desc->bytecode);
+ if (status < 0 || local_capture_desc->bytecode == NULL) {
+ ret = LTTNG_ERR_INVALID_CAPTURE_EXPRESSION;
+ goto end;
+ }
+ }
+
+ /* Everything went better than expected */
+ ret = LTTNG_OK;
+
+end:
+ return ret;
+}
+
+LTTNG_HIDDEN
+const struct lttng_bytecode *
+lttng_condition_event_rule_get_capture_bytecode_at_index(
+ const struct lttng_condition *condition, unsigned int index)
+{
+ const struct lttng_condition_event_rule *event_rule_cond =
+ container_of(condition,
+ const struct lttng_condition_event_rule,
+ parent);
+ struct lttng_capture_descriptor *desc = NULL;
+ struct lttng_bytecode *bytecode = NULL;
+ unsigned int count;
+ enum lttng_condition_status status;
+
+ if (!condition || !IS_EVENT_RULE_CONDITION(condition)) {
+ goto end;
+ }
+
+ status = lttng_condition_event_rule_get_capture_descriptor_count(
+ condition, &count);
+ if (status != LTTNG_CONDITION_STATUS_OK) {
+ goto end;
+ }
+
+ if (index >= count) {
+ goto end;
+ }
+
+ desc = lttng_dynamic_pointer_array_get_pointer(
+ &event_rule_cond->capture_descriptors, index);
+ if (desc == NULL) {
+ goto end;
+ }
+
+ bytecode = desc->bytecode;
+end:
+ return bytecode;
+}