changeset 15218:ec96d6d2fa6d

[gaim-migrate @ 18008] Patch from Graham Booker to slowly scale up the size of our read or write buffer when transfer files over fast networks. This should hopefully reduce CPU load a tiny bit when transfer large files over fast connections. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Fri, 15 Dec 2006 08:39:53 +0000
parents 717935e035ca
children 4bf7801a2539
files libgaim/ft.c libgaim/ft.h
diffstat 2 files changed, 33 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/libgaim/ft.c	Fri Dec 15 08:23:28 2006 +0000
+++ b/libgaim/ft.c	Fri Dec 15 08:39:53 2006 +0000
@@ -31,6 +31,9 @@
 #include "request.h"
 #include "util.h"
 
+#define FT_INITIAL_BUFFER_SIZE 4096
+#define FT_MAX_BUFFER_SIZE     65535
+
 static GaimXferUiOps *xfer_ui_ops = NULL;
 
 static int gaim_xfer_choose_file(GaimXfer *xfer);
@@ -53,6 +56,7 @@
 	xfer->who     = g_strdup(who);
 	xfer->ui_ops  = gaim_xfers_get_ui_ops();
 	xfer->message = NULL;
+	xfer->current_buffer_size = FT_INITIAL_BUFFER_SIZE;
 
 	ui_ops = gaim_xfer_get_ui_ops(xfer);
 
@@ -781,6 +785,13 @@
 	xfer->ops.cancel_recv = fnc;
 }
 
+static void
+gaim_xfer_increase_buffer_size(GaimXfer *xfer)
+{
+	xfer->current_buffer_size = MIN(xfer->current_buffer_size * 1.5,
+			FT_MAX_BUFFER_SIZE);
+}
+
 gssize
 gaim_xfer_read(GaimXfer *xfer, guchar **buffer)
 {
@@ -790,9 +801,9 @@
 	g_return_val_if_fail(buffer != NULL, 0);
 
 	if (gaim_xfer_get_size(xfer) == 0)
-		s = 4096;
+		s = xfer->current_buffer_size;
 	else
-		s = MIN(gaim_xfer_get_bytes_remaining(xfer), 4096);
+		s = MIN(gaim_xfer_get_bytes_remaining(xfer), xfer->current_buffer_size);
 
 	if (xfer->ops.read != NULL)
 		r = (xfer->ops.read)(buffer, xfer);
@@ -811,6 +822,14 @@
 			r = -1;
 	}
 
+	if (r == xfer->current_buffer_size)
+		/*
+		 * We managed to read the entire buffer.  This means our this
+		 * network is fast and our buffer is too small, so make it
+		 * bigger.
+		 */
+		gaim_xfer_increase_buffer_size(xfer);
+
 	return r;
 }
 
@@ -857,7 +876,7 @@
 	}
 
 	if (condition & GAIM_INPUT_WRITE) {
-		size_t s = MIN(gaim_xfer_get_bytes_remaining(xfer), 4096);
+		size_t s = MIN(gaim_xfer_get_bytes_remaining(xfer), xfer->current_buffer_size);
 
 		/* this is so the prpl can keep the connection open
 		   if it needs to for some odd reason. */
@@ -883,6 +902,13 @@
 		} else if (r < s) {
 			/* We have to seek back in the file now. */
 			fseek(xfer->dest_fp, r - s, SEEK_CUR);
+		} else {
+			/*
+			 * We managed to write the entire buffer.  This means our
+			 * network is fast and our buffer is too small, so make it
+			 * bigger.
+			 */
+			gaim_xfer_increase_buffer_size(xfer);
 		}
 	}
 
--- a/libgaim/ft.h	Fri Dec 15 08:23:28 2006 +0000
+++ b/libgaim/ft.h	Fri Dec 15 08:39:53 2006 +0000
@@ -84,7 +84,7 @@
  */
 struct _GaimXfer
 {
-	guint ref;                    /**< The reference count.                 */
+	guint ref;                    /**< The reference count.                */
 	GaimXferType type;            /**< The type of transfer.               */
 
 	GaimAccount *account;         /**< The account.                        */
@@ -111,6 +111,9 @@
 	time_t start_time;            /**< When the transfer of data began.    */
 	time_t end_time;              /**< When the transfer of data ended.    */
 
+	size_t current_buffer_size;   /**< This gradually increases for fast
+	                                   network connections. */
+
 	GaimXferStatusType status;    /**< File Transfer's status.             */
 
 	/* I/O operations. */