tcp: wait for connection to complete before notifying B_SELECT_WRITE

This commit is contained in:
Hamish Morrison
2015-05-31 17:30:00 +01:00
parent 2d5706f792
commit 162ae6204b
@@ -320,8 +320,14 @@ segment_in_sequence(const tcp_segment_header& segment, int size,
static inline bool static inline bool
is_writable(tcp_state state) is_writable(tcp_state state)
{ {
return state == SYNCHRONIZE_SENT || state == SYNCHRONIZE_RECEIVED return state == ESTABLISHED || state == FINISH_RECEIVED;
|| state == ESTABLISHED || state == FINISH_RECEIVED; }
static inline bool
is_establishing(tcp_state state)
{
return state == SYNCHRONIZE_SENT || state == SYNCHRONIZE_RECEIVED;
} }
@@ -786,7 +792,7 @@ TCPEndpoint::SendData(net_buffer *buffer)
return ENOTCONN; return ENOTCONN;
if (fState == LISTEN) if (fState == LISTEN)
return EDESTADDRREQ; return EDESTADDRREQ;
if (!is_writable(fState)) { if (!is_writable(fState) && !is_establishing(fState)) {
// we only send signals when called from userland // we only send signals when called from userland
if (gStackModule->is_syscall()) if (gStackModule->is_syscall())
send_signal(find_thread(NULL), SIGPIPE); send_signal(find_thread(NULL), SIGPIPE);
@@ -812,7 +818,7 @@ TCPEndpoint::SendData(net_buffer *buffer)
return posix_error(status); return posix_error(status);
} }
if (!is_writable(fState)) { if (!is_writable(fState) && !is_establishing(fState)) {
// we only send signals when called from userland // we only send signals when called from userland
if (gStackModule->is_syscall()) if (gStackModule->is_syscall())
send_signal(find_thread(NULL), SIGPIPE); send_signal(find_thread(NULL), SIGPIPE);
@@ -873,6 +879,8 @@ TCPEndpoint::SendAvailable()
if (is_writable(fState)) if (is_writable(fState))
available = fSendQueue.Free(); available = fSendQueue.Free();
else if (is_establishing(fState))
available = 0;
else else
available = EPIPE; available = EPIPE;
@@ -1182,6 +1190,7 @@ TCPEndpoint::_MarkEstablished()
} }
fSendList.Signal(); fSendList.Signal();
gSocketModule->notify(socket, B_SELECT_WRITE, fSendQueue.Free());
} }
@@ -2185,7 +2194,7 @@ TCPEndpoint::_Acknowledged(tcp_segment_header& segment)
if (is_writable(fState)) { if (is_writable(fState)) {
// notify threads waiting on the socket to become writable again // notify threads waiting on the socket to become writable again
fSendList.Signal(); fSendList.Signal();
gSocketModule->notify(socket, B_SELECT_WRITE, fSendQueue.Used()); gSocketModule->notify(socket, B_SELECT_WRITE, fSendQueue.Free());
} }
if (fCongestionWindow < fSlowStartThreshold) if (fCongestionWindow < fSlowStartThreshold)