Commit | Line | Data |
---|---|---|
0235b0db | 1 | # SPDX-License-Identifier: MIT |
81447b5b | 2 | # |
811644b8 | 3 | # Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com> |
81447b5b | 4 | |
81447b5b | 5 | |
78288f58 SM |
6 | class _BaseObject: |
7 | # Ensure that the object always has _ptr set, even if it throws during | |
8 | # construction. | |
9 | ||
10 | def __new__(cls, *args, **kwargs): | |
11 | obj = super().__new__(cls) | |
12 | obj._ptr = None | |
13 | return obj | |
81447b5b | 14 | |
81447b5b PP |
15 | def __init__(self, ptr): |
16 | self._ptr = ptr | |
17 | ||
18 | @property | |
19 | def addr(self): | |
20 | return int(self._ptr) | |
21 | ||
78288f58 | 22 | def __repr__(self): |
cfbd7cf3 FD |
23 | return '<{}.{} object @ {}>'.format( |
24 | self.__class__.__module__, self.__class__.__name__, hex(self.addr) | |
25 | ) | |
78288f58 SM |
26 | |
27 | def __copy__(self): | |
28 | raise NotImplementedError | |
29 | ||
30 | def __deepcopy__(self, memo): | |
31 | raise NotImplementedError | |
32 | ||
33 | ||
34 | # A Python object that is itself not refcounted, but is wholly owned by an | |
35 | # object that is itself refcounted (a _SharedObject). A Babeltrace unique | |
36 | # object gets destroyed once its owner gets destroyed (its refcount drops to | |
37 | # 0). | |
38 | # | |
39 | # In the Python bindings, to avoid having to deal with issues with the lifetime | |
40 | # of unique objects, we make it so acquiring a reference on a unique object | |
41 | # acquires a reference on its owner. | |
42 | ||
cfbd7cf3 | 43 | |
78288f58 SM |
44 | class _UniqueObject(_BaseObject): |
45 | ||
46 | # Create a _UniqueObject. | |
47 | # | |
48 | # - ptr: SWIG Object, pointer to the unique object. | |
49 | # - owner_ptr: SWIG Object, pointer to the owner of the unique | |
50 | # object. A new reference is acquired. | |
51 | # - owner_get_ref: Callback to get a reference on the owner | |
52 | # - owner_put_ref: Callback to put a reference on the owner. | |
53 | ||
81447b5b | 54 | @classmethod |
cfbd7cf3 | 55 | def _create_from_ptr_and_get_ref(cls, ptr, owner_ptr, owner_get_ref, owner_put_ref): |
81447b5b | 56 | obj = cls.__new__(cls) |
2ae9f48c | 57 | |
81447b5b | 58 | obj._ptr = ptr |
78288f58 | 59 | obj._owner_ptr = owner_ptr |
2ae9f48c | 60 | obj._owner_get_ref = owner_get_ref |
78288f58 | 61 | obj._owner_put_ref = owner_put_ref |
2ae9f48c SM |
62 | |
63 | obj._owner_get_ref(obj._owner_ptr) | |
64 | ||
81447b5b PP |
65 | return obj |
66 | ||
81447b5b | 67 | def __del__(self): |
78288f58 | 68 | self._owner_put_ref(self._owner_ptr) |
81447b5b | 69 | |
81447b5b | 70 | |
78288f58 SM |
71 | # Python object that owns a reference to a Babeltrace object. |
72 | class _SharedObject(_BaseObject): | |
81447b5b | 73 | |
78288f58 SM |
74 | # Get a new reference on ptr. |
75 | # | |
76 | # This must be implemented by subclasses to work correctly with a pointer | |
77 | # of the native type they wrap. | |
811644b8 | 78 | |
78288f58 SM |
79 | @staticmethod |
80 | def _get_ref(ptr): | |
81 | raise NotImplementedError | |
811644b8 | 82 | |
78288f58 SM |
83 | # Put a reference on ptr. |
84 | # | |
85 | # This must be implemented by subclasses to work correctly with a pointer | |
86 | # of the native type they wrap. | |
81447b5b | 87 | |
78288f58 SM |
88 | @staticmethod |
89 | def _put_ref(ptr): | |
90 | raise NotImplementedError | |
81447b5b | 91 | |
78288f58 SM |
92 | # Create a _SharedObject from an existing reference. |
93 | # | |
94 | # This assumes that the caller owns a reference to the Babeltrace object | |
95 | # and transfers this ownership to the newly created Python object. | |
81447b5b | 96 | |
78288f58 SM |
97 | @classmethod |
98 | def _create_from_ptr(cls, ptr_owned): | |
99 | obj = cls.__new__(cls) | |
100 | obj._ptr = ptr_owned | |
101 | return obj | |
81447b5b | 102 | |
78288f58 SM |
103 | # Like _create_from_ptr, but acquire a new reference rather than |
104 | # stealing the caller's reference. | |
105 | ||
106 | @classmethod | |
107 | def _create_from_ptr_and_get_ref(cls, ptr): | |
108 | obj = cls._create_from_ptr(ptr) | |
109 | cls._get_ref(obj._ptr) | |
110 | return obj | |
111 | ||
112 | def __del__(self): | |
113 | self._put_ref(self._ptr) |