Cancellation for GnomeVFSInetConnecton
- From: Christian Kellner <gicmo xatom net>
- To: "gnome-vfs-list gnome org" <gnome-vfs-list gnome org>
- Subject: Cancellation for GnomeVFSInetConnecton
- Date: Tue, 30 Mar 2004 16:06:03 +0200
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]