Re: [Rhythmbox-devel] Monitoring DAAP usage



On Wed, Oct 19, 2005 at 08:50:20PM +1000, Jonathan Matthew wrote:
> The DAAP server code currently reads the whole file into memory in order
> to send it to the client.  It really should be fixed so it only reads in
> small chunks, but that doesn't look too easy.  

I may have spoken too soon.


Index: daapsharing/rb-daap-share.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/daapsharing/rb-daap-share.c,v
retrieving revision 1.5
diff -u -r1.5 rb-daap-share.c
--- daapsharing/rb-daap-share.c	11 Sep 2005 10:31:45 -0000	1.5
+++ daapsharing/rb-daap-share.c	19 Oct 2005 12:27:41 -0000
@@ -59,6 +59,9 @@
 #define CONF_NAME CONF_PREFIX "/sharing/share_name"
 #define STANDARD_DAAP_PORT 3689
 
+/* HTTP chunk size used to send files to clients */
+#define DAAP_SHARE_CHUNK_SIZE	16384
+
 struct RBDAAPSharePrivate {
 	gchar *name;
 	guint port;
@@ -753,6 +756,24 @@
 	return bits;
 }
 
+static void
+write_next_chunk (SoupMessage *message, GnomeVFSHandle *handle)
+{
+	GnomeVFSFileSize read_size;
+	GnomeVFSResult result;
+	gchar *chunk = g_malloc (DAAP_SHARE_CHUNK_SIZE);
+
+	result = gnome_vfs_read (handle, chunk, DAAP_SHARE_CHUNK_SIZE, &read_size);
+	if (result != GNOME_VFS_OK || read_size == 0) {
+		g_free (chunk);
+		gnome_vfs_close (handle);
+		soup_message_add_final_chunk (message);
+		return;
+	}
+
+	soup_message_add_chunk (message, SOUP_BUFFER_SYSTEM_OWNED, chunk, read_size);
+}
+
 static void 
 databases_cb (RBDAAPShare *share, 
 	      SoupMessage *message)
@@ -931,7 +952,6 @@
 		GnomeVFSResult result;
 		GnomeVFSHandle *handle;
 		const gchar *range_header;
-		gchar *buf;
 		guint status_code = SOUP_STATUS_OK;
 		
 		id_str = rest_of_path + 9;
@@ -972,35 +992,12 @@
 
 			file_size -= range;
 		}
-		
-		/* FIXME FIXME FIXME
-		 * Ideally, it seems that an mmap type solution should be used
-		 * here.  However, this works for now.
-		 */
-		buf = g_try_malloc (file_size);
-		if (buf == NULL) {
-			g_warning ("Unable to malloc %"G_GUINT64_FORMAT" bytes to transfer file", file_size);
-			soup_message_set_status (message, SOUP_STATUS_INTERNAL_SERVER_ERROR);
-			goto out;
-		}
 
-		result = gnome_vfs_read (handle, buf, file_size, NULL);
-		if (result != GNOME_VFS_OK) {
-			soup_message_set_status (message, SOUP_STATUS_INTERNAL_SERVER_ERROR);
-			g_free (buf);
-			goto out;
-		}
-		
-		message_add_standard_headers (message);
-		soup_message_add_header (message->response_headers, "Accept-Ranges", "bytes");
-		message->response.owner = SOUP_BUFFER_SYSTEM_OWNED;
-		message->response.length = file_size;
-		message->response.body = buf;
-
-		gnome_vfs_close (handle);
-	
+		write_next_chunk (message, handle);
+		g_signal_connect (message, "wrote_chunk", G_CALLBACK (write_next_chunk), handle);
+		 
 		soup_message_set_status (message, status_code);
-		soup_server_message_set_encoding (SOUP_SERVER_MESSAGE (message), SOUP_TRANSFER_CONTENT_LENGTH);
+		soup_server_message_set_encoding (SOUP_SERVER_MESSAGE (message), SOUP_TRANSFER_CHUNKED);
 
 	} else {
 		g_print ("unhandled: %s\n", path);


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