[Bug 31438] [EA Origin]Unable to download game since the new version

wine-bugs at winehq.org wine-bugs at winehq.org
Mon Mar 24 11:30:02 CDT 2014


http://bugs.winehq.org/show_bug.cgi?id=31438

Alessandro Pignotti <alexpigna.dev at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |alexpigna.dev at gmail.com

--- Comment #118 from Alessandro Pignotti <alexpigna.dev at gmail.com> ---
I've spent a few hours analysing the issue. At this point I believe that the
issue is not a bug neither a race condition, but just a side-effect of the high
overhead caused by round trips to the wineserver.

Let me put down some facts which helps understanding my analysis:

*) Origin uses Qt5Network to handle the HTTP download and this analysis is
based on the open source Qt code.
*) HTTP download in Qt happens using unbuffered QTcpSockets
*) While parsing HTTP headers and status response Qt read one byte at a time
*) Notifications from WSAAsyncSelect are explicitly disabled when the first
message is received, and enabled again in QAbstractSocket as soon as the first
data is read
*) By design, WSARecv will issue a new notification message if more data is
available on the socket, this happens in wine as specified by the MSDN

Now, this is what happens

1) Qt send an HTTP request, it register a callback when some data is received.
In windows this asynchronous operations is supported using WSAAsyncSelect which
ask the system to send a window message when some data is available on the
socket.
2) Some data eventually arrives, aynchronous notifications are first disabled
by Qt, but then enabled again before reading the first bytes. Since headers are
read 1 byte at the time QAbstractSocket::readData will be invoked tons of
times. And since the socket is unbuffered WSARecv will be invoked tons of times
as well.
3) For each invocation of WSARecv there will be more data available (remember
we are parsing HTTP headers 1 byte at the time). Since async notifications are
enabled WSARecv will cause a new notification to be sent.
4) After the headers are successifully parsed and there is no more data, there
will be tons of pending async notification message, one for each call to
WSARecv
5) Each message will cause WSAAsyncSelect to be invoked twice: once to disable
notifications and once to enabled them again, even if there is no data
available since it has been all consumed in the mean time.

In wine each call to WSARecv and WSAAsyncSelect requires a roundtrip to the
wineserver, all togheter they add up and cause the connection to slow down to a
crawl, since the applications spend most of the time handling messages for the
socket even if there is no data to read.

The reason the usleep(5000) workaround works is that it effectively rate limit
the number of useless messages which are processed by the applications.

Ok, so how can this be fixed? Technically wine is working as it should, the
only problem is that roundtrips to the wineserver which are kind of equivalent
to windows system call are fairly heavyweight.

Tecnically also Qt is doing something which is valid, but I find that their
approach is actually questionable and inefficient, I believe there are a couple
of fixes which could be done at the Qt level.

1) Enable buffering for the TcpSockets (which is the default, actually). The
effect of this would be to reduce the number of actual calls to WSARecv which
in turn will reduce the amount of redundant messages being sent to the
application.
2) Completely disable async read notificatons while parsing HTTP responses and
enable them again after the last available data is used.

By the way, I believe that on native windows Qt seems to be working only
because windows is faster in handling system calls and sending messages to the
application. I think that overall Qt's approach is causing some slow down and
inefficieny on windows as well, but I have not verified this directly so I'm
speculating.

Sorry for the long post, I hope this helps in fixing the issue once and for
all.

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list