Hello everyone,<br>
<br>
(I&#39;m attaching the patchset here as I don&#39;t have the possibility to push
 stuff to my repository right now)<br>
<br>
I addressed most of your concerns and implemented most of your 
suggestions. Point to point:<br><br><div class="gmail_quote">2010/5/12 Olli Salli <span dir="ltr">&lt;<a href="mailto:ollisal@gmail.com">ollisal@gmail.com</a>&gt;</span><br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div><div></div><div class="h5">On Tue, May 11, 2010 at 8:20 PM, Dario Freddi &lt;<a href="mailto:drf54321@gmail.com">drf54321@gmail.com</a>&gt; wrote:<br>
&gt; Hi Olli, first of all thanks for the thorough review.<br>
&gt;<br>
&gt; On Tuesday 11 May 2010 18:36:02 Olli Salli wrote:<br>
&gt;&gt; On Sat, May 1, 2010 at 8:43 PM, Dario Freddi &lt;<a href="mailto:drf54321@gmail.com">drf54321@gmail.com</a>&gt; wrote:<br>
&gt;&gt; &gt; On Saturday 01 May 2010 16:19:10 Dario Freddi wrote:<br>
&gt;&gt; &gt;&gt; Hello,<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; I managed to implement a preliminary version of StreamTubes. There&#39;s<br>
&gt;&gt; &gt;&gt; still a critical problem in the accept phase I cannot get over and I&#39;d<br>
&gt;&gt; &gt;&gt; like you to take a look as well. But one thing at a time.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Quick update: I switched using Unix sockets in IncomingTubeChannel while<br>
&gt;&gt; &gt; the problem gets settled, and everything is working nicely :) I made the<br>
&gt;&gt; &gt; sockets exchange some random text messages and printing them to stdout.<br>
&gt;&gt; &gt; Also, to demonstrate that everything is working, the sender is using a<br>
&gt;&gt; &gt; standard QTcpServer with default listening arguments, while the receiver<br>
&gt;&gt; &gt; is using, as already said, a unix socket.<br>
&gt;&gt;<br>
&gt;&gt; Finally had time to take a more thorough look at your code. Some<br>
&gt;&gt; observations:<br>
&gt;&gt;<br>
&gt;&gt; Account::createStreamTube: about including TargetHandle == 0 in the<br>
&gt;&gt; request when contact is NULL: the spec states about TargetHandle that<br>
&gt;&gt; &quot;If this is present in a channel request, it must be nonzero&quot;. So, I<br>
&gt;&gt; think you should return a PendingChannelRequest which fails<br>
&gt;&gt; immediately if the contact isn&#39;t valid. However, I realize what you<br>
&gt;&gt; did is what the other Account methods are doing as well - Andre, can<br>
&gt;&gt; you give me a heads up on why this is so? Should we just change them<br>
&gt;&gt; all in fact?<br>
&gt;<br>
&gt; I agree with you they should all be changed - although, given that it should<br>
&gt; be a global change, I think it would be better to have my stuff merged first<br>
&gt; with this approach, and then change everything with a single commit - or<br>
&gt; otherwise have the other methods changed before the merge.<br>
&gt;<br>
<br>
</div></div>Let&#39;s do that. We should do a general spec vs lib implementation audit<br>
sometime soon anyway.<br>
<div class="im"><br>
&gt;&gt; In fact, to have the separate feature would be in a sense<br>
&gt;&gt; similar to having Connection&#39;s Status as an optional introspectable,<br>
&gt;&gt; which is clearly wrong.<br>
&gt;<br>
&gt; Ok - so I assume it is right to have this bundled into<br>
&gt; TubeChannel::FeatureCore (which will be renamed to FeatureTube as Simon<br>
&gt; suggested)?<br>
&gt;<br>
<br>
</div>Exactly.<br>
<div class="im"><br>
&gt;&gt;<br>
&gt;&gt; The documentation for FeatureCore says it&#39;s implicitly added to the<br>
&gt;&gt; set of features for isReady() and becomeReady() - is this really true?<br>
&gt;&gt; I see the FT channel docs say the same, but I don&#39;t think such a<br>
&gt;&gt; mechanism actually exists (while it would be useful). However,<br>
&gt;&gt; becomeReady does have a default parameter of Channel::FeatureCore, but<br>
&gt;&gt; that doesn&#39;t extend to subclasses. Andre? Maybe we could make<br>
&gt;&gt; ReadinessHelper always assume all registered introspectables with<br>
&gt;&gt; critical == true as requested, or something?<br>
&gt;<br>
&gt; I leave the ball to Andre here.<br>
<br>
</div>Yeah, I mostly brought this up here as a general point in tp-qt4<br>
subclassability.<br>
<div class="im"><br>
&gt;<br>
&gt;&gt; Not many applications are likely<br>
&gt;&gt; to care about the signals, and we should prevent the unneeded wakeups<br>
&gt;&gt; in those cases. However, one thing I&#39;d like to be explored here is<br>
&gt;&gt; implementing QObject::connectNotify to make the connection as-needed,<br>
&gt;&gt; which would lead to both less chances of getting it wrong (expecting<br>
&gt;&gt; the signals while the feature isn&#39;t requested) and possibly better<br>
&gt;&gt; performance (per-signal granularity instead of connecting all three).<br>
&gt;<br>
&gt; Well, connectNotify just lets the class know when a connection has been<br>
&gt; estabilished. It could be useful for spitting out warnings in case you<br>
&gt; connected to a signal which is not supposed to be emitted as the corresponding<br>
&gt; feature has not yet been enabled, but its purpose is barely limited to letting<br>
&gt; you know when $something connected to $signal, and act accordingly.<br>
&gt;<br>
&gt; I agree it should be implemented to spit out warnings, though.<br>
<br>
</div>Well, the QObject docs say about connectNotify(): &quot;it might be useful<br>
when you need to perform expensive initialization only if something is<br>
connected to a signal.&quot; - which is exactly what we&#39;d do here, the<br>
expensive initialization being doing a round-trip match rule add round<br>
trip to the bus daemon and then being woken up every time that signal<br>
pops up on the bus. In fact, this is exactly what QDBus internally<br>
does when one connects to a signal in a QDBusAbstractInterface-derived<br>
class (which our low-level proxy classes are). We&#39;re sort of throwing<br>
that away by always connecting our high-level object relay signals to<br>
the low-level signals at initialization time. Note that one needs to<br>
do refcounting in disconnectNotify too, and maybe some interaction<br>
with destroyed() (not sure if disconnectNotify would be called in that<br>
case too).<br></blockquote><div><br>Ok, now I clearly see your point. Although, in this case it is not applicable, as if we want to keep track of the connections, the signals must be connected as soon as the feature is enabled. However, I implemented connectNotify() in all of the new classes to spit out some warnings.<br>
 </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div class="im"><br>
&gt;<br>
&gt;&gt;<br>
&gt;&gt; If we still go down the Feature route we might as well offer a<br>
&gt;&gt; connections() method, with the StreamTubeChannel object internally<br>
&gt;&gt; keeping track of the changes, keeping the signals for change<br>
&gt;&gt; notification of that set.<br>
&gt;<br>
&gt; Ok - do you want to add a separate FeatureConnections for that, I suppose? I<br>
&gt; also suppose the connections method should eventually return a list of<br>
&gt; Contacts?<br>
<br>
</div>If there&#39;s a feature causing the D-Bus signals to be connected, that<br>
same feature should also cause the tracking to happen - any memory<br>
cost from keeping a list of small structs is negligible compared to<br>
the wakeup penalty from the signals.<br>
<br>
And yeah, the connection descriptors it returns should include Contact<br>
objects rather than handles.<br>
<br>
But I guess we can postpone the whole connection tracking stuff for<br>
now. It can be implemented in a backwards compatible fashion later on.<br>
Well, then the change notification for a set of connection structs<br>
would be signals essentially having the struct contents unpacked (conn<br>
id, contact, param) instead of a single parameter with the struct, but<br>
I think that&#39;s convenient anyway. Also consistent with eg.<br>
AccountManager&#39;s accountCreated/Removed signals having the account<br>
object path (essentially an unique ID) as the parameter instead of a<br>
AccountPtr.<br></blockquote><div><br>Ok - atm I keep track of all the connectionIds, we can remove the public exposures before the merge.<br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

<div class="im"><br>
&gt;&gt;<br>
&gt;&gt; OutgoingStreamTube: You should move PendingOpenTube out from the<br>
&gt;&gt; public header. That is, unless you&#39;re planning to add some useful API<br>
&gt;&gt; to it, maybe access to the Offer params, in which case you should<br>
&gt;&gt; change the offer() methods to admit they return PendingOpenTube *<br>
&gt;&gt; (also requires you to make them have the PendingFailure functionality<br>
&gt;&gt; by themselves).<br>
&gt;<br>
&gt; Yes, I wanted to do it but somehow forgot it, sorry for that. Although, since<br>
&gt; it needs to be processed by moc, I&#39;d need a separate private header. What is<br>
&gt; the naming convention for that? I saw there&#39;s a stream-media-channel-<br>
&gt; internal.h, so I suppose it&#39;s &lt;name&gt;-internal.h<br>
<br>
</div>Yeah, that&#39;s it.<br>
<div class="im"><br>
&gt;&gt;<br>
&gt;&gt; Maybe setAllowedAddress actually removes the need for the access<br>
&gt;&gt; control parameter?<br>
&gt;<br>
&gt; Maybe. There is still the Credential case which should be handled, even if<br>
&gt; there could probably be a similar way for doing it. Maybe if I had some<br>
&gt; enlightenments on how the Credential control works (as I don&#39;t really get what<br>
&gt; it stands for at the moment) I could come up with something.<br>
&gt;<br>
&gt; Given the above is solved, I&#39;m all for removing the parameter.<br>
&gt;<br>
&gt; Is such a thing applicable for Outgoing tubes as well? If so, those functions<br>
&gt; might be moved down to TubeChannel and simpify the whole deal, maybe even by<br>
&gt; having private classes inheriting one from the other thanks to the power of<br>
&gt; Q_DECLARE_PRIVATE.<br>
&gt;<br>
<br>
</div>Oh sorry, I did indeed forget about Credentials. Well, that<br>
authentication scheme is only applicable to unix sockets - for which<br>
Port access control obviously doesn&#39;t make sense. Credentials means<br>
sending a SCM_CREDENTIALS ancillary message when connecting to the<br>
socket, which the kernel checks and which guarantees to the listening<br>
process that the process making the connection is really from the same<br>
local user.<br>
<br>
One idea that springs to mind is to actually have two accept() methods<br>
- acceptLocal(bool requireCredentials) -&gt; PendingLocalSocket and<br>
acceptTCP(const QHostAddress &amp;allowedAddress = QHostAddress::Any, int<br>
port = 0) -&gt; PendingTCPSocket. The latter should probably be two<br>
overloads,  The Pending* classes would provide you with<br>
QLocalSocket/QTcpSocket *socket() and QByteArray / QHostAddress+int<br>
address(). This way you could dispense with both the address family<br>
selection &quot;guess&quot; and setting the parameter beforehand. Again, using a<br>
third-party library not accepting a QIODevice might require a specific<br>
address family to connect to, we can&#39;t necessarily just always force a<br>
specific type of socket, be it tcp or unix, down their throats. Yeah,<br>
unless there&#39;s something very wrong in my thinking here (entirely<br>
possible since this is like the 100th idea on this subject), this is<br>
exactly what we should do.<br></blockquote><div><br>It&#39;s a very good idea and I implemented it with some changes: I did not do two separate Pending* classes, but I created a single one returning the address type and both addresses (just like I did in StreamTubeChannel). Also, I named them {offer,accept}TubeAs{Tcp,Unix}Socket(), which seems to me more clear and consistent.<br>
 </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<br>
