[vhffs-dev] [1279] The master is now using a dynamically allocated buffer for recv.

[ Thread Index | Date Index | More vhffs.org/vhffs-dev Archives ]


Revision: 1279
Author:   gradator
Date:     2008-10-13 20:44:48 +0200 (Mon, 13 Oct 2008)

Log Message:
-----------
The master is now using a dynamically allocated buffer for recv.

Modified Paths:
--------------
    trunk/vhffs-fssync/vhffsfssync_master.c
    trunk/vhffs-fssync/vhffsfssync_slave.c


Modified: trunk/vhffs-fssync/vhffsfssync_master.c
===================================================================
--- trunk/vhffs-fssync/vhffsfssync_master.c	2008-10-13 17:08:31 UTC (rev 1278)
+++ trunk/vhffs-fssync/vhffsfssync_master.c	2008-10-13 18:44:48 UTC (rev 1279)
@@ -72,7 +72,8 @@
 /* -- network stuff -- */
 // huge buffer size reduce syscalls
 #define VHFFSFSSYNC_NET_MESSAGE_FILE_CHUNK 65536
-#define VHFFSFSSYNC_NET_RECV_BUF_LEN 65536
+#define VHFFSFSSYNC_NET_RECV_CHUNK 65536
+#define VHFFSFSSYNC_NET_RECV_OVERFLOW 10485760
 
 GList *vhffsfssync_conns;
 
@@ -81,10 +82,10 @@
 	struct sockaddr_in sockaddr;
 	uint32_t order;
 
-	/* TODO: change that to a dynamically allocated buffer */
-	char recv_buf[VHFFSFSSYNC_NET_RECV_BUF_LEN];
-	uint32_t recv_buf_len;
-	char *recv_buf_cur;
+	char *recvbuf;
+	uint32_t recvbuf_begin;
+	uint32_t recvbuf_end;
+
 	char **delayedevents;
 	uint32_t delayedevents_begin;
 	uint32_t delayedevents_end;
@@ -230,6 +231,11 @@
 	conn->delayedevents = NULL;
 	conn->delayedevents_begin = 0;
 	conn->delayedevents_end = 0;
+
+	if(conn->recvbuf) free(conn->recvbuf);
+	conn->recvbuf = NULL;
+	conn->recvbuf_begin = 0;
+	conn->recvbuf_end = 0;
 }
 
 
@@ -809,11 +815,11 @@
 int vhffsfssync_net_parse(vhffsfssync_conn *conn)  {
 	char *cur, *end;
 
-	//fprintf(stderr, "Buffer %d\n", conn->recv_buf_len);
+	//fprintf(stderr, "Buffer %d\n", conn->recvbuf_len);
 
 	/* parse the buffer */
-	cur = conn->recv_buf;
-	end = conn->recv_buf + conn->recv_buf_len; //beware: end can be outside the buffer, you should NOT read *end
+	cur = conn->recvbuf + conn->recvbuf_begin;
+	end = conn->recvbuf + conn->recvbuf_end; //beware: end can be outside the buffer, you should NOT read *end
 
 	while(cur < end)  {
 		char *begin;
@@ -821,6 +827,8 @@
 		for(begin = cur ; ( cur < end && *cur++ != '\0' ) || ( cur < end && *cur++ != '\0' ) ; );
 
 		if( !*(cur-2) && !*(cur-1) ) {
+			register uint32_t len = cur - begin;
+
 			if(!conn->delayedevents  &&  conn->messages_num < 20) {
 				vhffsfssync_net_recv_event(conn, begin);
 			}
@@ -830,39 +838,39 @@
 					//printf("==> %d events, %d allocated\n", conn->delayedevents_end, ( (conn->delayedevents_end >>10) +1) <<10);
 					conn->delayedevents = realloc( conn->delayedevents, (((conn->delayedevents_end >>10) +1) <<10) * sizeof(char*) );
 				}
-				conn->delayedevents[conn->delayedevents_end] = malloc(cur - begin);
-				memcpy(conn->delayedevents[conn->delayedevents_end], begin, cur - begin);
+				conn->delayedevents[conn->delayedevents_end] = malloc(len);
+				memcpy(conn->delayedevents[conn->delayedevents_end], begin, len);
 				conn->delayedevents_end++;
 			}
 			begin = cur;
+			conn->recvbuf_begin += len;
 		}
 
 		if(cur == end)  {
-			register uint32_t len;
-			len = end - begin;
+			register uint32_t len = end - begin;
 			//fprintf(stderr, "Not parsed %d\n", len);
-//			fprintf(stderr, "buffer = %lu, cur = %lu, end = %lu, begin = %lu\n", (unsigned long)conn->recv_buf, (unsigned long)cur, (unsigned long)end, (unsigned long)begin);
 
-/*			int i;
-			char *toto;
-			for(toto = begin, i = 0 ; i < 1000 && toto < end ; toto++, i++) {
-				fprintf(stderr, "%x ", *toto);
-			}
-			fprintf(stderr, "\n"); */
+			if(len) {
+				if(len > VHFFSFSSYNC_NET_RECV_OVERFLOW) {
+					vhffsfssync_net_conn_disable(conn);
+					break;
+				}
 
-			// buffer is full and we didn't manage to fetch everything
-			if(len == VHFFSFSSYNC_NET_RECV_BUF_LEN)  {
-				fprintf(stderr, "The buffer is not large enough, throwing away the content\n");
-				conn->recv_buf_cur = conn->recv_buf;
-				conn->recv_buf_len = 0;
-				exit(1);
-				break;
+				// copy the data that is not parsed to the begin of the buffer if the data don't overlap
+				if(len <= conn->recvbuf_begin) {
+					//printf("Realloc to %d bytes\n", len);
+					memcpy(conn->recvbuf, begin, len);
+					conn->recvbuf = realloc( conn->recvbuf , len );
+					conn->recvbuf_begin = 0;
+					conn->recvbuf_end = len;
+				}
 			}
-
-			// copy the data that is not parsed to the begin of the buffer
-			memcpy(conn->recv_buf, begin, len);
-			conn->recv_buf_cur = conn->recv_buf + len;
-			conn->recv_buf_len = len;
+			else {
+				free(conn->recvbuf);
+				conn->recvbuf = NULL;
+				conn->recvbuf_begin = 0;
+				conn->recvbuf_end = 0;
+			}
 			break;
 		}
 	}
