Cancellation for GnomeVFSInetConnecton



Hi,

I created a patch wich adds cancellation for GnomeVFSInetConnection. I
Also moved the wrapper for setting flags on file descriptors from gnome-
job to gnome-vfs-private-utils.
Please have a look at it and tell me what you think.

Thanks a lot,
Chris
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gnome-vfs/ChangeLog,v
retrieving revision 1.1780
diff -u -r1.1780 ChangeLog
--- ChangeLog	26 Mar 2004 15:31:25 -0000	1.1780
+++ ChangeLog	30 Mar 2004 13:48:35 -0000
@@ -1,3 +1,11 @@
+2004-03-30  Christian Kellner  <gicmo xatom net>
+
+	* libgnomevfs/gnome-vfs-private-utils.[ch]: 
+	* libgnomevfs/gnome-vfs-job.c: Moved set_fl and clr_fl to gnome-vfs-private-utils
+	  as _gnome_vfs_set_fd_flags and _gnome_vfs_clear_fd_flags.
+	* libgnomevfs/gnome-vfs-inet-connection.c: Added cancellation for read and write
+	  and fixed the wrong return value for the read function.
+
 2004-03-26  Alexander Larsson  <alexl redhat com>
 
 	* libgnomevfs/gnome-vfs-application-registry.c (gnome_vfs_application_registry_get_mime_types):
Index: libgnomevfs/gnome-vfs-job.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-job.c,v
retrieving revision 1.99
diff -u -r1.99 gnome-vfs-job.c
--- libgnomevfs/gnome-vfs-job.c	20 Oct 2003 11:55:54 -0000	1.99
+++ libgnomevfs/gnome-vfs-job.c	30 Mar 2004 13:57:30 -0000
@@ -33,8 +33,8 @@
 #include "gnome-vfs-async-job-map.h"
 #include "gnome-vfs-job-slave.h"
 #include "gnome-vfs-job-queue.h"
+#include "gnome-vfs-private-utils.h"
 #include <errno.h>
-#include <fcntl.h>
 #include <glib/gmessages.h>
 #include <glib/gstrfuncs.h>
 #include <libgnomevfs/gnome-vfs-cancellable-ops.h>
@@ -78,46 +78,6 @@
 static void	clear_current_job 		    (void);
 static void	set_current_job 		    (GnomeVFSJob *context);
 
-static void
-set_fl (int fd, int flags)
-{
-	int val;
-
-	val = fcntl (fd, F_GETFL, 0);
-	if (val < 0) {
-		g_warning ("fcntl() F_GETFL failed: %s", strerror (errno));
-		return;
-	}
-
-	val |= flags;
-	
-	val = fcntl (fd, F_SETFL, val);
-	if (val < 0) {
-		g_warning ("fcntl() F_SETFL failed: %s", strerror (errno));
-		return;
-	}
-}
-
-static void
-clr_fl (int fd, int flags)
-{
-	int val;
-
-	val = fcntl (fd, F_GETFL, 0);
-	if (val < 0) {
-		g_warning ("fcntl() F_GETFL failed: %s", strerror (errno));
-		return;
-	}
-
-	val &= ~flags;
-	
-	val = fcntl (fd, F_SETFL, val);
-	if (val < 0) {
-		g_warning ("fcntl() F_SETFL failed: %s", strerror (errno));
-		return;
-	}
-}
-
 /*
  *   Find out whether or not a given job should be left in
  * the job map, preserving it's open VFS handle, since we
@@ -887,7 +847,7 @@
 
 					fd = g_io_channel_unix_get_fd (channel_out);
 					
-					clr_fl (fd, O_NONBLOCK);
+					_gnome_vfs_clear_fd_flags (fd, O_NONBLOCK);
 				} else {
 					if (written_bytes_in_buffer > 0) {
 						/* Need to shift the unwritten bytes
@@ -1074,7 +1034,7 @@
 	 * thread is blocking for some reason the slave can keep
 	 * reading data.
 	 */
-	set_fl (pipefd[1], O_NONBLOCK);
+	_gnome_vfs_set_fd_flags (pipefd[1], O_NONBLOCK);
 	
 	channel_in = g_io_channel_unix_new (pipefd[0]);
 	channel_out = g_io_channel_unix_new (pipefd[1]);
