[vhffs-dev] [1263] fixed segfault (again)when a connection disappear, improved error messages, removed some recursion to prevent a huge stack size

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


Revision: 1263
Author:   gradator
Date:     2008-10-07 13:04:17 +0200 (Tue, 07 Oct 2008)

Log Message:
-----------
fixed segfault (again)when a connection disappear, improved error messages, removed some recursion to prevent a huge stack size

Modified Paths:
--------------
    trunk/vhffs-fssync/client.c
    trunk/vhffs-fssync/getevents.c


Modified: trunk/vhffs-fssync/client.c
===================================================================
--- trunk/vhffs-fssync/client.c	2008-10-06 23:21:31 UTC (rev 1262)
+++ trunk/vhffs-fssync/client.c	2008-10-07 11:04:17 UTC (rev 1263)
@@ -2,6 +2,7 @@
 #define _ATFILE_SOURCE
 
 #define DEBUG_NET 0
+#define DEBUG_EVENTS 0
 
 #include <unistd.h>
 #include <stdio.h>
@@ -128,7 +129,6 @@
 int coucou_event(coucou_conn *conn, char *event)  {
 	char *cur, *args[10];
 	int argc;
-	int i;
 
 	argc = 0;
 	cur = event;
@@ -143,10 +143,13 @@
 
 	if(!argc) return -1;
 
+#if DEBUG_EVENTS
+	int i;
 	for(i = 0 ; i < argc ; i++) {
 		printf("%s ", args[i]);
 	}
 	printf("\n");
+#endif
 
 	if(!strcmp(args[0], "remove")) {
 		char *pathname = args[1];
@@ -275,14 +278,22 @@
 		else {
 			size_t canread = MIN(conn->chunk_stilltoread, end-cur);
 			conn->chunk_stilltoread -= canread;
-
+#if DEBUG_EVENTS
 			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 */
+				}
 				if(!conn->chunk_stilltoread) {
-					printf("closing file\n");
+#if DEBUG_EVENTS
+					printf("  closing file\n");
+#endif
 					fclose(conn->chunk_file);
 					conn->chunk_file = NULL;
 				}
@@ -395,7 +406,7 @@
 							case EINTR:
 								break;
 							default:
-								fprintf(stderr, "read() failed on socket fd: %s\n", strerror(errno));
+								fprintf(stderr, "read() failed on socket %d: %s\n", conn->fd, strerror(errno));
 								conn->fd = -1;
 								break;
 						}

Modified: trunk/vhffs-fssync/getevents.c
===================================================================
--- trunk/vhffs-fssync/getevents.c	2008-10-06 23:21:31 UTC (rev 1262)
+++ trunk/vhffs-fssync/getevents.c	2008-10-07 11:04:17 UTC (rev 1263)
@@ -1,7 +1,7 @@
 #define _FILE_OFFSET_BITS 64
 
 #define DEBUG_NET 0
-#define DEBUG_INOTIFY 1
+#define DEBUG_INOTIFY 0
 
 #include <unistd.h>
 #include <stdio.h>
@@ -157,6 +157,7 @@
 
 
 // protos
+void coucou_net_conn_disable(coucou_conn *conn);
 void coucou_net_conn_destroy(coucou_conn *conn);
 inline coucou_net_message *coucou_net_new_message(coucou_conn *conn, msg_family_t family, uint32_t priority);
 gint coucou_net_message_insert_compare(gconstpointer a, gconstpointer b);
@@ -175,21 +176,27 @@
 
 
 /* ----------------------------------------- */
-
-void coucou_net_conn_destroy(coucou_conn *conn)  {
+void coucou_net_conn_disable(coucou_conn *conn)  {
 	GList *msgs;
 
-	coucou_conns = g_list_remove(coucou_conns, conn);
-
 	if(conn->fd >= 0) {
+#if DEBUG_NET
+		printf("Byebye %s... (used fd %d)\n", inet_ntoa(conn->sockaddr.sin_addr), conn->fd);
+#endif
 		shutdown(conn->fd, SHUT_RDWR);
 		close(conn->fd);
 	}
+	conn->fd = -1;
 
 	while( (msgs = g_list_first(conn->messages)) )  {
 		coucou_net_destroy_message(conn, (coucou_net_message*)msgs->data );
 	}
+}
 
+
+void coucou_net_conn_destroy(coucou_conn *conn)  {
+	coucou_conns = g_list_remove(coucou_conns, conn);
+	coucou_net_conn_disable(conn);
 	free(conn);
 }
 
@@ -239,8 +246,6 @@
 	msg->data_cur = 0;
 	conn->messages = g_list_insert_sorted(conn->messages, msg, coucou_net_message_insert_compare);
 
-	// try to send the message right away
-	coucou_net_send(conn);
 	return 0;
 }
 
@@ -313,8 +318,6 @@
 	msg->file_chunkcur = 0;
 	conn->messages = g_list_insert_sorted(conn->messages, msg, coucou_net_message_insert_compare);
 
-	// try to send the file right away
-	coucou_net_send(conn);
 	return 0;
 }
 
