beagle r4605 - in trunk/libbeagle: . beagle examples



Author: dbera
Date: Tue Mar 11 21:17:37 2008
New Revision: 4605
URL: http://svn.gnome.org/viewvc/beagle?rev=4605&view=rev

Log:
* Let libbeagle connect to beagled with a timeout of 5 seconds, which should be enough for a unix based socket. So if beagled is hanged for some reason, libbeagle will not hang.
* Scheduler information and index information can legally be null; so do not fail but return that information.
* Up library revision to 1.
* Catch common errors in the example.


Modified:
   trunk/libbeagle/beagle/beagle-daemon-information-response.c
   trunk/libbeagle/beagle/beagle-private.h
   trunk/libbeagle/beagle/beagle-request.c
   trunk/libbeagle/beagle/beagle-scheduler-information.c
   trunk/libbeagle/beagle/beagle-util.c
   trunk/libbeagle/configure.in
   trunk/libbeagle/examples/beagle-info.c

Modified: trunk/libbeagle/beagle/beagle-daemon-information-response.c
==============================================================================
--- trunk/libbeagle/beagle/beagle-daemon-information-response.c	(original)
+++ trunk/libbeagle/beagle/beagle-daemon-information-response.c	Tue Mar 11 21:17:37 2008
@@ -387,8 +387,6 @@
 	g_return_val_if_fail (BEAGLE_IS_DAEMON_INFORMATION_RESPONSE (response), NULL);
 
 	priv = BEAGLE_DAEMON_INFORMATION_RESPONSE_GET_PRIVATE (response);
-	g_return_val_if_fail (priv->scheduler_information != NULL, NULL);
-
 	process_info = priv->scheduler_information;
 	
 	return beagle_scheduler_information_to_human_readable_string (process_info);
@@ -410,7 +408,6 @@
 	g_return_val_if_fail (BEAGLE_IS_DAEMON_INFORMATION_RESPONSE (response), NULL);
 
 	priv = BEAGLE_DAEMON_INFORMATION_RESPONSE_GET_PRIVATE (response);
-	g_return_val_if_fail (priv->index_status, NULL);
 
 	return priv->index_status;
 }
@@ -435,7 +432,6 @@
 	g_return_val_if_fail (BEAGLE_IS_DAEMON_INFORMATION_RESPONSE (response), NULL);
 
 	priv = BEAGLE_DAEMON_INFORMATION_RESPONSE_GET_PRIVATE (response);
-	g_return_val_if_fail (priv->index_status != NULL, NULL);
 
 	tmp = g_string_new ("\n");
 

Modified: trunk/libbeagle/beagle/beagle-private.h
==============================================================================
--- trunk/libbeagle/beagle/beagle-private.h	(original)
+++ trunk/libbeagle/beagle/beagle-private.h	Tue Mar 11 21:17:37 2008
@@ -124,6 +124,7 @@
 						const char *xsi_type);
 void _beagle_query_part_append_standard_footer (GString *data);
 
+int _beagle_connect_timeout (const char *socket_path, GError **err);
 BeagleResponse *_beagle_request_send (BeagleRequest *request,
 				      const char *socket_path,
 				      GError **err);

Modified: trunk/libbeagle/beagle/beagle-request.c
==============================================================================
--- trunk/libbeagle/beagle/beagle-request.c	(original)
+++ trunk/libbeagle/beagle/beagle-request.c	Tue Mar 11 21:17:37 2008
@@ -34,6 +34,8 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#include <fcntl.h>
+#include <errno.h>
 
 #include "beagle-error-response.h"
 #include "beagle-marshal.h"
@@ -165,21 +167,38 @@
 
 	va_end (args);
 }
-	
-static gboolean
-request_connect (BeagleRequest *request, const char *path, GError **err)
+
+int
+_beagle_connect_timeout (const char *path, GError **err)
 {
-	BeagleRequestPrivate *priv;
 	int sockfd;
+	int ret;
+	int error, error_len;
+	long mode;
+	fd_set select_set;
+	struct timeval tv;
 	struct sockaddr_un sun;
 
-	priv = BEAGLE_REQUEST_GET_PRIVATE (request);
-
 	sockfd = socket (AF_UNIX, SOCK_STREAM, 0);
 	if (sockfd < 0) {
 		g_set_error (err, BEAGLE_ERROR, BEAGLE_ERROR,
 			     "Unable to create connection");
-		return FALSE;
+		return -1;
+	}
+
+	/* Set non-blocking mode */
+	if ((mode = fcntl (sockfd, F_GETFL, NULL)) < 0) {
+		g_set_error (err, BEAGLE_ERROR, BEAGLE_ERROR,
+			    "Internal error: unable to get status flag for socket");
+		return -1;
+	}
+
+	mode |= O_NONBLOCK;
+
+	if (fcntl (sockfd, F_SETFL, mode) < 0) {
+		g_set_error (err, BEAGLE_ERROR, BEAGLE_ERROR,
+			    "Internal error: unable to set socket to non-blocking mode");
+		return -1;
 	}
 
 	bzero (&sun, sizeof (sun));
@@ -187,11 +206,72 @@
 	snprintf (sun.sun_path, sizeof (sun.sun_path), path);
 
 	if (connect (sockfd, (struct sockaddr *) &sun, sizeof (sun)) < 0) {
+		if (errno != EINPROGRESS) {
+			g_set_error (err, BEAGLE_ERROR, BEAGLE_ERROR,
+				"Unable to connect to Beagle daemon");
+			return -1;
+		} else {
+			tv.tv_sec = 10; /* 5 seconds should be enough for a unix socket */
+			tv.tv_usec = 0;
+
+			FD_ZERO (&select_set);
+			FD_SET (sockfd, &select_set);
+
+			ret = select (sockfd + 1, NULL, &select_set, NULL, &tv);
+			if (ret > 0) {
+				/* Check for any error during select() */
+				error_len = sizeof (error);
+				ret = getsockopt (sockfd, SOL_SOCKET, SO_ERROR, &error, &error_len);
+				if (ret < 0 || error != 0) {
+					g_set_error (err, BEAGLE_ERROR, BEAGLE_ERROR,
+						"Unable to connect to Beagle daemon");
+					close (sockfd);
+					return -1;
+				}
+				/* Else, connection successful */
+			} else {
+				g_set_error (err, BEAGLE_ERROR, BEAGLE_ERROR,
+					"Unable to connect to Beagle daemon");
+				close (sockfd);
+				return -1;
+			}
+		}
+	}
+
+	/* Set socket to blocking mode */
+	if ((mode = fcntl (sockfd, F_GETFL, NULL)) < 0) {
 		g_set_error (err, BEAGLE_ERROR, BEAGLE_ERROR,
-			     "Unable to connect to Beagle daemon");
-		return FALSE;
+			    "Internal error: unable to get status flag for socket");
+		close (sockfd);
+		return -1;
+	}
+
+	mode &= (~O_NONBLOCK);
+
+	if (fcntl (sockfd, F_SETFL, mode) < 0) {
+		g_set_error (err, BEAGLE_ERROR, BEAGLE_ERROR,
+			    "Internal error: unable to set socket to non-blocking mode");
+		close (sockfd);
+		return -1;
 	}
 
