2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
9 #include <common/credentials.h>
10 #include <common/dynamic-array.h>
11 #include <common/error.h>
12 #include <common/optional.h>
13 #include <common/payload-view.h>
14 #include <common/payload.h>
16 #include <lttng/action/action-internal.h>
17 #include <lttng/condition/buffer-usage.h>
18 #include <lttng/condition/condition-internal.h>
19 #include <lttng/condition/event-rule-matches-internal.h>
20 #include <lttng/condition/event-rule-matches.h>
21 #include <lttng/domain.h>
22 #include <lttng/event-expr-internal.h>
23 #include <lttng/event-rule/event-rule-internal.h>
24 #include <lttng/trigger/trigger-internal.h>
28 bool lttng_trigger_validate(const struct lttng_trigger
*trigger
)
37 if (!trigger
->creds
.uid
.is_set
) {
42 valid
= lttng_condition_validate(trigger
->condition
) &&
43 lttng_action_validate(trigger
->action
);
48 struct lttng_trigger
*lttng_trigger_create(
49 struct lttng_condition
*condition
,
50 struct lttng_action
*action
)
52 struct lttng_trigger
*trigger
= NULL
;
54 if (!condition
|| !action
) {
58 trigger
= zmalloc(sizeof(struct lttng_trigger
));
63 urcu_ref_init(&trigger
->ref
);
65 lttng_condition_get(condition
);
66 trigger
->condition
= condition
;
68 lttng_action_get(action
);
69 trigger
->action
= action
;
71 pthread_mutex_init(&trigger
->lock
, NULL
);
72 trigger
->registered
= false;
79 * Note: the lack of reference counting 'get' on the condition object is normal.
80 * This API was exposed as such in 2.11. The client is not expected to call
81 * lttng_condition_destroy on the returned object.
83 struct lttng_condition
*lttng_trigger_get_condition(
84 struct lttng_trigger
*trigger
)
86 return trigger
? trigger
->condition
: NULL
;
89 const struct lttng_condition
*lttng_trigger_get_const_condition(
90 const struct lttng_trigger
*trigger
)
92 return trigger
? trigger
->condition
: NULL
;
96 * Note: the lack of reference counting 'get' on the action object is normal.
97 * This API was exposed as such in 2.11. The client is not expected to call
98 * lttng_action_destroy on the returned object.
100 struct lttng_action
*lttng_trigger_get_action(
101 struct lttng_trigger
*trigger
)
103 return trigger
? trigger
->action
: NULL
;
106 const struct lttng_action
*lttng_trigger_get_const_action(
107 const struct lttng_trigger
*trigger
)
109 return trigger
? trigger
->action
: NULL
;
112 static void trigger_destroy_ref(struct urcu_ref
*ref
)
114 struct lttng_trigger
*trigger
=
115 container_of(ref
, struct lttng_trigger
, ref
);
116 struct lttng_action
*action
= lttng_trigger_get_action(trigger
);
117 struct lttng_condition
*condition
=
118 lttng_trigger_get_condition(trigger
);
123 /* Release ownership. */
124 lttng_action_put(action
);
125 lttng_condition_put(condition
);
127 pthread_mutex_destroy(&trigger
->lock
);
133 void lttng_trigger_destroy(struct lttng_trigger
*trigger
)
135 lttng_trigger_put(trigger
);
139 ssize_t
lttng_trigger_create_from_payload(
140 struct lttng_payload_view
*src_view
,
141 struct lttng_trigger
**_trigger
)
143 ssize_t ret
, offset
= 0, condition_size
, action_size
, name_size
= 0;
144 struct lttng_condition
*condition
= NULL
;
145 struct lttng_action
*action
= NULL
;
146 const struct lttng_trigger_comm
*trigger_comm
;
147 const char *name
= NULL
;
148 struct lttng_credentials creds
= {
149 .uid
= LTTNG_OPTIONAL_INIT_UNSET
,
150 .gid
= LTTNG_OPTIONAL_INIT_UNSET
,
152 struct lttng_trigger
*trigger
= NULL
;
153 const struct lttng_payload_view trigger_comm_view
=
154 lttng_payload_view_from_view(
155 src_view
, 0, sizeof(*trigger_comm
));
157 if (!src_view
|| !_trigger
) {
162 if (!lttng_payload_view_is_valid(&trigger_comm_view
)) {
163 /* Payload not large enough to contain the header. */
168 /* lttng_trigger_comm header */
169 trigger_comm
= (typeof(trigger_comm
)) trigger_comm_view
.buffer
.data
;
171 /* Set the trigger's creds. */
172 if (trigger_comm
->uid
> (uint64_t) ((uid_t
) -1)) {
173 /* UID out of range for this platform. */
178 LTTNG_OPTIONAL_SET(&creds
.uid
, trigger_comm
->uid
);
180 offset
+= sizeof(*trigger_comm
);
182 if (trigger_comm
->name_length
!= 0) {
184 const struct lttng_payload_view name_view
=
185 lttng_payload_view_from_view(
187 trigger_comm
->name_length
);
189 if (!lttng_payload_view_is_valid(&name_view
)) {
194 name
= name_view
.buffer
.data
;
195 if (!lttng_buffer_view_contains_string(&name_view
.buffer
, name
,
196 trigger_comm
->name_length
)) {
201 offset
+= trigger_comm
->name_length
;
202 name_size
= trigger_comm
->name_length
;
206 /* struct lttng_condition */
207 struct lttng_payload_view condition_view
=
208 lttng_payload_view_from_view(
209 src_view
, offset
, -1);
211 condition_size
= lttng_condition_create_from_payload(&condition_view
,
215 if (condition_size
< 0) {
216 ret
= condition_size
;
220 offset
+= condition_size
;
222 /* struct lttng_action */
223 struct lttng_payload_view action_view
=
224 lttng_payload_view_from_view(
225 src_view
, offset
, -1);
227 action_size
= lttng_action_create_from_payload(&action_view
, &action
);
230 if (action_size
< 0) {
234 offset
+= action_size
;
236 /* Unexpected size of inner-elements; the buffer is corrupted. */
237 if ((ssize_t
) trigger_comm
->length
!= condition_size
+ action_size
+ name_size
) {
242 trigger
= lttng_trigger_create(condition
, action
);
248 lttng_trigger_set_credentials(trigger
, &creds
);
251 * The trigger object owns references to the action and condition
254 lttng_condition_put(condition
);
257 lttng_action_put(action
);
261 const enum lttng_trigger_status status
=
262 lttng_trigger_set_name(trigger
, name
);
264 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
273 lttng_condition_put(condition
);
274 lttng_action_put(action
);
279 lttng_trigger_put(trigger
);
286 * Both elements are stored contiguously, see their "*_comm" structure
287 * for the detailed format.
290 int lttng_trigger_serialize(const struct lttng_trigger
*trigger
,
291 struct lttng_payload
*payload
)
294 size_t header_offset
, size_before_payload
, size_name
;
295 struct lttng_trigger_comm trigger_comm
= {};
296 struct lttng_trigger_comm
*header
;
297 const struct lttng_credentials
*creds
= NULL
;
299 creds
= lttng_trigger_get_credentials(trigger
);
302 trigger_comm
.uid
= LTTNG_OPTIONAL_GET(creds
->uid
);
304 if (trigger
->name
!= NULL
) {
305 size_name
= strlen(trigger
->name
) + 1;
310 trigger_comm
.name_length
= size_name
;
312 header_offset
= payload
->buffer
.size
;
313 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &trigger_comm
,
314 sizeof(trigger_comm
));
319 size_before_payload
= payload
->buffer
.size
;
322 ret
= lttng_dynamic_buffer_append(
323 &payload
->buffer
, trigger
->name
, size_name
);
328 ret
= lttng_condition_serialize(trigger
->condition
, payload
);
333 ret
= lttng_action_serialize(trigger
->action
, payload
);
338 /* Update payload size. */
339 header
= (typeof(header
)) (payload
->buffer
.data
+ header_offset
);
340 header
->length
= payload
->buffer
.size
- size_before_payload
;
346 bool lttng_trigger_is_equal(
347 const struct lttng_trigger
*a
, const struct lttng_trigger
*b
)
349 if (!!a
->name
!= !!b
->name
) {
350 /* Both must be either anonymous or named. */
354 if (a
->name
&& strcmp(a
->name
, b
->name
) != 0) {
358 if (!lttng_condition_is_equal(a
->condition
, b
->condition
)) {
362 if (!lttng_action_is_equal(a
->action
, b
->action
)) {
366 if (!lttng_credentials_is_equal(lttng_trigger_get_credentials(a
),
367 lttng_trigger_get_credentials(b
))) {
374 enum lttng_trigger_status
lttng_trigger_set_name(struct lttng_trigger
*trigger
,
377 char *name_copy
= NULL
;
378 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
380 if (!trigger
|| !name
||
382 status
= LTTNG_TRIGGER_STATUS_INVALID
;
386 name_copy
= strdup(name
);
388 status
= LTTNG_TRIGGER_STATUS_ERROR
;
394 trigger
->name
= name_copy
;
400 enum lttng_trigger_status
lttng_trigger_get_name(
401 const struct lttng_trigger
*trigger
, const char **name
)
403 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
405 if (!trigger
|| !name
) {
406 status
= LTTNG_TRIGGER_STATUS_INVALID
;
410 if (!trigger
->name
) {
411 status
= LTTNG_TRIGGER_STATUS_UNSET
;
414 *name
= trigger
->name
;
420 int lttng_trigger_assign_name(struct lttng_trigger
*dst
,
421 const struct lttng_trigger
*src
)
424 enum lttng_trigger_status status
;
426 status
= lttng_trigger_set_name(dst
, src
->name
);
427 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
429 ERR("Failed to set name for trigger");
437 void lttng_trigger_set_tracer_token(struct lttng_trigger
*trigger
,
441 LTTNG_OPTIONAL_SET(&trigger
->tracer_token
, token
);
445 uint64_t lttng_trigger_get_tracer_token(const struct lttng_trigger
*trigger
)
449 return LTTNG_OPTIONAL_GET(trigger
->tracer_token
);
453 int lttng_trigger_generate_name(struct lttng_trigger
*trigger
,
457 char *generated_name
= NULL
;
459 ret
= asprintf(&generated_name
, "T%" PRIu64
"", unique_id
);
461 ERR("Failed to generate trigger name");
468 trigger
->name
= generated_name
;
474 void lttng_trigger_get(struct lttng_trigger
*trigger
)
476 urcu_ref_get(&trigger
->ref
);
480 void lttng_trigger_put(struct lttng_trigger
*trigger
)
486 urcu_ref_put(&trigger
->ref
, trigger_destroy_ref
);
489 static void delete_trigger_array_element(void *ptr
)
491 struct lttng_trigger
*trigger
= ptr
;
493 lttng_trigger_put(trigger
);
497 struct lttng_triggers
*lttng_triggers_create(void)
499 struct lttng_triggers
*triggers
= NULL
;
501 triggers
= zmalloc(sizeof(*triggers
));
506 lttng_dynamic_pointer_array_init(&triggers
->array
, delete_trigger_array_element
);
513 struct lttng_trigger
*lttng_triggers_borrow_mutable_at_index(
514 const struct lttng_triggers
*triggers
, unsigned int index
)
516 struct lttng_trigger
*trigger
= NULL
;
519 if (index
>= lttng_dynamic_pointer_array_get_count(&triggers
->array
)) {
523 trigger
= (struct lttng_trigger
*)
524 lttng_dynamic_pointer_array_get_pointer(
525 &triggers
->array
, index
);
531 int lttng_triggers_add(
532 struct lttng_triggers
*triggers
, struct lttng_trigger
*trigger
)
539 lttng_trigger_get(trigger
);
541 ret
= lttng_dynamic_pointer_array_add_pointer(&triggers
->array
, trigger
);
543 lttng_trigger_put(trigger
);
549 const struct lttng_trigger
*lttng_triggers_get_at_index(
550 const struct lttng_triggers
*triggers
, unsigned int index
)
552 return lttng_triggers_borrow_mutable_at_index(triggers
, index
);
555 enum lttng_trigger_status
lttng_triggers_get_count(const struct lttng_triggers
*triggers
, unsigned int *count
)
557 enum lttng_trigger_status status
= LTTNG_TRIGGER_STATUS_OK
;
559 if (!triggers
|| !count
) {
560 status
= LTTNG_TRIGGER_STATUS_INVALID
;
564 *count
= lttng_dynamic_pointer_array_get_count(&triggers
->array
);
569 void lttng_triggers_destroy(struct lttng_triggers
*triggers
)
575 lttng_dynamic_pointer_array_reset(&triggers
->array
);
579 int lttng_triggers_serialize(const struct lttng_triggers
*triggers
,
580 struct lttng_payload
*payload
)
583 unsigned int i
, count
;
584 size_t size_before_payload
;
585 struct lttng_triggers_comm triggers_comm
= {};
586 struct lttng_triggers_comm
*header
;
587 enum lttng_trigger_status status
;
588 const size_t header_offset
= payload
->buffer
.size
;
590 status
= lttng_triggers_get_count(triggers
, &count
);
591 if (status
!= LTTNG_TRIGGER_STATUS_OK
) {
592 ret
= LTTNG_ERR_INVALID
;
596 triggers_comm
.count
= count
;
598 /* Placeholder header; updated at the end. */
599 ret
= lttng_dynamic_buffer_append(&payload
->buffer
, &triggers_comm
,
600 sizeof(triggers_comm
));
605 size_before_payload
= payload
->buffer
.size
;
607 for (i
= 0; i
< count
; i
++) {
608 const struct lttng_trigger
*trigger
=
609 lttng_triggers_get_at_index(triggers
, i
);
613 ret
= lttng_trigger_serialize(trigger
, payload
);
619 /* Update payload size. */
620 header
= (struct lttng_triggers_comm
*) ((char *) payload
->buffer
.data
+ header_offset
);
621 header
->length
= payload
->buffer
.size
- size_before_payload
;
627 ssize_t
lttng_triggers_create_from_payload(
628 struct lttng_payload_view
*src_view
,
629 struct lttng_triggers
**triggers
)
631 ssize_t ret
, offset
= 0, triggers_size
= 0;
633 const struct lttng_triggers_comm
*triggers_comm
;
634 struct lttng_triggers
*local_triggers
= NULL
;
636 if (!src_view
|| !triggers
) {
641 /* lttng_trigger_comms header */
642 triggers_comm
= (const struct lttng_triggers_comm
*) src_view
->buffer
.data
;
643 offset
+= sizeof(*triggers_comm
);
645 local_triggers
= lttng_triggers_create();
646 if (!local_triggers
) {
651 for (i
= 0; i
< triggers_comm
->count
; i
++) {
652 struct lttng_trigger
*trigger
= NULL
;
653 struct lttng_payload_view trigger_view
=
654 lttng_payload_view_from_view(src_view
, offset
, -1);
655 ssize_t trigger_size
;
657 trigger_size
= lttng_trigger_create_from_payload(
658 &trigger_view
, &trigger
);
659 if (trigger_size
< 0) {
664 /* Transfer ownership of the trigger to the collection. */
665 ret
= lttng_triggers_add(local_triggers
, trigger
);
666 lttng_trigger_put(trigger
);
672 offset
+= trigger_size
;
673 triggers_size
+= trigger_size
;
676 /* Unexpected size of inner-elements; the buffer is corrupted. */
677 if ((ssize_t
) triggers_comm
->length
!= triggers_size
) {
682 /* Pass ownership to caller. */
683 *triggers
= local_triggers
;
684 local_triggers
= NULL
;
689 lttng_triggers_destroy(local_triggers
);
694 const struct lttng_credentials
*lttng_trigger_get_credentials(
695 const struct lttng_trigger
*trigger
)
697 return &trigger
->creds
;
701 void lttng_trigger_set_credentials(struct lttng_trigger
*trigger
,
702 const struct lttng_credentials
*creds
)
705 trigger
->creds
= *creds
;
708 enum lttng_trigger_status
lttng_trigger_set_owner_uid(
709 struct lttng_trigger
*trigger
, uid_t uid
)
711 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
712 const uid_t euid
= geteuid();
713 const struct lttng_credentials creds
= {
714 .uid
= LTTNG_OPTIONAL_INIT_VALUE(uid
),
715 .gid
= LTTNG_OPTIONAL_INIT_UNSET
,
719 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
723 /* Client-side validation only to report a clearer error. */
724 if (euid
!= 0 && euid
!= uid
) {
725 ret
= LTTNG_TRIGGER_STATUS_PERMISSION_DENIED
;
729 lttng_trigger_set_credentials(trigger
, &creds
);
735 enum lttng_trigger_status
lttng_trigger_get_owner_uid(
736 const struct lttng_trigger
*trigger
, uid_t
*uid
)
738 enum lttng_trigger_status ret
= LTTNG_TRIGGER_STATUS_OK
;
739 const struct lttng_credentials
*creds
= NULL
;
741 if (!trigger
|| !uid
) {
742 ret
= LTTNG_TRIGGER_STATUS_INVALID
;
746 if (!trigger
->creds
.uid
.is_set
) {
747 ret
= LTTNG_TRIGGER_STATUS_UNSET
;
751 creds
= lttng_trigger_get_credentials(trigger
);
752 *uid
= lttng_credentials_get_uid(creds
);
759 enum lttng_domain_type
lttng_trigger_get_underlying_domain_type_restriction(
760 const struct lttng_trigger
*trigger
)
762 enum lttng_domain_type type
= LTTNG_DOMAIN_NONE
;
763 const struct lttng_event_rule
*event_rule
;
764 enum lttng_condition_status c_status
;
765 enum lttng_condition_type c_type
;
768 assert(trigger
->condition
);
770 c_type
= lttng_condition_get_type(trigger
->condition
);
771 assert (c_type
!= LTTNG_CONDITION_TYPE_UNKNOWN
);
774 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
:
775 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
776 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
777 /* Apply to any domain. */
778 type
= LTTNG_DOMAIN_NONE
;
780 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
:
781 /* Return the domain of the event rule. */
782 c_status
= lttng_condition_event_rule_matches_get_rule(
783 trigger
->condition
, &event_rule
);
784 assert(c_status
== LTTNG_CONDITION_STATUS_OK
);
785 type
= lttng_event_rule_get_domain_type(event_rule
);
787 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
788 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
789 /* Return the domain of the channel being monitored. */
790 c_status
= lttng_condition_buffer_usage_get_domain_type(
791 trigger
->condition
, &type
);
792 assert(c_status
== LTTNG_CONDITION_STATUS_OK
);
802 * Generate bytecode related to the trigger.
803 * On success LTTNG_OK. On error, returns lttng_error code.
806 enum lttng_error_code
lttng_trigger_generate_bytecode(
807 struct lttng_trigger
*trigger
,
808 const struct lttng_credentials
*creds
)
810 enum lttng_error_code ret
;
811 struct lttng_condition
*condition
= NULL
;
813 condition
= lttng_trigger_get_condition(trigger
);
815 ret
= LTTNG_ERR_INVALID_TRIGGER
;
819 switch (lttng_condition_get_type(condition
)) {
820 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
:
822 struct lttng_event_rule
*event_rule
;
823 const enum lttng_condition_status condition_status
=
824 lttng_condition_event_rule_matches_borrow_rule_mutable(
825 condition
, &event_rule
);
827 assert(condition_status
== LTTNG_CONDITION_STATUS_OK
);
829 /* Generate the filter bytecode. */
830 ret
= lttng_event_rule_generate_filter_bytecode(
832 if (ret
!= LTTNG_OK
) {
836 /* Generate the capture bytecode. */
837 ret
= lttng_condition_event_rule_matches_generate_capture_descriptor_bytecode(
839 if (ret
!= LTTNG_OK
) {
855 struct lttng_trigger
*lttng_trigger_copy(const struct lttng_trigger
*trigger
)
858 struct lttng_payload copy_buffer
;
859 struct lttng_condition
*condition_copy
= NULL
;
860 struct lttng_action
*action_copy
= NULL
;
861 struct lttng_trigger
*copy
= NULL
;
862 enum lttng_trigger_status trigger_status
;
863 const char *trigger_name
;
864 uid_t trigger_owner_uid
;
866 lttng_payload_init(©_buffer
);
868 ret
= lttng_condition_serialize(trigger
->condition
, ©_buffer
);
874 struct lttng_payload_view view
=
875 lttng_payload_view_from_payload(
876 ©_buffer
, 0, -1);
878 ret
= lttng_condition_create_from_payload(
879 &view
, &condition_copy
);
885 lttng_payload_clear(©_buffer
);
887 ret
= lttng_action_serialize(trigger
->action
, ©_buffer
);
893 struct lttng_payload_view view
=
894 lttng_payload_view_from_payload(
895 ©_buffer
, 0, -1);
897 ret
= lttng_action_create_from_payload(
898 &view
, &action_copy
);
904 copy
= lttng_trigger_create(condition_copy
, action_copy
);
906 ERR("Failed to allocate trigger during trigger copy");
910 trigger_status
= lttng_trigger_get_name(trigger
, &trigger_name
);
911 switch (trigger_status
) {
912 case LTTNG_TRIGGER_STATUS_OK
:
913 trigger_status
= lttng_trigger_set_name(copy
, trigger_name
);
914 if (trigger_status
!= LTTNG_TRIGGER_STATUS_OK
) {
915 ERR("Failed to set name of new trigger during copy");
916 goto error_cleanup_trigger
;
919 case LTTNG_TRIGGER_STATUS_UNSET
:
922 ERR("Failed to get name of original trigger during copy");
923 goto error_cleanup_trigger
;
926 trigger_status
= lttng_trigger_get_owner_uid(
927 trigger
, &trigger_owner_uid
);
928 switch (trigger_status
) {
929 case LTTNG_TRIGGER_STATUS_OK
:
930 LTTNG_OPTIONAL_SET(©
->creds
.uid
, trigger_owner_uid
);
932 case LTTNG_TRIGGER_STATUS_UNSET
:
935 ERR("Failed to get owner uid of original trigger during copy");
936 goto error_cleanup_trigger
;
939 copy
->tracer_token
= trigger
->tracer_token
;
940 copy
->registered
= trigger
->registered
;
943 error_cleanup_trigger
:
944 lttng_trigger_destroy(copy
);
947 lttng_condition_put(condition_copy
);
948 lttng_action_put(action_copy
);
949 lttng_payload_reset(©_buffer
);
954 bool lttng_trigger_needs_tracer_notifier(const struct lttng_trigger
*trigger
)
956 bool needs_tracer_notifier
= false;
957 const struct lttng_condition
*condition
=
958 lttng_trigger_get_const_condition(trigger
);
960 switch (lttng_condition_get_type(condition
)) {
961 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
:
962 needs_tracer_notifier
= true;
964 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
:
965 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
966 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
967 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
968 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
970 case LTTNG_CONDITION_TYPE_UNKNOWN
:
975 return needs_tracer_notifier
;
979 void lttng_trigger_set_as_registered(struct lttng_trigger
*trigger
)
981 pthread_mutex_lock(&trigger
->lock
);
982 trigger
->registered
= true;
983 pthread_mutex_unlock(&trigger
->lock
);
987 void lttng_trigger_set_as_unregistered(struct lttng_trigger
*trigger
)
989 pthread_mutex_lock(&trigger
->lock
);
990 trigger
->registered
= false;
991 pthread_mutex_unlock(&trigger
->lock
);
995 * The trigger must be locked before calling lttng_trigger_registered.
996 * The lock is necessary since a trigger can be unregistered at anytime.
997 * Manipulations requiring that the trigger be registered must always acquire
998 * the trigger lock for the duration of the manipulation using
999 * `lttng_trigger_lock` and `lttng_trigger_unlock`.
1002 bool lttng_trigger_is_registered(struct lttng_trigger
*trigger
)
1004 ASSERT_LOCKED(trigger
->lock
);
1005 return trigger
->registered
;
1009 void lttng_trigger_lock(struct lttng_trigger
*trigger
)
1011 pthread_mutex_lock(&trigger
->lock
);
1015 void lttng_trigger_unlock(struct lttng_trigger
*trigger
)
1017 pthread_mutex_unlock(&trigger
->lock
);