[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;