+	/* Finally, we are done ! */
+	return sockfd;
+}
+
+static gboolean
+request_connect (BeagleRequest *request, const char *path, GError **err)
+{
+	BeagleRequestPrivate *priv;
+	int sockfd;
+	struct sockaddr_un sun;
+
+	priv = BEAGLE_REQUEST_GET_PRIVATE (request);
+
+	sockfd = _beagle_connect_timeout (path, err);
+	if (sockfd == -1)
+		return FALSE;
+
 	g_free (priv->path);
 	priv->path = g_strdup (path);
 

Modified: trunk/libbeagle/beagle/beagle-scheduler-information.c
==============================================================================
--- trunk/libbeagle/beagle/beagle-scheduler-information.c	(original)
+++ trunk/libbeagle/beagle/beagle-scheduler-information.c	Tue Mar 11 21:17:37 2008
@@ -196,7 +196,14 @@
 	GSList *iter;
 	GString *tmp = g_string_new (NULL);
 
-	g_string_append_printf (tmp, "Scheduler:\nCount: %d\n", sched_info->total_task_count);
+	g_string_append (tmp, "Scheduler:");
+	/* sched_info can be null if there is no scheduling information */
+	if (sched_info == NULL) {
+		g_string_append (tmp, " (empty)\n");
+		return g_string_free (tmp, FALSE);
+	}
+
+	g_string_append_printf (tmp, "\nCount: %d\n", sched_info->total_task_count);
 
 	if (sched_info->status_string)
 		g_string_append_printf (tmp, "Status: %s\n", sched_info->status_string);

Modified: trunk/libbeagle/beagle/beagle-util.c
==============================================================================
--- trunk/libbeagle/beagle/beagle-util.c	(original)
+++ trunk/libbeagle/beagle/beagle-util.c	Tue Mar 11 21:17:37 2008
@@ -159,21 +159,14 @@
 	if (socket_path == NULL)
 		return FALSE;
 
-	bzero (&sun, sizeof (sun));
-	sun.sun_family = AF_UNIX;
-	snprintf (sun.sun_path, sizeof (sun.sun_path), socket_path);
+	sockfd = _beagle_connect_timeout (socket_path, NULL);
 
 	g_free (socket_path);
 
-	sockfd = socket (AF_UNIX, SOCK_STREAM, 0);
 	if (sockfd < 0) {
 		return FALSE;
 	}
 
-	if (connect (sockfd, (struct sockaddr *) &sun, sizeof (sun)) < 0) {
-		return FALSE;
-	}
-
 	close (sockfd);
 	
 	return TRUE;

Modified: trunk/libbeagle/configure.in
==============================================================================
--- trunk/libbeagle/configure.in	(original)
+++ trunk/libbeagle/configure.in	Tue Mar 11 21:17:37 2008
@@ -42,7 +42,7 @@
 dnl Update when changing implementation of current API,
 dnl reset to 0 when changing CURRENT.  This is the revision of
 dnl current API version
-LIBBEAGLE_REVISION=0
+LIBBEAGLE_REVISION=1
 
 dnl Increase of API change is ABI compatible, otherwise reset to 0
 LIBBEAGLE_AGE=0

Modified: trunk/libbeagle/examples/beagle-info.c
==============================================================================
--- trunk/libbeagle/examples/beagle-info.c	(original)
+++ trunk/libbeagle/examples/beagle-info.c	Tue Mar 11 21:17:37 2008
@@ -13,6 +13,10 @@
 								  is_indexing
 								);
 	response = beagle_client_send_request (client, BEAGLE_REQUEST (request), NULL);
+	if (response == NULL) {
+		g_printf ("Invalid response from beagled\n");
+		return;
+	}
 
 	g_object_unref (request);
 
@@ -36,6 +40,11 @@
 	g_type_init ();
 
 	client = beagle_client_new (NULL);
+	if (client == NULL) {
+		g_printf ("beagled not running.\n");
+		return 1;
+	}
+
 	test_daemon_information (client);
 
 	return 0;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]