Index: api/api_msg.c
===================================================================
RCS file: /sources/lwip/lwip/src/api/api_msg.c,v
retrieving revision 1.124
diff -u -r1.124 api_msg.c
--- api/api_msg.c	21 Jan 2010 18:43:37 -0000	1.124
+++ api/api_msg.c	21 Jan 2010 19:03:22 -0000
@@ -292,7 +292,10 @@
   }
 
   if (conn) {
-    if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT)) {
+    /* If the queued byte- or pbuf-count drops below the configured low-water limit,
+       let select mark this pcb as writable again. */
+    if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) &&
+      (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) {
       API_EVENT(conn, NETCONN_EVT_SENDPLUS, len);
     }
   }
@@ -1101,7 +1104,10 @@
       conn->state = NETCONN_NONE;
     }
     err = tcp_output_nagle(conn->pcb.tcp);
-    if ((err == ERR_OK) && (tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT)) {
+    /* If the queued byte- or pbuf-count exceeds the configured low-water limit,
+       let select mark this pcb as non-writable. */
+    if ((err == ERR_OK) && (tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) ||
+        (tcp_sndqueuelen(conn->pcb.tcp) > TCP_SNDQUEUELOWAT)) {
       API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
     }
   } else if (err == ERR_MEM) {
Index: core/init.c
===================================================================
RCS file: /sources/lwip/lwip/src/core/init.c,v
retrieving revision 1.45
diff -u -r1.45 init.c
--- core/init.c	18 Jan 2010 08:19:48 -0000	1.45
+++ core/init.c	21 Jan 2010 19:01:25 -0000
@@ -219,8 +219,10 @@
     LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly\n"));
   if (TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF/TCP_MSS)))
     LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work\n"));
-  if (TCP_SNDLOWAT > TCP_SND_BUF)
-    LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than or equal to TCP_SND_BUF.\n"));
+  if (TCP_SNDLOWAT >= TCP_SND_BUF)
+    LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF.\n"));
+  if (TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN)
+    LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN.\n"));
   if (TCP_WND > (PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE))
     LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE\n"));
   if (TCP_WND < TCP_MSS)
Index: include/lwip/opt.h
===================================================================
RCS file: /sources/lwip/lwip/src/include/lwip/opt.h,v
retrieving revision 1.144
diff -u -r1.144 opt.h
--- include/lwip/opt.h	10 Jan 2010 12:44:09 -0000	1.144
+++ include/lwip/opt.h	21 Jan 2010 19:00:52 -0000
@@ -840,15 +840,24 @@
 #endif
 
 /**
- * TCP_SNDLOWAT: TCP writable space (bytes). This must be less than or equal
- * to TCP_SND_BUF. It is the amount of space which must be available in the
- * TCP snd_buf for select to return writable.
+ * TCP_SNDLOWAT: TCP writable space (bytes). This must be less than
+ * TCP_SND_BUF. It is the amount of space which must be available in the
+ * TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT).
  */
 #ifndef TCP_SNDLOWAT
 #define TCP_SNDLOWAT                    ((TCP_SND_BUF)/2)
 #endif
 
 /**
+ * TCP_SNDQUEUELOWAT: TCP writable bufs (pbuf count). This must be grater
+ * than TCP_SND_QUEUELEN. If the number of pbufs queued on a pcb drops below
+ * this number, select returns writable (combined with TCP_SNDLOWAT).
+ */
+#ifndef TCP_SNDQUEUELOWAT
+#define TCP_SNDQUEUELOWAT               ((TCP_SND_QUEUELEN)/2)
+#endif
+
+/**
  * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb.
  */
 #ifndef TCP_LISTEN_BACKLOG
Index: include/lwip/tcp.h
===================================================================
RCS file: /sources/lwip/lwip/src/include/lwip/tcp.h,v
retrieving revision 1.90
diff -u -r1.90 tcp.h
--- include/lwip/tcp.h	14 Jan 2010 20:02:16 -0000	1.90
+++ include/lwip/tcp.h	21 Jan 2010 18:47:30 -0000
@@ -132,11 +132,12 @@
 void             tcp_poll    (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval);
 void             tcp_err     (struct tcp_pcb *pcb, tcp_err_fn err);
 
-#define          tcp_mss(pcb)      ((pcb)->mss)
-#define          tcp_sndbuf(pcb)   ((pcb)->snd_buf)
-#define          tcp_nagle_disable(pcb)  ((pcb)->flags |= TF_NODELAY)
-#define          tcp_nagle_enable(pcb) ((pcb)->flags &= ~TF_NODELAY)
-#define          tcp_nagle_disabled(pcb) (((pcb)->flags & TF_NODELAY) != 0)
+#define          tcp_mss(pcb)             ((pcb)->mss)
+#define          tcp_sndbuf(pcb)          ((pcb)->snd_buf)
+#define          tcp_sndqueuelen(pcb)     ((pcb)->snd_queuelen)
+#define          tcp_nagle_disable(pcb)   ((pcb)->flags |= TF_NODELAY)
+#define          tcp_nagle_enable(pcb)    ((pcb)->flags &= ~TF_NODELAY)
+#define          tcp_nagle_disabled(pcb)  (((pcb)->flags & TF_NODELAY) != 0)
 
 #if TCP_LISTEN_BACKLOG
 #define          tcp_accepted(pcb) (((struct tcp_pcb_listen *)(pcb))->accepts_pending--)