Index: libgnomevfs/gnome-vfs-private-utils.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-private-utils.c,v
retrieving revision 1.26
diff -u -r1.26 gnome-vfs-private-utils.c
--- libgnomevfs/gnome-vfs-private-utils.c	10 Mar 2004 12:21:09 -0000	1.26
+++ libgnomevfs/gnome-vfs-private-utils.c	30 Mar 2004 13:57:31 -0000
@@ -43,6 +43,7 @@
 #include <sys/wait.h>
 #include <time.h>
 #include <unistd.h>
+#include <fcntl.h>
 
 #define GCONF_URL_HANDLER_PATH      	 "/desktop/gnome/url-handlers/"
 #define GCONF_DEFAULT_TERMINAL_EXEC_PATH "/desktop/gnome/applications/terminal/exec"
@@ -847,4 +848,78 @@
 
 	return TRUE;
 }		  
+
+/* This has been moved here from gnome-vfs-job.c because it is needed in other
+   places too */
+
+/**
+ * _gnome_vfs_set_fd_flags:
+ * @fd: a valid file descriptor
+ * @flags: file status flags to set
+ *
+ * Set the file status flags part of the descriptor’s flags to the
+ * value specified by @flags.
+ *
+ * Return value: TRUE if successful, FALSE otherwise.
+ *
+ * Since: 2.6
+ */
+
+gboolean
+_gnome_vfs_set_fd_flags (int fd, int flags)
+{
+	int val;
+
+	val = fcntl (fd, F_GETFL, 0);
+	if (val < 0) {
+		g_warning ("fcntl() F_GETFL failed: %s", strerror (errno));
+		return FALSE;
+	}
+
+	val |= flags;
+	
+	val = fcntl (fd, F_SETFL, val);
+	if (val < 0) {
+		g_warning ("fcntl() F_SETFL failed: %s", strerror (errno));
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+/**
+ * _gnome_vfs_clear_fd_flags:
+ * @fd: a valid file descriptor
+ * @flags: file status flags to clear
+ *
+ * Clear the flags sepcified by @flags of the file status flags part of the 
+ * descriptor’s flags. 
+ *
+ * Return value: TRUE if successful, FALSE otherwise.
+ *
+ * Since: 2.6
+ */
+
+gboolean
+_gnome_vfs_clear_fd_flags (int fd, int flags)
+{
+	int val;
+
+	val = fcntl (fd, F_GETFL, 0);
+	if (val < 0) {
+		g_warning ("fcntl() F_GETFL failed: %s", strerror (errno));
+		return FALSE;
+	}
+
+	val &= ~flags;
+	
+	val = fcntl (fd, F_SETFL, val);
+	if (val < 0) {
+		g_warning ("fcntl() F_SETFL failed: %s", strerror (errno));
+		return FALSE;
+	}
+	
+	return TRUE;
+
+}
 
Index: libgnomevfs/gnome-vfs-private-utils.h
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-private-utils.h,v
retrieving revision 1.19
diff -u -r1.19 gnome-vfs-private-utils.h
--- libgnomevfs/gnome-vfs-private-utils.h	10 Mar 2004 12:21:10 -0000	1.19
+++ libgnomevfs/gnome-vfs-private-utils.h	30 Mar 2004 13:57:32 -0000
@@ -88,6 +88,11 @@
 gboolean       _gnome_vfs_prepend_terminal_to_vector      (int          *argc,
 							   char       ***argv);
 
+gboolean       _gnome_vfs_set_fd_flags                    (int           fd,
+                                                           int           flags);
+gboolean       _gnome_vfs_clear_fd_flags                  (int           fd,
+                                                           int           flags);
+
 G_END_DECLS
 
 #endif /* _GNOME_VFS_PRIVATE_UTILS_H */
Index: libgnomevfs/gnome-vfs-inet-connection.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-inet-connection.c,v
retrieving revision 1.13
diff -u -r1.13 gnome-vfs-inet-connection.c
--- libgnomevfs/gnome-vfs-inet-connection.c	22 Jan 2004 12:29:09 -0000	1.13
+++ libgnomevfs/gnome-vfs-inet-connection.c	30 Mar 2004 13:49:06 -0000
@@ -35,6 +35,8 @@
 #include <netinet/in.h>
 #include <sys/socket.h>
 #include <sys/types.h>
+#include <sys/select.h>
+#include <fcntl.h>
 #include <unistd.h>
 
 /* AIX #defines h_errno */
@@ -49,6 +51,11 @@
 	struct sockaddr_in addr;
 	guint sock;
 	guint socklen;
+
+	GnomeVFSCancellation *cancellation;
+	guint pipe_cancel;
+	guint max_fds;
+
 };
 
 /**
@@ -185,6 +192,15 @@
 		new->sock = sock;
 
 	}
+
+	if (_gnome_vfs_set_fd_flags (new->sock, O_NONBLOCK)) {
+		new->pipe_cancel    = gnome_vfs_cancellation_get_fd (cancellation);
+		new->cancellation   = cancellation;
+		new->max_fds        = MAX (new->pipe_cancel, new->sock) + 1;
+	} else {
+		new->pipe_cancel = -1;
+	}
+
 	*connection_return = new;
 	return GNOME_VFS_OK;
 }
@@ -254,20 +270,49 @@
 		                GnomeVFSFileSize bytes,
 		                GnomeVFSFileSize *bytes_read)
 {
-	gint read_val;
+	gint     read_val;
+	fd_set   read_fds;
+
+read_loop:
+	read_val = read (connection->sock, buffer, bytes);
+
+	if (read_val == -1 && errno == EAGAIN) {
+
+		FD_ZERO (&read_fds);
+		FD_SET (connection->sock, &read_fds);
+		FD_SET (connection->pipe_cancel, &read_fds);
+		read_val = select (connection->max_fds, &read_fds, NULL, NULL, NULL);
 
-	do {
-		read_val = read (connection->sock, buffer, bytes);
-	} while (read_val == -1 && errno == EINTR);
+		if (read_val > -1) { 	
 
+			if (FD_ISSET (connection->sock, &read_fds)) {
+				goto read_loop;
+			}
+
+			if (FD_ISSET (connection->pipe_cancel, &read_fds)) {
+				return GNOME_VFS_ERROR_CANCELLED;
+			}
+		}
+	} 
+	
 	if (read_val == -1) {
 		*bytes_read = 0;
-		return gnome_vfs_result_from_errno ();
+
+		if (gnome_vfs_cancellation_check (connection->cancellation)) {
+			return GNOME_VFS_ERROR_CANCELLED;
+		} 
+		
+		if (errno == EINTR) {
+			goto read_loop;
+		} else {
+			return gnome_vfs_result_from_errno ();
+		}
+
 	} else {
 		*bytes_read = read_val;
 	}
 
-	return bytes_read == 0 ? GNOME_VFS_ERROR_EOF : GNOME_VFS_OK;
+	return *bytes_read == 0 ? GNOME_VFS_ERROR_EOF : GNOME_VFS_OK;
 }
 
 /**
@@ -288,15 +333,47 @@
 			         GnomeVFSFileSize bytes,
 			         GnomeVFSFileSize *bytes_written)
 {
-	gint write_val;
+	gint    write_val;
+	fd_set  write_fds;
+
+
+write_loop:	
+	write_val = write (connection->sock, buffer, bytes);
+		
+	if (write_val == -1 && errno == EAGAIN) {
+			
+         	FD_ZERO (&write_fds);
+		FD_SET (connection->sock, &write_fds);
+		FD_SET (connection->pipe_cancel, &write_fds);
+			
+		write_val = select (connection->max_fds, &write_fds, NULL, NULL, NULL);
+				
+		if (write_val > -1) { 	
+
+			if (FD_ISSET (connection->sock, &write_fds)) {
+				goto write_loop;
+			}
+
+			if (FD_ISSET (connection->pipe_cancel, &write_fds)) {
+				return GNOME_VFS_ERROR_CANCELLED;
+			}
+		}
+	}
 
-	do {
-		write_val = write (connection->sock, buffer, bytes);
-	} while (write_val == -1 && errno == EINTR);
 
 	if (write_val == -1) {
 		*bytes_written = 0;
-		return gnome_vfs_result_from_errno ();
+
+	        if (gnome_vfs_cancellation_check (connection->cancellation)) {
+			return GNOME_VFS_ERROR_CANCELLED;
+		}
+
+		if (errno == EINTR) {
+			goto write_loop;
+		} else {
+			return gnome_vfs_result_from_errno ();
+		}
+
 	} else {
 		*bytes_written = write_val;
 		return GNOME_VFS_OK;


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