Ticket #2963: 0002-tcp-wait-for-connection-to-complete-before-notifying.patch

File 0002-tcp-wait-for-connection-to-complete-before-notifying.patch, 2.5 KB (added by hamish, 9 years ago)
  • src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp

    From f07267c602f91c7c1ec207e1168b7a3a4b05678f Mon Sep 17 00:00:00 2001
    From: Hamish Morrison <hamishm53@gmail.com>
    Date: Sat, 30 May 2015 16:52:21 +0100
    Subject: [PATCH 2/2] tcp: wait for connection to complete before notifying
     B_SELECT_WRITE
    
    ---
     .../kernel/network/protocols/tcp/TCPEndpoint.cpp      | 19 ++++++++++++++-----
     1 file changed, 14 insertions(+), 5 deletions(-)
    
    diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
    index dc3a4a1..ce4769b 100644
    a b segment_in_sequence(const tcp_segment_header& segment, int size,  
    320320static inline bool
    321321is_writable(tcp_state state)
    322322{
    323     return state == SYNCHRONIZE_SENT || state == SYNCHRONIZE_RECEIVED
    324         || state == ESTABLISHED || state == FINISH_RECEIVED;
     323    return state == ESTABLISHED || state == FINISH_RECEIVED;
     324}
     325
     326
     327static inline bool
     328is_establishing(tcp_state state)
     329{
     330    return state == SYNCHRONIZE_SENT || state == SYNCHRONIZE_RECEIVED;
    325331}
    326332
    327333
    TCPEndpoint::SendData(net_buffer *buffer)  
    786792        return ENOTCONN;
    787793    if (fState == LISTEN)
    788794        return EDESTADDRREQ;
    789     if (!is_writable(fState)) {
     795    if (!is_writable(fState) && !is_establishing(fState)) {
    790796        // we only send signals when called from userland
    791797        if (gStackModule->is_syscall())
    792798            send_signal(find_thread(NULL), SIGPIPE);
    TCPEndpoint::SendData(net_buffer *buffer)  
    812818                return posix_error(status);
    813819            }
    814820
    815             if (!is_writable(fState)) {
     821            if (!is_writable(fState) && !is_establishing(fState)) {
    816822                // we only send signals when called from userland
    817823                if (gStackModule->is_syscall())
    818824                    send_signal(find_thread(NULL), SIGPIPE);
    TCPEndpoint::SendAvailable()  
    873879
    874880    if (is_writable(fState))
    875881        available = fSendQueue.Free();
     882    else if (is_establishing(fState))
     883        available = 0;
    876884    else
    877885        available = EPIPE;
    878886
    TCPEndpoint::_MarkEstablished()  
    11821190    }
    11831191
    11841192    fSendList.Signal();
     1193    gSocketModule->notify(socket, B_SELECT_WRITE, fSendQueue.Free());
    11851194}
    11861195
    11871196
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    21852194        if (is_writable(fState)) {
    21862195            // notify threads waiting on the socket to become writable again
    21872196            fSendList.Signal();
    2188             gSocketModule->notify(socket, B_SELECT_WRITE, fSendQueue.Used());
     2197            gSocketModule->notify(socket, B_SELECT_WRITE, fSendQueue.Free());
    21892198        }
    21902199
    21912200        if (fCongestionWindow < fSlowStartThreshold)