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

Ralf Habacker ralf.habacker at freenet.de
Sat Dec 10 11:57:15 GMT 2005


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.

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);


Ralf





More information about the kde-core-devel mailing list