Return FALSE from lm_connection_open in the synchronous case instead of open callback
authorOwen Taylor <otaylor@redhat.com>
Mon, 25 Feb 2008 23:58:43 +0100
changeset 344 11473296fea5
parent 343 35a19649d773
child 345 9a94f040cc56
child 346 ca353cc81e9a
Return FALSE from lm_connection_open in the synchronous case instead of open callback This patch fixes things up so that synchronous failures don't call the open callback but instead return the correct FALSE result from lm_connection_open(). Otherwise this means that we will get the callback before the lm_connection_open call has returned. committer: Mikael Hallendal <micke@imendio.com>
loudmouth/lm-connection.c
loudmouth/lm-socket.c
--- a/loudmouth/lm-connection.c	Mon Feb 25 23:13:58 2008 +0100
+++ b/loudmouth/lm-connection.c	Mon Feb 25 23:58:43 2008 +0100
@@ -458,14 +458,9 @@
 		domain = g_strdup (connection->server);
 	}
 
-	lm_message_queue_attach (connection->queue, connection->context);
-	
 	lm_verbose ("Connecting to: %s:%d\n", 
 		    connection->server, connection->port);
 
-	connection->state = LM_CONNECTION_STATE_OPENING;
-	connection->async_connect_waiting = FALSE;
-
 	connection->socket = lm_socket_create (connection->context,
 					       (IncomingDataFunc) connection_incoming_data,
 					       (SocketClosedFunc) connection_socket_closed_cb,
@@ -486,6 +481,11 @@
 		return FALSE;
 	}
 
+	lm_message_queue_attach (connection->queue, connection->context);
+	
+	connection->state = LM_CONNECTION_STATE_OPENING;
+	connection->async_connect_waiting = FALSE;
+
 	return TRUE;
 }
 					
--- a/loudmouth/lm-socket.c	Mon Feb 25 23:13:58 2008 +0100
+++ b/loudmouth/lm-socket.c	Mon Feb 25 23:58:43 2008 +0100
@@ -340,9 +340,10 @@
 		_lm_sock_shutdown (socket->fd);
 		_lm_sock_close (socket->fd);
 
-		if (!delayed)
+		if (!delayed && socket->connect_func) {
 			(socket->connect_func) (socket, FALSE, socket->user_data);
-
+		}
+		
 		return FALSE;
 	}
 
@@ -380,7 +381,9 @@
 	/* Need some way to report error/success */
 	if (socket->cancel_open) {
 		lm_verbose ("Cancelling connection...\n");
-		(socket->connect_func) (socket, FALSE, socket->user_data);
+		if (socket->connect_func) {
+			(socket->connect_func) (socket, FALSE, socket->user_data);
+		}
 		return;
 	}
 	
@@ -393,8 +396,9 @@
 
 	/* old-style ssl should be started immediately */
 	if (socket->ssl && (lm_ssl_get_use_starttls (socket->ssl) == FALSE)) {
-		if (!_lm_socket_ssl_init (socket, FALSE))
+		if (!_lm_socket_ssl_init (socket, FALSE)) {
 			return;
+		}
 	}
 
 	socket->watch_in = 
@@ -424,7 +428,9 @@
 				      socket);
 #endif
 
-	(socket->connect_func) (socket, TRUE, socket->user_data);
+	if (socket->connect_func) {
+		(socket->connect_func) (socket, TRUE, socket->user_data);
+	}
 }
 
 gboolean 
@@ -451,7 +457,9 @@
 	}
 	
 	if (connect_data->current_addr == NULL) {
-		(socket->connect_func) (socket, FALSE, socket->user_data);
+		if (socket->connect_func) {
+			(socket->connect_func) (socket, FALSE, socket->user_data);
+		}
 		
 		 /* if the user callback called connection_close(), this is already freed */
 		if (socket->connect_data != NULL) {
@@ -966,8 +974,9 @@
 #else
 	err = getaddrinfo (remote_addr, NULL, &req, &ans);
 	_lm_socket_create_phase2 (socket, (err) ? NULL : ans);
-	if (err != 0)
+	if (err != 0) {
 		return;
+	}
 #endif
 }
 
@@ -976,7 +985,9 @@
 {
 	if (ans == NULL) {
 		lm_verbose ("error while resolving, bailing out\n");
-		(socket->connect_func) (socket, FALSE, socket->user_data);
+		if (socket->connect_func) {
+			(socket->connect_func) (socket, FALSE, socket->user_data);
+		}
 		g_free (socket->connect_data);
 		socket->connect_data = NULL;
 		return;
@@ -1029,10 +1040,6 @@
 	socket->ssl_started = FALSE;
 	socket->proxy = NULL;
 	socket->blocking = blocking;
-	socket->data_func = data_func;
-	socket->closed_func = closed_func;
-	socket->connect_func = connect_func;
-	socket->user_data = user_data;
 
 	if (context) {
 		socket->context = g_main_context_ref (context);
@@ -1066,6 +1073,29 @@
 		_lm_socket_create_phase1 (socket, NULL, 0);
 	}
 
+	if (socket->connect_data == NULL) {
+		/* Open failed synchronously, probably a DNS lookup problem */
+		lm_socket_unref(socket);
+		
+		g_set_error (error,
+			     LM_ERROR,                 
+			     LM_ERROR_CONNECTION_FAILED,   
+			     "Failed to resolve server");
+		
+		return NULL;
+	}
+		
+
+	/* If the connection fails synchronously, we don't want to call the
+	 * connect_func to indicate an error, we return an error indication
+	 * instead. So, we delay saving the functions until after we know
+	 * we are going to return success.
+	 */
+	socket->data_func = data_func;
+	socket->closed_func = closed_func;
+	socket->connect_func = connect_func;
+	socket->user_data = user_data;
+	
 	return socket;
 }