[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