2 * event-notifier-notification.c
4 * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; only
9 * version 2.1 of the License.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 #include <lttng/ust-events.h>
27 #include <usterr-signal-safe.h>
29 #include "../libmsgpack/msgpack.h"
30 #include "lttng-bytecode.h"
34 void capture_enum(struct lttng_msgpack_writer
*writer
,
35 struct lttng_interpreter_output
*output
) __attribute__ ((unused
));
37 void capture_enum(struct lttng_msgpack_writer
*writer
,
38 struct lttng_interpreter_output
*output
)
40 lttng_msgpack_begin_map(writer
, 2);
41 lttng_msgpack_write_str(writer
, "type");
42 lttng_msgpack_write_str(writer
, "enum");
44 lttng_msgpack_write_str(writer
, "value");
46 switch (output
->type
) {
47 case LTTNG_INTERPRETER_TYPE_SIGNED_ENUM
:
48 lttng_msgpack_write_signed_integer(writer
, output
->u
.s
);
50 case LTTNG_INTERPRETER_TYPE_UNSIGNED_ENUM
:
51 lttng_msgpack_write_signed_integer(writer
, output
->u
.u
);
57 lttng_msgpack_end_map(writer
);
61 int64_t capture_sequence_element_signed(uint8_t *ptr
,
62 const struct lttng_integer_type
*type
)
65 unsigned int size
= type
->size
;
66 bool byte_order_reversed
= type
->reverse_byte_order
;
75 tmp
= *(int16_t *) ptr
;
76 if (byte_order_reversed
)
85 tmp
= *(int32_t *) ptr
;
86 if (byte_order_reversed
)
95 tmp
= *(int64_t *) ptr
;
96 if (byte_order_reversed
)
110 uint64_t capture_sequence_element_unsigned(uint8_t *ptr
,
111 const struct lttng_integer_type
*type
)
114 unsigned int size
= type
->size
;
115 bool byte_order_reversed
= type
->reverse_byte_order
;
124 tmp
= *(uint16_t *) ptr
;
125 if (byte_order_reversed
)
134 tmp
= *(uint32_t *) ptr
;
135 if (byte_order_reversed
)
144 tmp
= *(uint64_t *) ptr
;
145 if (byte_order_reversed
)
159 void capture_sequence(struct lttng_msgpack_writer
*writer
,
160 struct lttng_interpreter_output
*output
) __attribute__ ((unused
));
162 void capture_sequence(struct lttng_msgpack_writer
*writer
,
163 struct lttng_interpreter_output
*output
)
165 const struct lttng_integer_type
*integer_type
;
166 const struct lttng_type
*nested_type
;
171 lttng_msgpack_begin_array(writer
, output
->u
.sequence
.nr_elem
);
173 ptr
= (uint8_t *) output
->u
.sequence
.ptr
;
174 nested_type
= output
->u
.sequence
.nested_type
;
175 switch (nested_type
->atype
) {
177 integer_type
= &nested_type
->u
.integer
;
180 /* Treat enumeration as an integer. */
181 integer_type
= &nested_type
->u
.enum_nestable
.container_type
->u
.integer
;
184 /* Capture of array of non-integer are not supported. */
187 signedness
= integer_type
->signedness
;
188 for (i
= 0; i
< output
->u
.sequence
.nr_elem
; i
++) {
190 lttng_msgpack_write_signed_integer(writer
,
191 capture_sequence_element_signed(ptr
, integer_type
));
193 lttng_msgpack_write_unsigned_integer(writer
,
194 capture_sequence_element_unsigned(ptr
, integer_type
));
198 * We assume that alignment is smaller or equal to the size.
199 * This currently holds true but if it changes in the future,
200 * we will want to change the pointer arithmetics below to
201 * take into account that the next element might be further
204 assert(integer_type
->alignment
<= integer_type
->size
);
206 /* Size is in number of bits. */
207 ptr
+= (integer_type
->size
/ CHAR_BIT
) ;
210 lttng_msgpack_end_array(writer
);
213 void lttng_event_notifier_notification_send(
214 struct lttng_event_notifier
*event_notifier
)
217 * We want this write to be atomic AND non-blocking, meaning that we
218 * want to write either everything OR nothing.
219 * According to `pipe(7)`, writes that are smaller that the `PIPE_BUF`
220 * value must be atomic, so we assert that the message we send is less
223 struct lttng_ust_event_notifier_notification notif
;
226 assert(event_notifier
);
227 assert(event_notifier
->group
);
228 assert(sizeof(notif
) <= PIPE_BUF
);
230 notif
.token
= event_notifier
->user_token
;
232 ret
= patient_write(event_notifier
->group
->notification_fd
, ¬if
,
235 if (errno
== EAGAIN
) {
236 DBG("Cannot send event notifier notification without blocking: %s",
239 DBG("Error to sending event notifier notification: %s",