@@ -429,7 +432,7 @@
 	printf("--------------------------------------------------\n");
 	printf("conn: %d, to: %s\n", conn->fd, inet_ntoa(conn->sockaddr.sin_addr));
 #endif
-	while(!full  &&  conn  &&  (msgs = g_list_first(conn->messages)) )  {
+	while(!full  &&  conn->fd >= 0  &&  (msgs = g_list_first(conn->messages)) )  {
 		coucou_net_message *msg = msgs->data;
 #if DEBUG_NET
  		printf("  family: %d , priority: %d , order: %d\n", msg->msg_family, msg->msg_priority, msg->msg_order);
@@ -460,9 +463,8 @@
 						full = TRUE;
 						break;
 					default:
-						fprintf(stderr, "write() failed on socket fd: %s\n", strerror(errno));
-						coucou_net_conn_destroy(conn);
-						conn = NULL;
+						fprintf(stderr, "write() failed on socket %d: %s\n", conn->fd, strerror(errno));
+						coucou_net_conn_disable(conn);
 				}
 			}
 			else {
@@ -506,8 +508,8 @@
 				// we need to make sure that the chunk will not be truncated, we set the current message to the highest priority
 				msg->msg_priority = 1;
 				coucou_net_send_string(conn, g_strdup_printf("write\x1F%s\x1F%lld\x1F%lld\n", filemsg->file_pathname, (long long int)filemsg->file_offset, (long long int)filemsg->file_chunksize) , 0);
-				// coucou_net_send_string() called coucou_net_send() too, we really need to break here
-				break;
+				// we need to reset here in order to consider the new priorities
+				continue;
 			}
 			/* the previous chunk was partially sent */
 			else  {
@@ -526,9 +528,8 @@
 						full = TRUE;
 						break;
 					default:
-						fprintf(stderr, "sendfile() failed from file %s to socket: %s\n", filemsg->file_pathname, strerror(errno));
-						coucou_net_conn_destroy(conn);
-						conn = NULL;
+						fprintf(stderr, "sendfile() failed from file %s to socket %d: %s\n", filemsg->file_pathname, conn->fd, strerror(errno));
+						coucou_net_conn_disable(conn);
 				}
 			}
 			else {
@@ -588,7 +589,7 @@
 						printf("=====> EAGAIN on write()\n");
 						break;
 					default:
-						fprintf(stderr, "write() failed on socket fd: %s\n", strerror(errno));
+						fprintf(stderr, "write() failed on socket %d: %s\n", conn->fd, strerror(errno));
 				}
 				written = 0;
 			}
@@ -624,7 +625,7 @@
 					printf("=====> EAGAIN on write()\n");
 					break;
 				default:
