diff options
| author | Wilmer van der Gaast <wilmer@gaast.net> | 2006-05-13 21:01:14 +0200 | 
|---|---|---|
| committer | Wilmer van der Gaast <wilmer@gaast.net> | 2006-05-13 21:01:14 +0200 | 
| commit | 782d988a88582a0f3dd6539664d535fb790df024 (patch) | |
| tree | fa8d1bc22b6f96611111794bb2a9caf016a5e728 /protocols | |
| parent | 309cb9e19395261d020f7ea649807ff1adbe76de (diff) | |
libevent code works better with epoll() now in some (pretty common) situations.
Diffstat (limited to 'protocols')
| -rw-r--r-- | protocols/events.h | 8 | ||||
| -rw-r--r-- | protocols/events_glib.c | 2 | ||||
| -rw-r--r-- | protocols/events_libevent.c | 78 | ||||
| -rw-r--r-- | protocols/ssl_openssl.c | 2 | 
4 files changed, 65 insertions, 25 deletions
| diff --git a/protocols/events.h b/protocols/events.h index 5b684f8c..a61dc98c 100644 --- a/protocols/events.h +++ b/protocols/events.h @@ -39,8 +39,8 @@  #include <gmodule.h>  typedef enum { -	GAIM_INPUT_READ = 1 << 0, -	GAIM_INPUT_WRITE = 1 << 1 +	GAIM_INPUT_READ = 1 << 1, +	GAIM_INPUT_WRITE = 1 << 2  } b_input_condition;  typedef gboolean (*b_event_handler)(gpointer data, gint fd, b_input_condition cond); @@ -48,8 +48,8 @@ typedef gboolean (*b_event_handler)(gpointer data, gint fd, b_input_condition co  #define GAIM_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL)  #define GAIM_ERR_COND   (G_IO_HUP | G_IO_ERR | G_IO_NVAL) -// #define event_debug( x... ) printf( x ) -#define event_debug( x... ) +#define event_debug( x... ) printf( x ) +// #define event_debug( x... )  G_MODULE_EXPORT void b_main_init();  G_MODULE_EXPORT void b_main_run(); diff --git a/protocols/events_glib.c b/protocols/events_glib.c index 01265fd8..ff6e5a74 100644 --- a/protocols/events_glib.c +++ b/protocols/events_glib.c @@ -130,7 +130,7 @@ gint b_timeout_add(gint timeout, b_event_handler func, gpointer data)  void b_event_remove(gint tag)  { -	event_debug( "g_source_remove( %d )\n", tag ); +	event_debug( "b_event_remove( %d )\n", tag );  	if (tag > 0)  		g_source_remove(tag); diff --git a/protocols/events_libevent.c b/protocols/events_libevent.c index bcfb3b45..d4767348 100644 --- a/protocols/events_libevent.c +++ b/protocols/events_libevent.c @@ -38,6 +38,13 @@  static guint id_next;  static GHashTable *id_hash; +/* Since libevent doesn't handle two event handlers for one fd-condition +   very well (which happens sometimes when BitlBee changes event handlers +   for a combination), let's buid some indexes so we can delete them here +   already, just in time. */ +static GHashTable *read_hash; +static GHashTable *write_hash; +  struct b_event_data  {  	guint id; @@ -52,6 +59,8 @@ void b_main_init()  	id_next = 1;  	id_hash = g_hash_table_new( g_int_hash, g_int_equal ); +	read_hash = g_hash_table_new( g_int_hash, g_int_equal ); +	write_hash = g_hash_table_new( g_int_hash, g_int_equal );  }  void b_main_run() @@ -96,26 +105,49 @@ static void b_event_passthrough( int fd, short event, void *data )  gint b_input_add( gint fd, b_input_condition condition, b_event_handler function, gpointer data )  { -	struct b_event_data *b_ev = g_new0( struct b_event_data, 1 ); -	GIOCondition out_cond; -	 -	b_ev->id = id_next++; -	b_ev->function = function; -	b_ev->data = data; +	struct b_event_data *b_ev; -	out_cond = EV_PERSIST; -	if( condition & GAIM_INPUT_READ ) -		out_cond |= EV_READ; -	if( condition & GAIM_INPUT_WRITE ) -		out_cond |= EV_WRITE; +	event_debug( "b_input_add( %d, %d, 0x%x, 0x%x ) ", fd, condition, function, data ); -	event_set( &b_ev->evinfo, fd, out_cond, b_event_passthrough, b_ev ); -	event_add( &b_ev->evinfo, NULL ); -	 -	event_debug( "b_input_add( %d, %d, 0x%x, 0x%x ) = %d\n", fd, condition, function, data, b_ev->id ); +	if( ( condition & GAIM_INPUT_READ  && ( b_ev = g_hash_table_lookup( read_hash,  &fd ) ) ) || +	    ( condition & GAIM_INPUT_WRITE && ( b_ev = g_hash_table_lookup( write_hash, &fd ) ) ) ) +	{ +		/* We'll stick with this libevent entry, but give it a new BitlBee id. */ +		g_hash_table_remove( id_hash, &b_ev->id ); +		 +		event_debug( "(replacing old handler (id = %d)) = %d\n", b_ev->id, id_next ); +		 +		b_ev->id = id_next++; +		b_ev->function = function; +		b_ev->data = data; +	} +	else +	{ +		GIOCondition out_cond; +		 +		event_debug( "(new) = %d\n", id_next ); +		 +		b_ev = g_new0( struct b_event_data, 1 ); +		b_ev->id = id_next++; +		b_ev->function = function; +		b_ev->data = data; +		 +		out_cond = EV_PERSIST; +		if( condition & GAIM_INPUT_READ ) +			out_cond |= EV_READ; +		if( condition & GAIM_INPUT_WRITE ) +			out_cond |= EV_WRITE; +		 +		event_set( &b_ev->evinfo, fd, out_cond, b_event_passthrough, b_ev ); +		event_add( &b_ev->evinfo, NULL ); +		 +		if( out_cond & EV_READ ) +			g_hash_table_insert( read_hash, &b_ev->evinfo.ev_fd, b_ev ); +		if( out_cond & EV_WRITE ) +			g_hash_table_insert( write_hash, &b_ev->evinfo.ev_fd, b_ev ); +	}  	g_hash_table_insert( id_hash, &b_ev->id, b_ev ); -	  	return b_ev->id;  } @@ -135,7 +167,7 @@ gint b_timeout_add( gint timeout, b_event_handler function, gpointer data )  	evtimer_set( &b_ev->evinfo, b_event_passthrough, b_ev );  	evtimer_add( &b_ev->evinfo, &tv ); -	event_debug( "b_timeout_add( %d, %d, 0x%x ) = %d\n", timeout, function, data, b_ev->id ); +	event_debug( "b_timeout_add( %d, 0x%x, 0x%x ) = %d\n", timeout, function, data, b_ev->id );  	g_hash_table_insert( id_hash, &b_ev->id, b_ev ); @@ -149,13 +181,21 @@ void b_event_remove( gint id )  	event_debug( "b_event_remove( %d )\n", id );  	if( b_ev )  	{ -		event_del( &b_ev->evinfo );  		g_hash_table_remove( id_hash, &b_ev->id ); +		if( b_ev->evinfo.ev_fd >= 0 ) +		{ +			if( b_ev->evinfo.ev_events & EV_READ ) +				g_hash_table_remove( read_hash, &b_ev->evinfo.ev_fd ); +			if( b_ev->evinfo.ev_events & EV_WRITE ) +				g_hash_table_remove( write_hash, &b_ev->evinfo.ev_fd ); +		} +		 +		event_del( &b_ev->evinfo );  		g_free( b_ev );  	}  	else  	{ -		event_debug( "Double remove?\n" ); +		event_debug( "Already removed?\n" );  	}  } diff --git a/protocols/ssl_openssl.c b/protocols/ssl_openssl.c index 54788ec3..5aa0263e 100644 --- a/protocols/ssl_openssl.c +++ b/protocols/ssl_openssl.c @@ -114,7 +114,7 @@ static gboolean ssl_handshake( gpointer data, gint source, b_input_condition con  	struct scd *conn = data;  	int st; -	if( conn->inpa != -1 ) +	if( 0 && conn->inpa != -1 )  	{  		b_event_remove( conn->inpa );  		conn->inpa = -1; | 