@@ -1483,7 +1491,7 @@
 	uint16_t bindport;
 	struct sockaddr_in src;
 
-	srand(time(NULL));
+//	srand(time(NULL));
 
 	/* chdir() to the filesystem to monitor */
 	root = argv[1];
@@ -1677,10 +1685,6 @@
 					}
 				}
 				else {
-					//char *grosbuf;
-					//grosbuf=malloc(104857600);
-					//memset(grosbuf, 'A', 104857600);
-
 					// We don't need the reverse DNS, the code here is for learning purpose
 					//ent = gethostbyaddr((const void*)&addr.sin_addr, sizeof(sizeof(addr.sin_addr)), AF_INET);
 					//if(ent) printf("And you are %s\n", ent->h_name);
@@ -1697,8 +1701,9 @@
 					conn->fd = newfd;
 					conn->sockaddr = addr;
 					conn->order = 0;
-					conn->recv_buf_len = 0;
-					conn->recv_buf_cur = conn->recv_buf;
+					conn->recvbuf = NULL;
+					conn->recvbuf_begin = 0;
+					conn->recvbuf_end = 0;
 					conn->delayedevents = NULL;
 					conn->delayedevents_begin = 0;
 					conn->delayedevents_end = 0;
@@ -1712,33 +1717,6 @@
 					printf("Welcome %s ! (using fd %d)\n", inet_ntoa(conn->sockaddr.sin_addr), conn->fd);
 #endif
 					vhffsfssync_net_send_event(conn, g_strdup_printf("hello%c", '\0') , VHFFSFSSYNC_NET_PRIO_HIGHEST);
-/*
-					grosbuf=malloc(10485760);
-					memset(grosbuf, 'A', 10485760);
-					vhffsfssync_net_send_data(conn, grosbuf, 1048576, 3);
-
-					grosbuf=malloc(10485760);
-					memset(grosbuf, 'B', 10485760);
-					vhffsfssync_net_send_data(conn, grosbuf, 1048576, 2);
-
-					grosbuf=malloc(10485760);
-					memset(grosbuf, 'C', 10485760);
-					vhffsfssync_net_send_data(conn, grosbuf, 1048576, 1);
-
-					grosbuf=malloc(10485760);
-  					memset(grosbuf, 'D', 10485760);
-					vhffsfssync_net_send_data(conn, grosbuf, 1048576, 0);
-*/
-					//vhffsfssync_net_send_data(conn, strdup("Salut!\n"), strlen("Salut!\n"), 2);
-					//vhffsfssync_net_send_data(conn, strdup("Salut!\n"), strlen("Salut!\n"), 2);
-					//vhffsfssync_net_send_data(conn, strdup("Salut!\n"), strlen("Salut!\n"), 0);
-					//vhffsfssync_net_send_data(conn, strdup("Salut!\n"), strlen("Salut!\n"), 1);
-					//vhffsfssync_net_send_data(conn, strdup("Salut!\n"), strlen("Salut!\n"), 1);
-					//vhffsfssync_net_send_data(conn, strdup("Salut!\n"), strlen("Salut!\n"), 0);
-					//vhffsfssync_net_send_data(conn, strdup("Salut!\n"), strlen("Salut!\n"), 2);
-					//vhffsfssync_net_send_data(conn, strdup("Salut!\n"), strlen("Salut!\n"), 0);
-					//vhffsfssync_net_write(conn, "Salut!\n", strlen("Salut!\n"));
-	 				//vhffsfssync_net_write(conn, grosbuf, 104857600);
 				}
 			}
 