-					fprintf(stderr, "write() failed on socket fd: %s\n", strerror(errno));
+					fprintf(stderr, "write() failed on socket %d: %s\n", conn->fd, strerror(errno));
 			}
 			written = 0;
 		}
@@ -1101,7 +1102,7 @@
 	/* add the ability to listen on a TIME_WAIT */
 	opt = 1;
 	if( setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt) ) )  {
-		fprintf(stderr, "setsockopt() failed: %s\n", strerror(errno));
+		fprintf(stderr, "setsockopt() failed on socket %d: %s\n", listenfd, strerror(errno));
 	}
 
 	bindaddr = INADDR_ANY;
@@ -1110,12 +1111,12 @@
 	src.sin_family = AF_INET;
 	src.sin_port = htons(bindport);
 	if( bind(listenfd, (struct sockaddr*)&src, sizeof(src) ) < 0) {
-		fprintf(stderr, "bind() failed: %s\n", strerror(errno));
+		fprintf(stderr, "bind() failed on socket %d: %s\n", listenfd, strerror(errno));
 		return -1;
 	}
 
 	if( listen(listenfd, SOMAXCONN) < 0) {
-		fprintf(stderr, "listen() failed: %s\n", strerror(errno));
+		fprintf(stderr, "listen() failed on socket %d: %s\n", listenfd, strerror(errno));
 		return -1;
 	}
 
@@ -1148,6 +1149,12 @@
 			coucou_conn *conn = conns->data;
 			conns = g_list_next(conns);
 
+			/* this connnection was disabled, destroy it */
+			if(conn->fd < 0) {
+				coucou_net_conn_destroy(conn);
+				continue;
+			}
+
 			FD_SET(conn->fd, &readfs);
 			if(conn->messages) FD_SET(conn->fd, &writefs);
 			if(conn->fd > max_fd) max_fd = conn->fd;
@@ -1178,7 +1185,7 @@
 						case EINTR:
 							break;
 						default:
-							fprintf(stderr, "read() failed on inotify fd: %s\n", strerror(errno));
+							fprintf(stderr, "read() failed on inotify fd(%d): %s\n", inotifyfd, strerror(errno));
 					}
 				}
 				else {
@@ -1213,7 +1220,7 @@
 						case EINTR:
 							break;
 						default:
-							fprintf(stderr, "accept() failed on listen fd: %s\n", strerror(errno));
+							fprintf(stderr, "accept() failed on listen fd(%d): %s\n", listenfd, strerror(errno));
 					}
 				}
 				else {
@@ -1248,7 +1255,7 @@
 #if DEBUG_NET
 					printf("Welcome %s ! (using fd %d)\n", inet_ntoa(conn->sockaddr.sin_addr), conn->fd);
 #endif
-					coucou_net_send_data(conn, strdup("hello\n"), strlen("hello\n"), 2);
+					coucou_net_send_string(conn, strdup("hello\n"), COUCOU_NET_PRIO_HIGHEST);
 /*
 					grosbuf=malloc(10485760);
 					memset(grosbuf, 'A', 10485760);
@@ -1296,17 +1303,12 @@
 							case EINTR:
 								break;
 							default:
-								fprintf(stderr, "read() failed on socket fd: %s\n", strerror(errno));
-								coucou_net_conn_destroy(conn);
-								conn = NULL;
+								fprintf(stderr, "read() failed on socket %d: %s\n", conn->fd, strerror(errno));
+								coucou_net_conn_disable(conn);
 						}
 					}
 					else if(len == 0) {
-#if DEBUG_NET
-						printf("Byebye %s... (used fd %d)\n", inet_ntoa(conn->sockaddr.sin_addr), conn->fd);
-#endif
-						coucou_net_conn_destroy(conn);
-						conn = NULL;
+						coucou_net_conn_disable(conn);
 					}
 					else {
 						char *plop = malloc(len+1);


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