From c9ca519cca1bdfb4848514f1ecd30e769c6e1c2f Mon Sep 17 00:00:00 2001
From: Howard Chu <hyc@openldap.org>
Date: Mon, 20 Feb 2012 14:51:30 -0800
Subject: [PATCH] ITS#7167 only poll sockets for write as needed

---
 libraries/libldap/ldap-int.h |  1 +
 libraries/libldap/open.c     |  2 --
 libraries/libldap/os-ip.c    | 26 ++++++++++++++++++++++++++
 libraries/libldap/request.c  |  1 +
 libraries/libldap/result.c   |  6 +++---
 5 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h
index b4261a1cac..1ef15ad215 100644
--- a/libraries/libldap/ldap-int.h
+++ b/libraries/libldap/ldap-int.h
@@ -624,6 +624,7 @@ LDAP_F (void) ldap_free_select_info( void *sip );
 LDAP_F (void) ldap_mark_select_write( LDAP *ld, Sockbuf *sb );
 LDAP_F (void) ldap_mark_select_read( LDAP *ld, Sockbuf *sb );
 LDAP_F (void) ldap_mark_select_clear( LDAP *ld, Sockbuf *sb );
+LDAP_F (void) ldap_clear_select_write( LDAP *ld, Sockbuf *sb );
 LDAP_F (int) ldap_is_read_ready( LDAP *ld, Sockbuf *sb );
 LDAP_F (int) ldap_is_write_ready( LDAP *ld, Sockbuf *sb );
 
diff --git a/libraries/libldap/open.c b/libraries/libldap/open.c
index 6b92ba68b7..a92095334e 100644
--- a/libraries/libldap/open.c
+++ b/libraries/libldap/open.c
@@ -344,7 +344,6 @@ ldap_init_fd(
 
 	/* Add the connection to the *LDAP's select pool */
 	ldap_mark_select_read( ld, conn->lconn_sb );
-	ldap_mark_select_write( ld, conn->lconn_sb );
 	
 	*ldp = ld;
 	return LDAP_SUCCESS;
@@ -502,7 +501,6 @@ ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp )
 
 	/* Add the connection to the *LDAP's select pool */
 	ldap_mark_select_read( ld, c->lconn_sb );
-	ldap_mark_select_write( ld, c->lconn_sb );
 
 	/* Make this connection an LDAP V3 protocol connection */
 	rc = LDAP_VERSION3;
diff --git a/libraries/libldap/os-ip.c b/libraries/libldap/os-ip.c
index daa765e3fe..2864256916 100644
--- a/libraries/libldap/os-ip.c
+++ b/libraries/libldap/os-ip.c
@@ -966,6 +966,32 @@ ldap_mark_select_clear( LDAP *ld, Sockbuf *sb )
 #endif
 }
 
+void
+ldap_clear_select_write( LDAP *ld, Sockbuf *sb )
+{
+	struct selectinfo	*sip;
+	ber_socket_t		sd;
+
+	sip = (struct selectinfo *)ld->ld_selectinfo;
+
+	ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
+
+#ifdef HAVE_POLL
+	/* for UNIX poll(2) */
+	{
+		int i;
+		for(i=0; i < sip->si_maxfd; i++) {
+			if( sip->si_fds[i].fd == sd ) {
+				sip->si_fds[i].events &= ~POLL_WRITE;
+			}
+		}
+	}
+#else
+	/* for UNIX select(2) */
+	FD_CLR( sd, &sip->si_writefds );
+#endif
+}
+
 
 int
 ldap_is_write_ready( LDAP *ld, Sockbuf *sb )
diff --git a/libraries/libldap/request.c b/libraries/libldap/request.c
index 88190a2d36..071391d9ab 100644
--- a/libraries/libldap/request.c
+++ b/libraries/libldap/request.c
@@ -202,6 +202,7 @@ ldap_int_flush_request(
 
 		/* sent -- waiting for a response */
 		ldap_mark_select_read( ld, lc->lconn_sb );
+		ldap_clear_select_write( ld, lc->lconn_sb );
 	}
 	return 0;
 }
diff --git a/libraries/libldap/result.c b/libraries/libldap/result.c
index b6e8e75105..7241df93f2 100644
--- a/libraries/libldap/result.c
+++ b/libraries/libldap/result.c
@@ -302,7 +302,7 @@ wait4msg(
 				if ( ber_sockbuf_ctrl( lc->lconn_sb,
 					LBER_SB_OPT_DATA_READY, NULL ) )
 				{
-					lc_ready = 1;
+					lc_ready = 2;	/* ready at ber level, not socket level */
 					break;
 				}
 			}
@@ -373,8 +373,8 @@ wait4msg(
 					}
 				}
 				LDAP_MUTEX_UNLOCK( &ld->ld_req_mutex );
-				/* Quit looping if no one handled any events */
-				if (!serviced)
+				/* Quit looping if no one handled any socket events */
+				if (!serviced && lc_ready == 1)
 					rc = -1;
 			}
 			LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
-- 
GitLab