[Kde-windows] dcopserver only accepts one coneection on win32

Christian Ehrlicher Ch.Ehrlicher at gmx.de
Sat Dec 10 12:17:15 GMT 2005


Ralf Habacker schrieb:
> Christian Ehrlicher schrieb:
> 
> 
>>Hi,
>>
>>we have a problem with dcopserver on win32 - it only accepts one
>>connection. After a lot of debugging (I think I understand dcopserver
>>now much better :-) ) I found out that there is a problem with
>>QSocketNotifier. It just sends too much events and dcopserver gets into
>>an endless loop in dcop/KDE-ICE/misc.c:259.
>>
>>The problem is the behaviour of WSAAsyncSelect used in qtcore to get
>>notification that new data has arrived. I'll try to explain (or read
>>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/wsaasyncselect_2.asp)
>>the problem:
>>
>>client sends data -> WSAAsyncSelect creates an event ->
>>DCOPServer::processData() -> server reads data -> server and client are
>>communicating without a need for a socketnotifier -> ready -> because
>>new data arrived, an new event is created -> processData() is called but
>>can't read anything from the socket -> endless loop
>>
>>WSAAsyncSelect stops sending events until it is reenabled by calling the
>>specific function. This means that I don't get an event until I called
>>recv().
>>
>>But since DCOPServer::processData() sends and reads data, new events a
>>created...
>>My current hack is to disable the event notifier inside
>>DCOPServer::processData() (see attached patch). I'm unsure if this is ok
>>because I currently don't know what happens when new data arrives after
>>I called recv() the last time but QSocketNotifier isn't enabled yet. If
>>I get a notification, it will work, but if not, the server get out of
>>sync/the client waits forever.
>>
>>I wonder how this worked with qt3 because there also WSAAsyncSelect is
>>used (at least I use it for qt3/free because I found no solution how to
>>get it working with select())
>>
>> 
>>
> 
> As far as I understand does dcopserver use QSocketnotifier derived 
> classes for socket event handling. There is one signal slot connection 
> for detecting new clients (signal=DCOPListener::activated() : 
> slot=DCOPServer::newClient()) and one for processing data 
> (signal=DCOPConnection::activated() slot=DCOPServer::processData()).
> The first connection is bound to the listening socket, the second is 
> bound to the accepted socket. On unix this seems to work well. To find 
> the differences there a some questions:
> 1. Are the listening and the accepted socket connections blocking or non 
> blocking socket connections ?
> I believe blocking, but I'm not sure; on windows they definitly are non 
> blocking because QSocketNotifier uses WSAAsyncSelect(), which may result 
> in problems because recv does not wait until data is there (and I had 
> tried to catch with the EWOULDBLOCK hack in kICE). Instead it trigger 
> socket events although no data is there. May be this hide the newClient 
> signal ?
> 
> 2. How does qt distinct the signal activation for different 
> QSocketNotifier objects ?
> The newClient() slot is never called, when a connection is opened ,also 
> the related socket notifier is activated ?
> 
> from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/wsaasyncselect_2.asp
> 
> The socket created by the *accept* 
> <http://msdn.microsoft.com/library/en-us/winsock/winsock/accept_2.asp> 
> function has the same properties as the listening socket used to accept 
> it. Consequently, *WSAAsyncSelect* events set for the listening socket 
> also apply to the accepted socket. For example, if a listening socket 
> has *WSAAsyncSelect* events *FD_ACCEPT*, *FD_READ*, and *FD_WRITE*, then 
> any socket accepted on that listening socket will also have *FD_ACCEPT*, 
> *FD_READ*, and *FD_WRITE* events with the same /wMsg/ [2] value used for 
> messages. If a different /wMsg/ or events are desired, the application 
> should call *WSAAsyncSelect*, passing the accepted socket and the 
> desired new data.
No, you never will get this because in newClient() a new listener is
created which overwrites the old settings for the new socket :-)
> 
> How does qt distingh the several QSocketNotifier events set with 
> *WSAAsyncSelect() ?
> 
> *They uses the WM_USER message and I cannot see how qt_internal_proc 
> detect the related QSocketNotifier for signaling. The take the wp param, 
> but I haven't seen, that *WSAAsyncSelect* was given such an identifer. 
> Have I overseen something =?
> 
> LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, 
> LPARAM lp)
> <snip>
> 
>                 QSockNot *sn = dict ? dict->value(wp) : 0;
>                 if (sn) {
>                     QEvent event(QEvent::SockAct);
>                     QCoreApplication::sendEvent(sn->obj, &event);
> 
socketfd is used as a key - WSAAsyncSelect creates a messge with wParam
= socketfd.
See qeventdispatcher_win.cpp line 256

This is the normal behaviour - same with qt3/free.

The only problem is that WSAAsyncSelect creates messages when new data
is on the socket and we don't fetch those messages (because dcopseerver
knows that there must arrive some data). After processing, Qt jumps into
the eventloop and gets those messages but no more data is there...

Because of this I disable the socket notifier while dcopserver
communicates with the client and reactivate them after.

Christian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 250 bytes
Desc: OpenPGP digital signature
URL: <http://mail.kde.org/pipermail/kde-core-devel/attachments/20051210/a2aae1f4/attachment.sig>


More information about the kde-core-devel mailing list