Patch to do not write in chunks to filesystem



Hi,

we found in Modest that writing data (like saving a draft to a local
folder) to the internal flash of devices like N810 is terribly slow. The
problem was that we shouldn't use the write in chunks code that was
added to the camel_write function in camel-file-utils.c

Writing a big file in chunks of 64 bytes to a flash memory is horrible
because they're especially slow in writings.

This patch adds a new function that is like camel_write but receives a
new argument that tells it to write in chunks or not. The camel_write
function will NOT write in chunks (this way the old behaviour is
restored). The function that will use the write in chunks feature will
be camel_write_socket, that's it, operations that write in raw tcp
connections.

Br
Index: libtinymail-camel/camel-lite/camel/camel-file-utils.c
===================================================================
--- libtinymail-camel/camel-lite/camel/camel-file-utils.c	(revision 3775)
+++ libtinymail-camel/camel-lite/camel/camel-file-utils.c	(working copy)
@@ -569,23 +569,8 @@
 	return nread;
 }
 
-
-/**
- * camel_write:
- * @fd: file descriptor
- * @buf: buffer to write
- * @n: number of bytes of @buf to write
- *
- * Cancellable libc write() replacement.
- *
- * Code that intends to be portable to Win32 should call this function
- * only on file descriptors returned from open(), not on sockets.
- *
- * Returns number of bytes written or -1 on fail. On failure, errno will
- * be set appropriately.
- **/
-ssize_t
-camel_write (int fd, const char *buf, size_t n)
+static ssize_t
+camel_write_shared (int fd, const char *buf, size_t n, gboolean write_in_chunks)
 {
 	ssize_t w, written = 0;
 	int cancel_fd;
@@ -601,11 +586,13 @@
 #endif
 	if (cancel_fd == -1) {
 		do {
-			/* Write in chunks of max WRITE_CHUNK_SIZE bytes */
-			ssize_t actual = MIN (n - written, WRITE_CHUNK_SIZE);
-
 			do {
-				w = write (fd, buf + written, actual /* n - written */);
+				/* Write in chunks of max WRITE_CHUNK_SIZE bytes */
+				ssize_t actual = MIN (n - written, WRITE_CHUNK_SIZE);
+				if (write_in_chunks)
+					w = write (fd, buf + written, actual);
+				else
+					w = write (fd, buf + written, n - written);
 			} while (w == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
 			if (w > 0)
 				written += w;
@@ -625,9 +612,6 @@
 			struct timeval tv;
 			int res;
 
-			/* Write in chunks of max WRITE_CHUNK_SIZE bytes */
-			ssize_t actual = MIN (n - written, WRITE_CHUNK_SIZE);
-
 			FD_ZERO (&rdset);
 			FD_ZERO (&wrset);
 			FD_SET (fd, &wrset);
@@ -646,7 +630,12 @@
 				errno = EINTR;
 			else {
 				do {
-					w = write (fd, buf + written, actual /*n - written*/);
+				/* Write in chunks of max WRITE_CHUNK_SIZE bytes */
+				ssize_t actual = MIN (n - written, WRITE_CHUNK_SIZE);
+				if (write_in_chunks)
+					w = write (fd, buf + written, actual);
+				else
+					w = write (fd, buf + written, n - written);
 				} while (w == -1 && errno == EINTR);
 
 				if (w == -1) {
@@ -669,7 +658,28 @@
 	return written;
 }
 
+
+/**
+ * camel_write:
+ * @fd: file descriptor
+ * @buf: buffer to write
+ * @n: number of bytes of @buf to write
+ *
+ * Cancellable libc write() replacement.
+ *
+ * Code that intends to be portable to Win32 should call this function
+ * only on file descriptors returned from open(), not on sockets.
+ *
+ * Returns number of bytes written or -1 on fail. On failure, errno will
+ * be set appropriately.
+ **/
 ssize_t
+camel_write (int fd, const char *buf, size_t n)
+{
+	camel_write_shared (fd, buf, n, FALSE);
+}
+
+ssize_t
 camel_read_nb (int fd, char *buf, size_t n)
 {
 	ssize_t nread;
@@ -906,7 +916,7 @@
 camel_write_socket (int fd, const char *buf, size_t n)
 {
 #ifndef G_OS_WIN32
-	return camel_write (fd, buf, n);
+	return camel_write_shared (fd, buf, n, TRUE);
 #else
 	ssize_t w, written = 0;
 	int cancel_fd;


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