Commit | Line | Data |
---|---|---|
0235b0db | 1 | # SPDX-License-Identifier: MIT |
81447b5b | 2 | # |
811644b8 | 3 | # Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com> |
81447b5b | 4 | |
5995b304 SM |
5 | import uuid as uuidp |
6 | import functools | |
81447b5b | 7 | import collections.abc |
5995b304 SM |
8 | |
9 | from bt2 import error as bt2_error | |
10 | from bt2 import utils as bt2_utils | |
3fb99a22 | 11 | from bt2 import value as bt2_value |
5995b304 | 12 | from bt2 import object as bt2_object |
3fb99a22 | 13 | from bt2 import stream as bt2_stream |
5995b304 | 14 | from bt2 import native_bt |
3fb99a22 | 15 | from bt2 import stream_class as bt2_stream_class |
335a2da5 PP |
16 | |
17 | ||
79935628 SM |
18 | def _bt2_trace_class(): |
19 | from bt2 import trace_class as bt2_trace_class | |
20 | ||
21 | return bt2_trace_class | |
22 | ||
23 | ||
f0a42b33 FD |
24 | class _TraceEnvironmentConst(collections.abc.Mapping): |
25 | _create_value_from_ptr_and_get_ref = staticmethod( | |
26 | bt2_value._create_from_const_ptr_and_get_ref | |
27 | ) | |
28 | ||
335a2da5 PP |
29 | def __init__(self, trace): |
30 | self._trace = trace | |
31 | ||
32 | def __getitem__(self, key): | |
e5914347 | 33 | bt2_utils._check_str(key) |
335a2da5 PP |
34 | |
35 | borrow_entry_fn = native_bt.trace_borrow_environment_entry_value_by_name_const | |
36 | value_ptr = borrow_entry_fn(self._trace._ptr, key) | |
37 | ||
38 | if value_ptr is None: | |
39 | raise KeyError(key) | |
40 | ||
f0a42b33 | 41 | return self._create_value_from_ptr_and_get_ref(value_ptr) |
335a2da5 PP |
42 | |
43 | def __len__(self): | |
44 | count = native_bt.trace_get_environment_entry_count(self._trace._ptr) | |
45 | assert count >= 0 | |
46 | return count | |
47 | ||
48 | def __iter__(self): | |
f0a42b33 | 49 | trace_ptr = self._trace._ptr |
335a2da5 PP |
50 | |
51 | for idx in range(len(self)): | |
52 | borrow_entry_fn = native_bt.trace_borrow_environment_entry_by_index_const | |
53 | entry_name, _ = borrow_entry_fn(trace_ptr, idx) | |
54 | assert entry_name is not None | |
55 | yield entry_name | |
81447b5b PP |
56 | |
57 | ||
f0a42b33 FD |
58 | class _TraceEnvironment(_TraceEnvironmentConst, collections.abc.MutableMapping): |
59 | _create_value_from_ptr_and_get_ref = staticmethod( | |
60 | bt2_value._create_from_ptr_and_get_ref | |
61 | ) | |
62 | ||
63 | def __setitem__(self, key, value): | |
64 | if isinstance(value, str): | |
65 | set_env_entry_fn = native_bt.trace_set_environment_entry_string | |
66 | elif isinstance(value, int): | |
67 | set_env_entry_fn = native_bt.trace_set_environment_entry_integer | |
68 | else: | |
f5567ea8 | 69 | raise TypeError("expected str or int, got {}".format(type(value))) |
81447b5b | 70 | |
f0a42b33 | 71 | status = set_env_entry_fn(self._trace._ptr, key, value) |
e5914347 SM |
72 | bt2_utils._handle_func_status( |
73 | status, "cannot set trace object's environment entry" | |
74 | ) | |
81447b5b | 75 | |
f0a42b33 FD |
76 | def __delitem__(self, key): |
77 | raise NotImplementedError | |
78 | ||
79 | ||
e5914347 | 80 | class _TraceConst(bt2_object._SharedObject, collections.abc.Mapping): |
9dee90bd SM |
81 | @staticmethod |
82 | def _get_ref(ptr): | |
83 | native_bt.trace_get_ref(ptr) | |
84 | ||
85 | @staticmethod | |
86 | def _put_ref(ptr): | |
87 | native_bt.trace_put_ref(ptr) | |
88 | ||
f0a42b33 FD |
89 | _borrow_stream_ptr_by_id = staticmethod(native_bt.trace_borrow_stream_by_id_const) |
90 | _borrow_stream_ptr_by_index = staticmethod( | |
91 | native_bt.trace_borrow_stream_by_index_const | |
92 | ) | |
93 | _borrow_class_ptr = staticmethod(native_bt.trace_borrow_class_const) | |
94 | _borrow_user_attributes_ptr = staticmethod( | |
95 | native_bt.trace_borrow_user_attributes_const | |
96 | ) | |
97 | _create_value_from_ptr_and_get_ref = staticmethod( | |
98 | bt2_value._create_from_const_ptr_and_get_ref | |
99 | ) | |
100 | _stream_pycls = property(lambda _: bt2_stream._StreamConst) | |
79935628 | 101 | _trace_class_pycls = property(lambda _: _bt2_trace_class()._TraceClassConst) |
f0a42b33 | 102 | _trace_env_pycls = property(lambda _: _TraceEnvironmentConst) |
811644b8 PP |
103 | |
104 | def __len__(self): | |
8c2367b8 SM |
105 | count = native_bt.trace_get_stream_count(self._ptr) |
106 | assert count >= 0 | |
811644b8 PP |
107 | return count |
108 | ||
8c2367b8 | 109 | def __getitem__(self, id): |
e5914347 | 110 | bt2_utils._check_uint64(id) |
81447b5b | 111 | |
f0a42b33 | 112 | stream_ptr = self._borrow_stream_ptr_by_id(self._ptr, id) |
81447b5b | 113 | |
8c2367b8 SM |
114 | if stream_ptr is None: |
115 | raise KeyError(id) | |
81447b5b | 116 | |
f0a42b33 | 117 | return self._stream_pycls._create_from_ptr_and_get_ref(stream_ptr) |
81447b5b PP |
118 | |
119 | def __iter__(self): | |
8c2367b8 | 120 | for idx in range(len(self)): |
f0a42b33 | 121 | stream_ptr = self._borrow_stream_ptr_by_index(self._ptr, idx) |
8c2367b8 | 122 | assert stream_ptr is not None |
81447b5b | 123 | |
8c2367b8 SM |
124 | id = native_bt.stream_get_id(stream_ptr) |
125 | assert id >= 0 | |
81447b5b | 126 | |
8c2367b8 | 127 | yield id |
81447b5b | 128 | |
05abc762 PP |
129 | @property |
130 | def cls(self): | |
f0a42b33 | 131 | trace_class_ptr = self._borrow_class_ptr(self._ptr) |
05abc762 | 132 | assert trace_class_ptr is not None |
f0a42b33 | 133 | return self._trace_class_pycls._create_from_ptr_and_get_ref(trace_class_ptr) |
05abc762 | 134 | |
5783664e PP |
135 | @property |
136 | def user_attributes(self): | |
f0a42b33 | 137 | ptr = self._borrow_user_attributes_ptr(self._ptr) |
5783664e | 138 | assert ptr is not None |
f0a42b33 | 139 | return self._create_value_from_ptr_and_get_ref(ptr) |
5783664e | 140 | |
81447b5b PP |
141 | @property |
142 | def name(self): | |
50842bdc | 143 | return native_bt.trace_get_name(self._ptr) |
81447b5b | 144 | |
f0a42b33 FD |
145 | @property |
146 | def uuid(self): | |
147 | uuid_bytes = native_bt.trace_get_uuid(self._ptr) | |
148 | if uuid_bytes is None: | |
149 | return | |
150 | ||
151 | return uuidp.UUID(bytes=uuid_bytes) | |
152 | ||
153 | @property | |
154 | def environment(self): | |
155 | return self._trace_env_pycls(self) | |
156 | ||
157 | def add_destruction_listener(self, listener): | |
f5567ea8 | 158 | """Add a listener to be called when the trace is destroyed.""" |
f0a42b33 FD |
159 | if not callable(listener): |
160 | raise TypeError("'listener' parameter is not callable") | |
161 | ||
e5914347 | 162 | handle = bt2_utils._ListenerHandle(self.addr) |
67de22ba | 163 | |
f0a42b33 FD |
164 | fn = native_bt.bt2_trace_add_destruction_listener |
165 | listener_from_native = functools.partial( | |
67de22ba | 166 | _trace_destruction_listener_from_native, listener, handle |
f0a42b33 FD |
167 | ) |
168 | ||
169 | status, listener_id = fn(self._ptr, listener_from_native) | |
e5914347 | 170 | bt2_utils._handle_func_status( |
f5567ea8 | 171 | status, "cannot add destruction listener to trace object" |
f0a42b33 FD |
172 | ) |
173 | ||
67de22ba SM |
174 | handle._set_listener_id(listener_id) |
175 | ||
176 | return handle | |
f0a42b33 | 177 | |
1114a7d5 | 178 | def remove_destruction_listener(self, listener_handle): |
e5914347 | 179 | bt2_utils._check_type(listener_handle, bt2_utils._ListenerHandle) |
1114a7d5 | 180 | |
67de22ba | 181 | if listener_handle._addr != self.addr: |
1114a7d5 | 182 | raise ValueError( |
f5567ea8 | 183 | "This trace destruction listener does not match the trace object." |
1114a7d5 SM |
184 | ) |
185 | ||
186 | if listener_handle._listener_id is None: | |
f5567ea8 | 187 | raise ValueError("This trace destruction listener was already removed.") |
1114a7d5 SM |
188 | |
189 | status = native_bt.trace_remove_destruction_listener( | |
190 | self._ptr, listener_handle._listener_id | |
191 | ) | |
e5914347 | 192 | bt2_utils._handle_func_status(status) |
67de22ba | 193 | listener_handle._invalidate() |
1114a7d5 | 194 | |
f0a42b33 FD |
195 | |
196 | class _Trace(_TraceConst): | |
197 | _borrow_stream_ptr_by_id = staticmethod(native_bt.trace_borrow_stream_by_id) | |
198 | _borrow_stream_ptr_by_index = staticmethod(native_bt.trace_borrow_stream_by_index) | |
199 | _borrow_class_ptr = staticmethod(native_bt.trace_borrow_class) | |
200 | _borrow_user_attributes_ptr = staticmethod(native_bt.trace_borrow_user_attributes) | |
201 | _create_value_from_ptr_and_get_ref = staticmethod( | |
202 | bt2_value._create_from_ptr_and_get_ref | |
203 | ) | |
204 | _stream_pycls = property(lambda _: bt2_stream._Stream) | |
79935628 | 205 | _trace_class_pycls = property(lambda _: _bt2_trace_class()._TraceClass) |
f0a42b33 FD |
206 | _trace_env_pycls = property(lambda _: _TraceEnvironment) |
207 | ||
8c2367b8 | 208 | def _name(self, name): |
e5914347 | 209 | bt2_utils._check_str(name) |
d24d5663 | 210 | status = native_bt.trace_set_name(self._ptr, name) |
e5914347 | 211 | bt2_utils._handle_func_status(status, "cannot set trace class object's name") |
81447b5b | 212 | |
8c2367b8 | 213 | _name = property(fset=_name) |
811644b8 | 214 | |
f0a42b33 FD |
215 | def _user_attributes(self, user_attributes): |
216 | value = bt2_value.create_value(user_attributes) | |
e5914347 | 217 | bt2_utils._check_type(value, bt2_value.MapValue) |
f0a42b33 | 218 | native_bt.trace_set_user_attributes(self._ptr, value._ptr) |
335a2da5 | 219 | |
f0a42b33 | 220 | _user_attributes = property(fset=_user_attributes) |
335a2da5 PP |
221 | |
222 | def _uuid(self, uuid): | |
e5914347 | 223 | bt2_utils._check_type(uuid, uuidp.UUID) |
335a2da5 PP |
224 | native_bt.trace_set_uuid(self._ptr, uuid.bytes) |
225 | ||
226 | _uuid = property(fset=_uuid) | |
227 | ||
5783664e | 228 | def create_stream(self, stream_class, id=None, name=None, user_attributes=None): |
e5914347 | 229 | bt2_utils._check_type(stream_class, bt2_stream_class._StreamClass) |
81447b5b | 230 | |
8c2367b8 SM |
231 | if stream_class.assigns_automatic_stream_id: |
232 | if id is not None: | |
cfbd7cf3 FD |
233 | raise ValueError( |
234 | "id provided, but stream class assigns automatic stream ids" | |
235 | ) | |
81447b5b | 236 | |
8c2367b8 SM |
237 | stream_ptr = native_bt.stream_create(stream_class._ptr, self._ptr) |
238 | else: | |
239 | if id is None: | |
cfbd7cf3 FD |
240 | raise ValueError( |
241 | "id not provided, but stream class does not assign automatic stream ids" | |
242 | ) | |
81447b5b | 243 | |
e5914347 | 244 | bt2_utils._check_uint64(id) |
cfbd7cf3 FD |
245 | stream_ptr = native_bt.stream_create_with_id( |
246 | stream_class._ptr, self._ptr, id | |
247 | ) | |
81447b5b | 248 | |
8c2367b8 | 249 | if stream_ptr is None: |
c345b078 | 250 | raise bt2_error._MemoryError("cannot create stream object") |
81447b5b | 251 | |
3fb99a22 | 252 | stream = bt2_stream._Stream._create_from_ptr(stream_ptr) |
81447b5b | 253 | |
8c2367b8 SM |
254 | if name is not None: |
255 | stream._name = name | |
81447b5b | 256 | |
5783664e PP |
257 | if user_attributes is not None: |
258 | stream._user_attributes = user_attributes | |
259 | ||
8c2367b8 | 260 | return stream |
81447b5b | 261 | |
81447b5b | 262 | |
67de22ba | 263 | def _trace_destruction_listener_from_native(user_listener, handle, trace_ptr): |
f0a42b33 FD |
264 | trace = _TraceConst._create_from_ptr_and_get_ref(trace_ptr) |
265 | user_listener(trace) | |
67de22ba | 266 | handle._invalidate() |