@@ -1747,18 +1725,20 @@
 				vhffsfssync_conn *conn = conns->data;
 				conns = g_list_next(conns);
 
-				/* data to read ?, gimme gimme ! */
+				/* data to read ?, give give ! */
 				if( FD_ISSET(conn->fd, &readfs)  )  {
 					ssize_t len;
 
-					len = read(conn->fd, conn->recv_buf_cur, VHFFSFSSYNC_NET_RECV_BUF_LEN - (conn->recv_buf_cur - conn->recv_buf) );
+					//fprintf(stdout, "Alloc %d bytes\n", conn->recvbuf_end + VHFFSFSSYNC_NET_RECV_CHUNK);
+					conn->recvbuf = realloc( conn->recvbuf , conn->recvbuf_end + VHFFSFSSYNC_NET_RECV_CHUNK );
+					len = read(conn->fd, conn->recvbuf+conn->recvbuf_end, VHFFSFSSYNC_NET_RECV_CHUNK);
 					if(len < 0)  {
 						switch(errno)  {
 							case EAGAIN:
 							case EINTR:
 								break;
 							default:
-								fprintf(stderr, "read() failed on socket %d: %s\n", conn->fd, strerror(errno));
+								fprintf(stdout, "read() failed on socket %d: %s\n", conn->fd, strerror(errno));
 								vhffsfssync_net_conn_disable(conn);
 						}
 					}
@@ -1766,8 +1746,8 @@
 						vhffsfssync_net_conn_disable(conn);
 					}
 					else {
-						//fprintf(stderr, "Read %d\n", len);
-						conn->recv_buf_len += len;
+						//fprintf(stdout, "Read %d, buffer is %lu, begin is %lu, end is %lu\n", len, (unsigned long)conn->recvbuf, (unsigned long)conn->recvbuf_begin, (unsigned long)conn->recvbuf_end);
+						conn->recvbuf_end += len;
 						vhffsfssync_net_parse(conn);
 					}
 				}

Modified: trunk/vhffs-fssync/vhffsfssync_slave.c
===================================================================
--- trunk/vhffs-fssync/vhffsfssync_slave.c	2008-10-13 17:08:31 UTC (rev 1278)
+++ trunk/vhffs-fssync/vhffsfssync_slave.c	2008-10-13 18:44:48 UTC (rev 1279)
@@ -509,13 +509,12 @@
 			printf("binary mode: read: %d stilltoread: %d\n", canread, conn->chunk_stilltoread);
 #endif
 			if(conn->chunk_file) {
-				/* TODO: handle errors and use a bigger nmemb */
 				size_t len = fwrite(cur, 1, canread, conn->chunk_file);
 #if DEBUG_EVENTS
 				printf("  written=%d\n", len);
 #endif
 				if(len != canread)  {
-					/* TODO: Handle errors */
+					fprintf(stderr, "fwrite() failed: %s\n", strerror(errno));
 				}
 				if(!conn->chunk_stilltoread) {
 #if DEBUG_EVENTS
@@ -625,10 +624,6 @@
 		vhffsfssync_net_send_event(conn, g_strdup_printf("hello%c", '\0') );
 		vhffsfssync_net_send_event(conn, g_strdup_printf("fulltree%c", '\0') );
 
-		//char *grosbuf=malloc(10485760);
-		//memset(grosbuf, 'D', 10485760);
-		//vhffsfssync_net_send_data(conn, grosbuf, 10485760);
-
 		/* -- the real main loop starts here -- */
 		while(1)  {
 			int max_fd = 0;
@@ -657,7 +652,7 @@
 				}
 			}
 			if(ret > 0)  {
-				/* data to read ?, gimme gimme ! */
+				/* data to read ?, give give ! */
 				if(FD_ISSET(conn->fd, &readfs)  )  {
 					ssize_t len;
 


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/