For outgoing tubes, Credentials authentication is applicable but Port<br>
isn&#39;t (you can&#39;t limit the CM to make all its connections to your<br>
listening service from just one port, as any connections besides the<br>
first one would fail with EADDRINUSE). So, as we already have address<br>
family -specific overloads for Offer, we should just drop the access<br>
control param from the TCP variants since for those Localhost will be<br>
the only available choice anyway. For the unix variants we should<br>
change it to bool requiresCredentials, switching between using<br>
Localhost and Credentials. Tada, away with the abstract access control<br>
param.<br></blockquote><div><br>Done :)<br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<br>
This makes me think of another detail we could make more high-level:<br>
how would changing StreamTubeChannel::supportedSocketTypes() to bool<br>
supportsTCPSockets(), bool supportsTCPPortSelection(), bool<br>
supportsLocalSockets() &amp; bool supportsLocalCredentialPassing() with<br>
appropriate documentation sound? Then it would be more obvious which<br>
of the offer/accept variants are expected to actually work.<br></blockquote><div><br>Done as well, with slightly different names and a caveat: supportsTCPSockets is not really applicable here: I used supportedTcpProtocols, returning which IP protocol version is supported.<br>
 </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div class="im"><br>
&gt;<br>
&gt; P.S.: About that, would you prefer a particular commit scheme for the final<br>
&gt; patches?<br>
&gt;<br>
<br>
</div>Anything goes, but you should preserve as much of your original change<br>
history as you dare. At least, don&#39;t overwrite commits from before a<br>
review, instead fix them in later commits - this makes it easier to<br>
spot the changes resulting from the review, and verify they fix the<br>
issues as intended.<br></blockquote><div><br>Well, before reading your mail, I fixed everything you raised in the previous mails and amended like hell :\ so the commit scheme is very clear, but it is to be rebased on the cmake branch, and my previous patches are to be deleted. The last fixes went in as separate commits, after I read this :D<br>
<br>Thanks, and waiting for the usual feedback :)<br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div class="im"><br>
&gt; -------------------<br>
&gt;<br>
&gt; Dario Freddi<br>
&gt; KDE Developer<br>
&gt; GPG Key Signature: 511A9A3B<br>
&gt;<br>
<br>
<br>
</div>--<br>
<br>
Br,<br>
<font color="#888888">Olli Salli<br>
</font></blockquote></div><br><div style="visibility: hidden; display: inline;" id="avg_ls_inline_popup"></div><style type="text/css">#avg_ls_inline_popup {  position:absolute;  z-index:9999;  padding: 0px 0px;  margin-left: 0px;  margin-top: 0px;  width: 240px;  overflow: hidden;  word-wrap: break-word;  color: black;  font-size: 10px;  text-align: left;  line-height: 13px;}</style>