<div dir="ltr">Phil,<div><br></div><div>Thanks for the response and the explanation. That was very helpful!</div><div><br></div><div>Bryan</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Feb 13, 2016 at 3:00 AM, Phil Thompson <span dir="ltr"><<a href="mailto:phil@riverbankcomputing.com" target="_blank">phil@riverbankcomputing.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 12 Feb 2016, at 10:39 pm, Jones, Bryan <<a href="mailto:bjones@ece.msstate.edu">bjones@ece.msstate.edu</a>> wrote:<br>
><br>
> Phil,<br>
><br>
> Thanks for your response. I'm specifically concerned about the context of passing data between threads using the signal/slot mechanism. As you say, in the direct or blocking case, there's no concern with object lifetime.<br>
><br>
> To test this, I modified Ilya's code to make it easier to test the signal/slot mechanism on different types. A QObject fails, but standard Python types (dict, list, object, etc.) pass, showing that their reference count increases after an emit. I can even pass a list containing a QObject safely. This suggests to me that your code increases the reference count when emitting pure Python objects, but not when emitting Qt objects. Based on some digging (see below), I would expect Qt objects to arrive safely to the slot because they're copied, but this doesn't work in practice. What's safe and what's not safe when using the signal/slot mechanism when crossing thread boundaries?<br>
<br>
</span>PyQt tries to convert a Python object to something that the Qt meta-type system understands. If it can't then it wraps it in a PyQt_PyObject. This is registered with the meta-type system and part of its job is to manage the reference count of the object as it gets copied around the meta-type system.<br>
<br>
If PyQt can convert the object then it's up to the meta-type system to manage the lifecycle of the converted C++ instance as you describe below.<br>
<br>
It would be wrong for PyQt to use PyQt_PyObject for every type of Python object because that would mean you couldn't connect to slots implemented in C++ that do not understand PyQt_PyObject. However you can explicitly use PyQt_PyObject yourself by declaring the signal as...<br>
<br>
    mysig = pyqtSignal('PyQt_PyObject')<br>
<br>
...and this will "protect" the object even if it was a QObject. I was about to include the link to the relevant bit of the documentation and realised that it's only in the current snapshot and I must have added it (the documentation) since the last release.<br>
<span class=""><br>
> Looking at the Qt source, from what I understand:<br>
><br>
> 1. In qobject.cpp, the queued_activate function is used to post an signal to another thread's event queue. (See qobject.cpp::activate for the generic mechanism used to emit a signal, which calls queued_activate for queued connections). Here's a helpful blog post on the topic.<br>
> 2. To do this, queued_activate makes a copy of each argument by invoking QMetaType::create (which invokes that type's copy constructor) in the signal being emitted.<br>
> 3. When all signals have been delivered, QMetaCallEvent::destroy frees memory used by this copy.<br>
><br>
> Based on this, I conclude that Qt allows the emission of signals with any type registered with the Qt meta-type system by copying the type, delivering it to all slots, then destroying the copy.<br>
<br>
</span>Your analysis is correct, but with one key omission. You cannot copy QObject instances. It is QObject* that is supported by the meta-type system and not QObject. You still have to manage the lifecycle of what the pointer points to (or use PyQt_PyObject).<br>
<span class="HOEnZb"><font color="#888888"><br>
Phil</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature">Bryan A. Jones, Ph.D.<br>Associate Professor<br>Department of Electrical and Computer Engineering<br>231 Simrall / PO Box 9571<br>Mississippi State University<br>Mississippi state, MS 39762<br><a href="http://www.ece.msstate.edu/~bjones" target="_blank">http://www.ece.msstate.edu/~bjones</a><br>bjones AT ece DOT msstate DOT edu<br>voice 662-325-3149<br>fax 662-325-2298<br><br>Our Master, Jesus Christ, is on his way. He'll show up right on<br>time, his arrival guaranteed by the Blessed and Undisputed Ruler,<br>High King, High God.<br>- 1 Tim. 6:14b-15 (The Message)<br></div>
</div>