Fix semantics of NotifySend() for Tcp
authorTom Henderson <tomh@tomh.org>
Tue, 13 May 2008 06:57:57 -0700
changeset 3119 d65486147a02
parent 3118 3fdbdaf6142d
child 3120 774b2637845e
Fix semantics of NotifySend() for Tcp
src/internet-node/tcp-socket.cc
src/internet-node/tcp-socket.h
--- a/src/internet-node/tcp-socket.cc	Mon May 12 23:02:44 2008 -0700
+++ b/src/internet-node/tcp-socket.cc	Tue May 13 06:57:57 2008 -0700
@@ -83,7 +83,8 @@
     m_lastMeasuredRtt (Seconds(0.0)),
     m_rxAvailable (0), 
     m_sndBufLimit (0xffffffff), 
-    m_rcvBufLimit (0xffffffff) 
+    m_rcvBufLimit (0xffffffff), 
+    m_wouldBlock (false) 
 {
   NS_LOG_FUNCTION (this);
   
@@ -378,7 +379,11 @@
   NS_LOG_FUNCTION (this << buf << size);
   if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT)
     { // Ok to buffer some data to send
-      size = std::min(size, GetTxAvailable() ); //only buffer what can fit
+      if (size > GetTxAvailable ())
+        {
+          size = std::min(size, GetTxAvailable() ); //only buffer what can fit
+          m_wouldBlock = true;
+        }
       if (!m_pendingData)
         {
           m_pendingData = new PendingData ();   // Create if non-existent
@@ -390,7 +395,6 @@
                    " state " << m_state);
       Actions_t action = ProcessEvent (APP_SEND);
       NS_LOG_DEBUG(" action " << action);
-      //NotifySend (GetTxAvailable ()); //XXX not here, do this when data acked
       if (!ProcessAction (action)) 
         {
           return -1; // Failed, return zero
@@ -785,7 +789,12 @@
       if (tcpHeader.GetAckNumber () > m_highestRxAck)
       {
         m_highestRxAck = tcpHeader.GetAckNumber ();
-        //NotifySend (GetTxAvailable() );  //XXX do when data gets acked
+        // Data freed from the send buffer; notify any blocked sender
+        if (m_wouldBlock)
+          {
+            NotifySend (GetTxAvailable ());
+            m_wouldBlock = false;
+          }
       }
       SendPendingData ();
       break;
@@ -1184,9 +1193,13 @@
   NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack 
            << " numberAck " << (ack - m_highestRxAck)); // Number bytes ack'ed
   m_highestRxAck = ack;         // Note the highest recieved Ack
-  //m_highestRxAck advancing means some data was acked, and the size of free
-  //space in the buffer has increased
-  NotifySend (GetTxAvailable ());
+  if (m_wouldBlock)
+    {
+      // m_highestRxAck advancing means some data was acked, and the size 
+      // of free space in the buffer has increased
+      NotifySend (GetTxAvailable ());
+      m_wouldBlock = false;
+    }
   if (ack > m_nextTxSequence) 
     {
       m_nextTxSequence = ack; // If advanced
--- a/src/internet-node/tcp-socket.h	Mon May 12 23:02:44 2008 -0700
+++ b/src/internet-node/tcp-socket.h	Tue May 13 06:57:57 2008 -0700
@@ -189,6 +189,7 @@
   
   uint32_t m_sndBufLimit;   // buffer limit for the outgoing queue
   uint32_t m_rcvBufLimit;   // maximum receive socket buffer size
+  bool m_wouldBlock;  // set to true whenever socket would block on send()
 };
 
 }//namespace ns3