You are here: Home » Topic » Slow performance on Windows Home Server RTM [svn-1676]

Slow performance on Windows Home Server RTM [svn-1676]

FireFly Media Server (formerly mt-daapd) Firefly Media Server Forums Firefly Media Server Nightlies Feedback Slow performance on Windows Home Server RTM [svn-1676]

This topic contains 6 replies, has 2 voices, and was last updated by  rpedde 11 years, 7 months ago.

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #1815

    AHodsdon
    Participant

    Hi, I’ve been using Firefly [svn-1676] rather successfully on my Windows Home Server box, but I’ve hit a snag. I think this has something to do with the “WSAEWOULDBLOCK hack”, but here’s the full story:

    Music plays pretty well, but whenever I play media, I get interminable delays. Looking at resource monitor, I can see data is being streamed at a pokey 140KBps. This happens when streaming over a wired gigabit network to either my Vista or MacOS X clients running iTunes 7.4.3.1. Curiously, the CPU is almost completely idle on both client and server (and I don’t appear to be disk-bound either). Also curiously, when I stream from my Mac (using Firefly) I get around 2.1MBps.

    Looking at the log files, I see something that looks like:

    // …
    2007-10-14 17:35:56 (08f43bf7): wrote 256 bytes to socket 544
    2007-10-14 17:35:56 (08f43bf7): wrote 256 bytes to socket 544
    2007-10-14 17:35:56 (08f43bf7): wrote 256 bytes to socket 544
    2007-10-14 17:35:56 (08f43bf7): wrote 256 bytes to socket 544
    2007-10-14 17:35:56 (08f43bf7): wrote -1 bytes to socket 544
    2007-10-14 17:35:56 (08f43bf7): WSAEWOULDBLOCK hack
    2007-10-14 17:35:56 (08f43bf7): wrote 256 bytes to socket 544
    2007-10-14 17:35:56 (08f43bf7): wrote 256 bytes to socket 544
    2007-10-14 17:35:56 (08f43bf7): wrote 256 bytes to socket 544
    2007-10-14 17:35:56 (08f43bf7): wrote 256 bytes to socket 544
    // …

    It appears that the WinSock SendTo is returning WSAEWOULDBLOCK, and Firefly handles this by sleeping 50 millliseconds and trying again.

    It looks like I get ~30 writes of 256 bytes before the “WSAEWOULDBLOCK hack’ kicks in. Doing a little math: 30*256bytes / .05 s = 150 KBps. Hence, it looks like this parameter was specifically tuned for a typical mp3’s bandwidth.

    Does anyone know anything more about the bug this hack is trying to work-around? I tried searching on msdn, and all I could find was:

    [Slow performance occurs when you copy data to a TCP server by using a Windows Sockets API program]
    http://support.microsoft.com/kb/823764/en-us

    This looks promising, except that it refers to streaming *to* a windows server system, not from (and I get the same bad perf when I stream to my Mac).

    Any ideas?

    [Edit: Renamed title — WHS is based on WS 2003, but certainly didn’t come out in 2003 :-/]

    #12913

    AHodsdon
    Participant

    Further searching on the net turned up:

    http://tangentsoft.net/wskfaq/newbie.html#wouldblock:

    2.8 – Winsock keeps returning the error WSAEWOULDBLOCK. What’s wrong with my program?
    Not a thing. WSAEWOULDBLOCK is a perfectly normal occurrence in programs using non-blocking and asynchronous sockets. It’s Winsock’s way of telling your program “I can’t do that right now, because I would have to block to do so.”

    The next question is, how do you know when it’s safe to try again? In the case of asynchronous sockets, Winsock will send you an FD_WRITE message after a failed send() call when it is safe to write; it will send you an FD_READ message after a recv() call when more data arrives on that socket. Similarly, in a non-blocking sockets program that uses select(), the writefds will be set when it’s okay to write, and the readfds will be set if there is data to read.

    Note that Win9x has a bug where select() can fail to block on a nonblocking socket. It will signal one of the sockets, which will cause your program to call recv() or send() or similar. That function will return WSAEWOULDBLOCK, which can be quite a surprise. So, a program using select() under Win9x has to be able to deal with this error at any time.

    This gets to a larger issue: whenever you use some form of nonblocking sockets, you have to be prepared for WSAEWOULDBLOCK at any time. It’s simply a matter of defensive programming, just like checking for null pointers.

    Can firefly just wait for a FD_WRITE message?

    #12914

    rpedde
    Participant

    @ahodsdon wrote:

    Further searching on the net turned up:

    http://tangentsoft.net/wskfaq/newbie.html#wouldblock:

    2.8 – Winsock keeps returning the error WSAEWOULDBLOCK. What’s wrong with my program?
    Not a thing. WSAEWOULDBLOCK is a perfectly normal occurrence in programs using non-blocking and asynchronous sockets. It’s Winsock’s way of telling your program “I can’t do that right now, because I would have to block to do so.”

    The next question is, how do you know when it’s safe to try again? In the case of asynchronous sockets, Winsock will send you an FD_WRITE message after a failed send() call when it is safe to write; it will send you an FD_READ message after a recv() call when more data arrives on that socket. Similarly, in a non-blocking sockets program that uses select(), the writefds will be set when it’s okay to write, and the readfds will be set if there is data to read.

    Note that Win9x has a bug where select() can fail to block on a nonblocking socket. It will signal one of the sockets, which will cause your program to call recv() or send() or similar. That function will return WSAEWOULDBLOCK, which can be quite a surprise. So, a program using select() under Win9x has to be able to deal with this error at any time.

    This gets to a larger issue: whenever you use some form of nonblocking sockets, you have to be prepared for WSAEWOULDBLOCK at any time. It’s simply a matter of defensive programming, just like checking for null pointers.

    Can firefly just wait for a FD_WRITE message?

    Yeah, but when you do, it kicks the socket back into nonblocking mode. Or something does. I’m not sure why the socket keeps going nonblocking. It think it might be the WSAAsyncSelect. I might just have to rip all that crap out and just use the bsd select. Sucks, because then I can’t select on sockets and files (using WaitForMultipleObjects), but so it goes, I guess.

    Windows.

    — Ron

    #12915

    AHodsdon
    Participant

    Yep. It looks like that’s it. Msdn has this to say on WSAAsyncSelect (http://msdn2.microsoft.com/en-us/library/ms741540.aspx):

    The WSAAsyncSelect function automatically sets socket s to nonblocking mode, regardless of the value of lEvent. To set socket s back to blocking mode, it is first necessary to clear the event record associated with socket s via a call to WSAAsyncSelect with lEvent set to zero. You can then call ioctlsocket or WSAIoctl to set the socket back to blocking mode. For more information about how to set the nonblocking socket back to blocking mode, see the ioctlsocket and WSAIoctl functions.

    #12916

    rpedde
    Participant

    @ahodsdon wrote:

    Yep. It looks like that’s it. Msdn has this to say on WSAAsyncSelect (http://msdn2.microsoft.com/en-us/library/ms741540.aspx):

    The WSAAsyncSelect function automatically sets socket s to nonblocking mode, regardless of the value of lEvent. To set socket s back to blocking mode, it is first necessary to clear the event record associated with socket s via a call to WSAAsyncSelect with lEvent set to zero. You can then call ioctlsocket or WSAIoctl to set the socket back to blocking mode. For more information about how to set the nonblocking socket back to blocking mode, see the ioctlsocket and WSAIoctl functions.

    Hrm. So it’s broken, they know it, know how to fix it, but leave it to the programmer to do it. Why not just make it work the way everyone expects it to work? Clearly they recognize that’s not what people expect.

    Lame.

    And people accuse unix of being the poster-boy for the pc-losering problem. Not even close. Not only does win32 have baroque api’s, but they push complexity toward the programmer, not into the api. Ugh.

    Grumble grumble windows suckage. But I thought as much, which is why I put the warning text in there. Dang it.

    #12917

    AHodsdon
    Participant

    Just wanted to let you know that 1695 is working much better for me. Thanks!

    #12918

    rpedde
    Participant

    @ahodsdon wrote:

    Just wanted to let you know that 1695 is working much better for me. Thanks!

    Still a nasty memory leak by the looks of it, but it’s getting there.

Viewing 7 posts - 1 through 7 (of 7 total)

The forum ‘Nightlies Feedback’ is closed to new topics and replies.