[ekg2-commit] r4237 - trunk/ekg: trunk/ekg/net.c trunk/ekg/net.h

SVN commit svn w toxygen.net
Pią, 8 Sie 2008, 17:09:54 CEST


Author: peres
Date: 2008-08-08 17:09:54 +0200 (Fri, 08 Aug 2008)
New Revision: 4237

Modified:
   trunk/ekg/net.c
   trunk/ekg/net.h
Log:

Totally fix connection aborting, now everything should work fine.

ekg_connect() returns pointer to 'watch', which needs to be freed when connecting is cancelled.



Modified: trunk/ekg/net.c
===================================================================
--- trunk/ekg/net.c	2008-08-08 13:53:08 UTC (rev 4236)
+++ trunk/ekg/net.c	2008-08-08 15:09:54 UTC (rev 4237)
@@ -319,6 +319,7 @@
 	char	**resolver_queue;	/* here we keep list of domains to be resolved	*/
 	char	**connect_queue;	/* here we keep list of IPs to try to connect	*/
 	watch_t	*current_watch;
+	watch_t	*internal_watch;	/* allowing user to abort connecting */
 
 		/* data provided by user */
 	int	port;
@@ -328,8 +329,10 @@
 };
 
 static void ekg_connect_data_free(struct ekg_connect_data *c) {
-	/* XXX: call async with type==1? */
-
+	if (c->internal_watch) {
+		c->internal_watch->data = NULL;	/* avoid double free */
+		watch_free(c->internal_watch);
+	}
 	array_free(c->resolver_queue);
 	array_free(c->connect_queue);
 	xfree(c->session);
@@ -469,18 +472,19 @@
 	socklen_t res_size = sizeof(res);
 	session_t *s;
 	int abort;
-	
+
 	if (!c)
 		return -1;
 
 	debug_function("ekg_connect_handler(), type = %d.\n", type);
 
+	if (type == 1)
+		return 0;
+
 	s = session_find(c->session);
 	abort = (!((s = session_find(c->session))) || !(s->connecting));
 
-	if (type == 1)
-		return 0;
-	else if (abort) {
+	if (abort) {
 		ekg_connect_loop(c);
 		close(fd);
 		return -1;
@@ -501,7 +505,7 @@
 		close(fd);
 	} else
 		ekg_connect_data_free(c);
-	
+
 	return -1;
 }
 
@@ -586,7 +590,25 @@
 	return 0;
 }
 
-int ekg_connect(session_t *session, const char *server, const int port, int (*prefer_comparison)(const char *, const char *), watcher_handler_func_t async) {
+static WATCHER(ekg_connect_abort) {
+	struct ekg_connect_data *c = (struct ekg_connect_data*) data;
+
+	if (type == 1) {
+		if (data) {
+			c->internal_watch		= NULL;	/* avoid freeing twice */
+			c->current_watch->data		= NULL;	/* avoid running handler, just make watch disappear */
+			watch_free(c->current_watch);
+			ekg_connect_data_free(c);
+
+			debug_function("ekg_connect_abort(), data freed.\n");
+		}
+	} else
+		debug_error("ekg_connect_abort() called with incorrect type!\n");
+
+	return -1;
+}
+
+watch_t *ekg_connect(session_t *session, const char *server, const int port, int (*prefer_comparison)(const char *, const char *), watcher_handler_func_t async) {
 	struct ekg_connect_data	*c;
 
 	if (!session || !server || !async)
@@ -600,7 +622,15 @@
 	c->prefer_comparison	= prefer_comparison;
 	c->port			= port;
 
+	c->internal_watch		= xmalloc(sizeof(watch_t));
+	c->internal_watch->type		= WATCH_NONE;
+	c->internal_watch->handler	= ekg_connect_abort;
+	c->internal_watch->data		= c;
+
 	/* 2) call in the loop */
-	return ekg_connect_loop(c);
+	ekg_connect_loop(c);
+
+	/* 3) return internal watch, allowing caller to abort */
+	return c->internal_watch;
 }
 

Modified: trunk/ekg/net.h
===================================================================
--- trunk/ekg/net.h	2008-08-08 13:53:08 UTC (rev 4236)
+++ trunk/ekg/net.h	2008-08-08 15:09:54 UTC (rev 4237)
@@ -31,7 +31,7 @@
 watch_t *ekg_resolver2(plugin_t *plugin, const char *server, watcher_handler_func_t async, void *data);
 watch_t *ekg_resolver3(plugin_t *plugin, const char *server, watcher_handler_func_t async, void *data);
 
-int ekg_connect(session_t *session, const char *server, const int port, int (*prefer_comparison)(const char *, const char *), watcher_handler_func_t async);
+watch_t *ekg_connect(session_t *session, const char *server, const int port, int (*prefer_comparison)(const char *, const char *), watcher_handler_func_t async);
 
 #endif /* EKG2_WIN32_NOFUNCTION */
 #endif /* __EKG_NET_H */



Więcej informacji o liście dyskusyjnej ekg2-commit