| Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date | |
| All threads index page 3 | |
I have 2 questions that may be someone can clarify. I searched on the web and failed to find good explanation of what is going on underneath of QT.... 1.When we use Signal/Slot connection and the object sends a signal where paramenter is passed by reference (there is a lot of such with QString for example). As much as I understand the paramater should be marshalled (serialized) into event and the slot will be called later from event loop. But how qt ensures that the object referenced is still alived? especially if it was allocated on stack? I tried the same with sending pointer - the application craches ( as expected). Can someone shed a light on this issue (or better give a link to resources on this topic or reference to some books)? 2. Is there any chance that event loop will exit while it still have events to process. The main worry is to send from one thread a message to another with pointer parameter and the object pointed should be released in the targetted thread (let's ommit coupling of threads and not-so-good knowledge that one object has about it's spouse...). Any web resources will be welcomed.. Thank you in advance. Alexander Tumarov. -- [ signature omitted ]
On Monday 17 March 2008 16:13:51 Alexander Tumarov wrote: > I have 2 questions that may be someone can clarify. I searched on the web > and failed to find good explanation of what is going on underneath of > QT.... > > 1.When we use Signal/Slot connection and the object sends a signal where > paramenter is passed by reference (there is a lot of such with QString for > example). As much as I understand the paramater should be marshalled > (serialized) into event and the slot will be called later from event loop. > But how qt ensures that the object referenced is still alived? You're talking here about a queued connection. If it is a direct connection, there's no marshalling/demarshalling. Quite simply, the slot function is called with the parameter that the signal had. Since all of the directly-connected slots are run inside the signal function, there's no problem here. Well, as long as you don't modify the parameter during the execution of the slots... If it's a queued connection, on the other hand, Qt has to create a copy. It does that by calling QMetaType::construct(), which is nothing more than the low-level version of QVariant. All types that can be queued must be registered with QMetaType, if they are not already (see http://doc.trolltech.com/4.3/qvariant.html#Type-enum for types that are already registered) > especially > if it was allocated on stack? I tried the same with sending pointer - the > application craches ( as expected). Can someone shed a light on this issue > (or better give a link to resources on this topic or reference to some > books)? Like I said above, Qt creates a copy and keeps it around until the signal is delivered to all slots. The caveat is that when creating a copy of a pointer, it copies the pointer value, not the object pointed to. > 2. Is there any chance that event loop will exit while it still have events > to process. The main worry is to send from one thread a message to another > with pointer parameter and the object pointed should be released in the > targetted thread (let's ommit coupling of threads and not-so-good knowledge > that one object has about it's spouse...). Any web resources will be > welcomed.. Yes, it can happen. The event dispatcher, when it starts, it looks at the events that are in queue and always delivers all of those -- except if something really bad like an exception occurred. At the end, it checks if the quit() function was called. If it was, it exits. But note that the event dispatcher does not deliver new events: that is, events that were posted after it started processing. Those would be sent at the next iteration if the quit() function had not been called. -- [ signature omitted ]
Attachment:
signature.asc
Description: This is a digitally signed message part.
Thank you for reply. My coments in the body of email ... On Monday 17 March 2008 17:28:52 Thiago Macieira wrote: > On Monday 17 March 2008 16:13:51 Alexander Tumarov wrote: > > I have 2 questions that may be someone can clarify. I searched on the web > > and failed to find good explanation of what is going on underneath of > > QT.... > > > > 1.When we use Signal/Slot connection and the object sends a signal where > > paramenter is passed by reference (there is a lot of such with QString > > for example). As much as I understand the paramater should be marshalled > > (serialized) into event and the slot will be called later from event > > loop. But how qt ensures that the object referenced is still alived? > > You're talking here about a queued connection. > > If it is a direct connection, there's no marshalling/demarshalling. Quite > simply, the slot function is called with the parameter that the signal had. > Since all of the directly-connected slots are run inside the signal > function, there's no problem here. Well, as long as you don't modify the > parameter during the execution of the slots... > > If it's a queued connection, on the other hand, Qt has to create a copy. It > does that by calling QMetaType::construct(), which is nothing more than the > low-level version of QVariant. All types that can be queued must be > registered with QMetaType, if they are not already (see > http://doc.trolltech.com/4.3/qvariant.html#Type-enum for types that are > already registered) Yes - It is about queued connection. So what I can understand is if the parameters passed by reference it is copied? And it then means that the only case that it is not copied is direct connection (that in general is preffered but not always available of course)? > > > especially > > if it was allocated on stack? I tried the same with sending pointer - the > > application craches ( as expected). Can someone shed a light on this > > issue (or better give a link to resources on this topic or reference to > > some books)? > > Like I said above, Qt creates a copy and keeps it around until the signal > is delivered to all slots. > > The caveat is that when creating a copy of a pointer, it copies the pointer > value, not the object pointed to. > > > 2. Is there any chance that event loop will exit while it still have > > events to process. The main worry is to send from one thread a message to > > another with pointer parameter and the object pointed should be released > > in the targetted thread (let's ommit coupling of threads and not-so-good > > knowledge that one object has about it's spouse...). Any web resources > > will be welcomed.. > > Yes, it can happen. > > The event dispatcher, when it starts, it looks at the events that are in > queue and always delivers all of those -- except if something really bad > like an exception occurred. At the end, it checks if the quit() function > was called. If it was, it exits. It is not about missing exception or like that. It is about queues for threads mostly. So do you mean if thread's object that runs event loop is deleted there is a possibility that events will be destroyed without proccessing? If this is a case - if events from signals contain marshalled objects - does the framework will delete them correctly (destructors?)... then memory leaks can avoided by using proxies wrappers (like auto_ptr & co....). > > But note that the event dispatcher does not deliver new events: that is, > events that were posted after it started processing. Those would be sent at > the next iteration if the quit() function had not been called. Wierd that there is no good explanation neither in books nor on trolltech site for these issues....I purchased both books by JBlanchette & M.Summerfield end either somehow missed explanations on these topics or it is just not there.... -- [ signature omitted ]
Alexander Tumarov wrote: >> If it's a queued connection, on the other hand, Qt has to create a >> copy. It does that by calling QMetaType::construct(), which is nothing >> more than the low-level version of QVariant. All types that can be >> queued must be registered with QMetaType, if they are not already (see >> http://doc.trolltech.com/4.3/qvariant.html#Type-enum for types that >> are already registered) > >Yes - It is about queued connection. >So what I can understand is if the parameters passed by reference it is >copied? Clarifying: it copies the parameter if you pass by constant reference or by value. Passing by non-constant reference is like passing by pointer. >And it then means that the only case that it is not copied is direct >connection (that in general is preffered but not always available of > course)? Yes, passing by anything that is not by value in a direct connection will result in 0 copies. Passing by value will result in -- probably -- 1+N copies. That assumes that signals and slots have the same signature. If you pass by const-ref in the signal by pass by value in the slot, that will trigger a copy. >> The event dispatcher, when it starts, it looks at the events that are >> in queue and always delivers all of those -- except if something >> really bad like an exception occurred. At the end, it checks if the >> quit() function was called. If it was, it exits. > >It is not about missing exception or like that. It is about queues for > threads mostly. So do you mean if thread's object that runs event loop > is deleted there is a possibility that events will be destroyed without > proccessing? If this is a case - if events from signals contain > marshalled objects - does the framework will delete them correctly > (destructors?)... then memory leaks can avoided by using proxies > wrappers (like auto_ptr & co....). If you quit the thread, the event dispatcher finishes its round of processing and exits. Events posted *after* you called quit() will not be processed and will be left in the thread's event dispatcher queue. If you then delete the thread, those events will get destroyed. Qt correctly cleans up any copied parameters: remember, QEvent has a virtual destructor, so you can catch those things. >Wierd that there is no good explanation neither in books nor on > trolltech site for these issues....I purchased both books by > JBlanchette & M.Summerfield end either somehow missed explanations on > these topics or it is just not there.... I'd consider what I've just explained completely internal implementation details. They're rather too advanced for the book or shouldn't be there because it may change. Besides, the behaviour is what you would expect. So, unless there are surprises (and there aren't), there's nothing to document. -- [ signature omitted ]
Attachment:
signature.asc
Description: This is a digitally signed message part.
On Tuesday 18 March 2008 09:01:11 Thiago Macieira wrote: > Alexander Tumarov wrote: > >> If it's a queued connection, on the other hand, Qt has to create a > >> copy. It does that by calling QMetaType::construct(), which is nothing > >> more than the low-level version of QVariant. All types that can be > >> queued must be registered with QMetaType, if they are not already (see > >> http://doc.trolltech.com/4.3/qvariant.html#Type-enum for types that > >> are already registered) > > > >Yes - It is about queued connection. > >So what I can understand is if the parameters passed by reference it is > >copied? > > Clarifying: it copies the parameter if you pass by constant reference or > by value. > > Passing by non-constant reference is like passing by pointer. Hm.... this is pretty error-prone approach. > > >And it then means that the only case that it is not copied is direct > >connection (that in general is preffered but not always available of > > course)? > > Yes, passing by anything that is not by value in a direct connection will > result in 0 copies. Passing by value will result in -- probably -- 1+N > copies. > > That assumes that signals and slots have the same signature. If you pass > by const-ref in the signal by pass by value in the slot, that will > trigger a copy. > > >> The event dispatcher, when it starts, it looks at the events that are > >> in queue and always delivers all of those -- except if something > >> really bad like an exception occurred. At the end, it checks if the > >> quit() function was called. If it was, it exits. > > > >It is not about missing exception or like that. It is about queues for > > threads mostly. So do you mean if thread's object that runs event loop > > is deleted there is a possibility that events will be destroyed without > > proccessing? If this is a case - if events from signals contain > > marshalled objects - does the framework will delete them correctly > > (destructors?)... then memory leaks can avoided by using proxies > > wrappers (like auto_ptr & co....). > > If you quit the thread, the event dispatcher finishes its round of > processing and exits. Events posted *after* you called quit() will not be > processed and will be left in the thread's event dispatcher queue. > > If you then delete the thread, those events will get destroyed. Qt > correctly cleans up any copied parameters: remember, QEvent has a virtual > destructor, so you can catch those things. Thank you. > > >Wierd that there is no good explanation neither in books nor on > > trolltech site for these issues....I purchased both books by > > JBlanchette & M.Summerfield end either somehow missed explanations on > > these topics or it is just not there.... > > I'd consider what I've just explained completely internal implementation > details. They're rather too advanced for the book or shouldn't be there > because it may change. > > Besides, the behaviour is what you would expect. So, unless there are > surprises (and there aren't), there's nothing to document. Understanding of what is going on (at least at theoretical level) is pretty vital. If QT is used in a simple notepad-like projects - I agree - the existing documentation is enough. But if you delve in a big complex projects that involves multithreading and for example complex IO (network ... local... whatever) - such small misunderstandings can cost a lot. Waiting for surprises is in general not acceptable (at least from my point of view). Of course I understand that "there is no bugs-free software" and that no library can be suited for every possible need. It is very wierd that really important subjects like marshalling are not explained thouroughly. It seems that the only way to get a proper understanding is a "usual open source way" - read through sources ( I am not complaining... I just hope that it would change - I hope QT will become more and more usable.... but libraries at these extents cannot evolve good without proper documentation) I am just evaluating QT for some projects that will demand pretty complex multithreading and networking. Thank you for answering my questions. -- [ signature omitted ]
Alexander Tumarov wrote: > Understanding of what is going on (at least at theoretical level) is > pretty vital. If QT is used in a simple notepad-like projects - I agree > - the existing documentation is enough. But if you delve in a big > complex projects that involves multithreading and for example complex > IO (network ... local... whatever) - such small misunderstandings can > cost a lot. Waiting for surprises is in general not acceptable (at > least from my point of view). Of course I understand that "there is no > bugs-free software" and that no library can be suited for every > possible need. It is very wierd that really important subjects like > marshalling are not explained thouroughly. >It seems that the only way to get a proper understanding is a "usual > open source way" - read through sources ( I am not complaining... I > just hope that it would change - I hope QT will become more and more > usable.... but libraries at these extents cannot evolve good without > proper documentation) > >I am just evaluating QT for some projects that will demand pretty > complex multithreading and networking. The book will never document everything that all readers want. No book ever will and even all books put together won't be enough. For one thing, the book would be incredibly thick -- both in physical dimensions and text quality [*]. Second, keeping up with the pace of development is also very difficult. I consider documenting D-Bus, Graphics View (4.2), QtScript (4.3), Widgets on Canvas, XmlPatterns, WebKit, Phonon (4.4) a lot more important than the implementation details of how the Qt Meta Type system works. For another, you have all of the source code. If you want to make sure what the behaviour is, read the source code or run examples, tracing it through those functions. And you have mailing lists and forums. I consider this mailing list, the Qt Centre, etc. all part of the experience with and advantages of programming with Qt. [*] I was going to say "in literal sense", but literal means "to the letter", which is also ambiguous in this context :-) -- [ signature omitted ]
Attachment:
signature.asc
Description: This is a digitally signed message part.
On Tuesday 18 March 2008 10:04:21 Thiago Macieira wrote: > Alexander Tumarov wrote: > >ÂUnderstanding of what is going on (at least at theoretical level) is > > pretty vital. If QT is used in a simple notepad-like projects - I agree > > Â- the existing documentation is enough. But if you delve in a big > > complex projects that involves multithreading and for example complex > > IO (network ... local... whatever) - such small misunderstandings can > > cost a lot. Waiting for surprises is in general not acceptable (at > > least from my point of view). Of course I understand that "there is no > > bugs-free software" and that no library can be suited for every > > possible need. It is very wierd that really important subjects like > > marshalling are not explained thouroughly. > >It seems that the only way to get a proper understanding is a "usual > > open source way" - read through sources ( I am not complaining... I > > just hope that it would change - I hope QT will become more and more > > usable.... but libraries at these extents cannot evolve good without > > proper documentation) > > > >I am just evaluating QT for some projects that will demand pretty > > complex multithreading and networking. > > The book will never document everything that all readers want. No book > ever will and even all books put together won't be enough. > > For one thing, the book would be incredibly thick -- both in physical > dimensions and text quality [*]. Second, keeping up with the pace of > development is also very difficult. I consider documenting D-Bus, > Graphics View (4.2), QtScript (4.3), Widgets on Canvas, XmlPatterns, > WebKit, Phonon (4.4) a lot more important than the implementation details > of how the Qt Meta Type system works. Without any shadow of doubt - All of these are VERY important. At the same time -marshalling is always very important issue and indeed it is something that very important part of QT (if not of central features) is build upon. At list at my opinion - this topic deserves it's own part in documentation. > > For another, you have all of the source code. If you want to make sure > what the behaviour is, read the source code or run examples, tracing it > through those functions. > > And you have mailing lists and forums. I consider this mailing list, the > Qt Centre, etc. all part of the experience with and advantages of > programming with Qt. Thank you againg for your time and answers. > > [*] I was going to say "in literal sense", but literal means "to the > letter", which is also ambiguous in this context :-) -- [ signature omitted ]
On Tuesday 18 March 2008 09:36:35 Alexander Tumarov wrote: > Without any shadow of doubt - All of these are VERY important. > At the same time Â-marshalling is always very important issue and indeed it > is something that very important part of QT (if not of central features) is > build upon. At list at my opinion - this topic deserves it's own part in > documentation. There's no marshalling. It's a simple copy (QMetaType calls your copy constructor). Marshalling is used in QDataStream and in QtDBus. Both of those are optional features for registered meta types and both of them require that you call an extra function to register the marshalling (operator<<) and demarshalling (operator>>) functions. All of the above is handled through template magic, macro magic and function pointers. It's really a hairy subject. -- [ signature omitted ]
Attachment:
signature.asc
Description: This is a digitally signed message part.
On Tuesday 18 March 2008 11:19:40 Thiago Macieira wrote: > On Tuesday 18 March 2008 09:36:35 Alexander Tumarov wrote: > > Without any shadow of doubt - All of these are VERY important. > > At the same time Â-marshalling is always very important issue and indeed > > it is something that very important part of QT (if not of central > > features) is build upon. At list at my opinion - this topic deserves it's > > own part in documentation. > > There's no marshalling. It's a simple copy (QMetaType calls your copy > constructor). > You definitelly right - not marshalling. Wrong term. Copied... I meant that a copy of data created. > Marshalling is used in QDataStream and in QtDBus. Both of those are > optional features for registered meta types and both of them require that > you call an extra function to register the marshalling (operator<<) and > demarshalling (operator>>) functions. > > All of the above is handled through template magic, macro magic and > function pointers. It's really a hairy subject. -- [ signature omitted ]