Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove references to self when creating device finalizers #132

Merged

Conversation

jonasmalacofilho
Copy link
Contributor

@jonasmalacofilho jonasmalacofilho commented Nov 3, 2021

Reported-by @bearsh in #130 (comment).


From the documentation:

It is important to ensure that func, args and kwargs do not own any references to obj, either directly or indirectly, since otherwise obj will never be garbage collected. In particular, func should not be a bound method of obj.

The issue wasn't observed during testing, but it may be implementation-defined (as with __del__) and depend on specific
combinations of interpreter and Cython versions.

Instead of relying on unspecified behavior, only keep the hid_device pointer. This requires a wrapper because weakref.finalize() cannot be passed cdef functions or C pointers.

Alternatives were attempted—__dealloc__, weakref.ref(self)—but they only worked in some cases (respectively: only for del <device> and except for del <device>).

Besides removing references to self from the finalizers, also fix another problem in #130: raise a RuntimeError if open()/open_path() are called on an already open device(), preventing the old hid_device * to leak, which would later crash hid_exit().

This is necessary so open devices don't leak, later crashing hid_exit().
From the documentation:

> It is important to ensure that func, args and kwargs do not own any
references to obj, either directly or indirectly, since otherwise obj
will never be garbage collected. In particular, func should not be a
bound method of obj.

The issue wasn't observed during testing, but it may be
implementation-defined (as with __del__) and depend on specific
combinations of interpreter and Cython versions.

Instead of relying on unspecified behavior, only keep the hid_device
pointer.  This requires a wrapper because weakref.finalize() cannot be
passed cdef functions or C pointers.

Alternatives were attempted---__dealloc__, weakref.ref(self)---but
they only worked in some cases (respectively: only for `del <device>`
and except for `del <device>`).

Reported-by: @bearsh
Related: trezor#130
@jonasmalacofilho
Copy link
Contributor Author

@bearsh, do you think this solves the problem?

@bearsh
Copy link
Contributor

bearsh commented Nov 15, 2021

according to the doc it should. I didn't try this PR yet but I suppose you did 😉 and looking at the code it seems to be sane.

at the end it's up to the maintainer to decide...

@prusnak prusnak merged commit 236150b into trezor:master Nov 15, 2021
@prusnak
Copy link
Member

prusnak commented Nov 15, 2021

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants