changeset 19816:e2f9c117aef7

lib-http: http_client_connection_unref() now always sets *conn=NULL This makes its behavior consistent with other APIs in Dovecot.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Mon, 22 Feb 2016 20:14:57 +0200
parents 6cbcdcbd9ad7
children fa23955f6028
files src/lib-http/http-client-connection.c src/lib-http/http-client-private.h
diffstat 2 files changed, 14 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-http/http-client-connection.c	Mon Feb 22 20:03:44 2016 +0200
+++ b/src/lib-http/http-client-connection.c	Mon Feb 22 20:14:57 2016 +0200
@@ -538,9 +538,10 @@
 }
 
 static bool
-http_client_connection_return_response(struct http_client_connection *conn,
-	struct http_client_request *req, struct http_response *response)
+http_client_connection_return_response(struct http_client_request *req,
+	struct http_response *response)
 {
+	struct http_client_connection *conn = req->conn;
 	struct istream *payload;
 	bool retrying, ret;
 
@@ -571,9 +572,7 @@
 	conn->in_req_callback = TRUE;
 	http_client_connection_ref(conn);
 	retrying = !http_client_request_callback(req, response);
-	http_client_connection_unref(&conn);
-	if (conn == NULL) {
-		req->conn = NULL;
+	if (!http_client_connection_unref(&req->conn)) {
 		/* the callback managed to get this connection destroyed */
 		if (!retrying)
 			http_client_request_finish(&req);
@@ -863,7 +862,8 @@
 
 			if (!handled) {
 				/* response for application */
-				if (!http_client_connection_return_response(conn, req, &response))
+				i_assert(req->conn == conn);
+				if (!http_client_connection_return_response(req, &response))
 					return;
 			}
 		}
@@ -1055,7 +1055,7 @@
 			response.status = 200;
 			response.reason = "OK";
 
-			(void)http_client_connection_return_response(conn, req, &response);
+			(void)http_client_connection_return_response(req, &response);
 			http_client_request_unref(&req);
 			return;
 		} 
@@ -1395,7 +1395,7 @@
 		timeout_remove(&conn->to_response);
 }
 
-void http_client_connection_unref(struct http_client_connection **_conn)
+bool http_client_connection_unref(struct http_client_connection **_conn)
 {
 	struct http_client_connection *conn = *_conn;
 	struct http_client_connection *const *conn_idx;
@@ -1404,8 +1404,10 @@
 
 	i_assert(conn->refcount > 0);
 
+	*_conn = NULL;
+
 	if (--conn->refcount > 0)
-		return;
+		return TRUE;
 
 	http_client_connection_debug(conn, "Connection destroy");
 
@@ -1431,7 +1433,7 @@
 	if (conn->connect_succeeded)
 		http_client_peer_connection_lost(peer);
 	i_free(conn);
-	*_conn = NULL;
+	return FALSE;
 }
 
 void http_client_connection_close(struct http_client_connection **_conn)
--- a/src/lib-http/http-client-private.h	Mon Feb 22 20:03:44 2016 +0200
+++ b/src/lib-http/http-client-private.h	Mon Feb 22 20:14:57 2016 +0200
@@ -304,7 +304,8 @@
 struct http_client_connection *
 	http_client_connection_create(struct http_client_peer *peer);
 void http_client_connection_ref(struct http_client_connection *conn);
-void http_client_connection_unref(struct http_client_connection **_conn);
+/* Returns FALSE if unrefing destroyed the connection entirely */
+bool http_client_connection_unref(struct http_client_connection **_conn);
 void http_client_connection_close(struct http_client_connection **_conn);
 int http_client_connection_output(struct http_client_connection *conn);
 void http_client_connection_start_request_timeout(