Ignore:
Timestamp:
2006-05-13T19:01:14Z (19 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
19ac9c5
Parents:
309cb9e
Message:

libevent code works better with epoll() now in some (pretty common) situations.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/events_libevent.c

    r309cb9e r782d988  
    3939static GHashTable *id_hash;
    4040
     41/* Since libevent doesn't handle two event handlers for one fd-condition
     42   very well (which happens sometimes when BitlBee changes event handlers
     43   for a combination), let's buid some indexes so we can delete them here
     44   already, just in time. */
     45static GHashTable *read_hash;
     46static GHashTable *write_hash;
     47
    4148struct b_event_data
    4249{
     
    5360        id_next = 1;
    5461        id_hash = g_hash_table_new( g_int_hash, g_int_equal );
     62        read_hash = g_hash_table_new( g_int_hash, g_int_equal );
     63        write_hash = g_hash_table_new( g_int_hash, g_int_equal );
    5564}
    5665
     
    97106gint b_input_add( gint fd, b_input_condition condition, b_event_handler function, gpointer data )
    98107{
     108        struct b_event_data *b_ev;
     109       
     110        event_debug( "b_input_add( %d, %d, 0x%x, 0x%x ) ", fd, condition, function, data );
     111       
     112        if( ( condition & GAIM_INPUT_READ  && ( b_ev = g_hash_table_lookup( read_hash,  &fd ) ) ) ||
     113            ( condition & GAIM_INPUT_WRITE && ( b_ev = g_hash_table_lookup( write_hash, &fd ) ) ) )
     114        {
     115                /* We'll stick with this libevent entry, but give it a new BitlBee id. */
     116                g_hash_table_remove( id_hash, &b_ev->id );
     117               
     118                event_debug( "(replacing old handler (id = %d)) = %d\n", b_ev->id, id_next );
     119               
     120                b_ev->id = id_next++;
     121                b_ev->function = function;
     122                b_ev->data = data;
     123        }
     124        else
     125        {
     126                GIOCondition out_cond;
     127               
     128                event_debug( "(new) = %d\n", id_next );
     129               
     130                b_ev = g_new0( struct b_event_data, 1 );
     131                b_ev->id = id_next++;
     132                b_ev->function = function;
     133                b_ev->data = data;
     134               
     135                out_cond = EV_PERSIST;
     136                if( condition & GAIM_INPUT_READ )
     137                        out_cond |= EV_READ;
     138                if( condition & GAIM_INPUT_WRITE )
     139                        out_cond |= EV_WRITE;
     140               
     141                event_set( &b_ev->evinfo, fd, out_cond, b_event_passthrough, b_ev );
     142                event_add( &b_ev->evinfo, NULL );
     143               
     144                if( out_cond & EV_READ )
     145                        g_hash_table_insert( read_hash, &b_ev->evinfo.ev_fd, b_ev );
     146                if( out_cond & EV_WRITE )
     147                        g_hash_table_insert( write_hash, &b_ev->evinfo.ev_fd, b_ev );
     148        }
     149       
     150        g_hash_table_insert( id_hash, &b_ev->id, b_ev );
     151        return b_ev->id;
     152}
     153
     154/* TODO: Persistence for timers! */
     155gint b_timeout_add( gint timeout, b_event_handler function, gpointer data )
     156{
    99157        struct b_event_data *b_ev = g_new0( struct b_event_data, 1 );
    100         GIOCondition out_cond;
     158        struct timeval tv;
    101159       
    102160        b_ev->id = id_next++;
     
    104162        b_ev->data = data;
    105163       
    106         out_cond = EV_PERSIST;
    107         if( condition & GAIM_INPUT_READ )
    108                 out_cond |= EV_READ;
    109         if( condition & GAIM_INPUT_WRITE )
    110                 out_cond |= EV_WRITE;
    111        
    112         event_set( &b_ev->evinfo, fd, out_cond, b_event_passthrough, b_ev );
    113         event_add( &b_ev->evinfo, NULL );
    114        
    115         event_debug( "b_input_add( %d, %d, 0x%x, 0x%x ) = %d\n", fd, condition, function, data, b_ev->id );
    116        
    117         g_hash_table_insert( id_hash, &b_ev->id, b_ev );
    118        
    119         return b_ev->id;
    120 }
    121 
    122 /* TODO: Persistence for timers! */
    123 gint b_timeout_add( gint timeout, b_event_handler function, gpointer data )
    124 {
    125         struct b_event_data *b_ev = g_new0( struct b_event_data, 1 );
    126         struct timeval tv;
    127        
    128         b_ev->id = id_next++;
    129         b_ev->function = function;
    130         b_ev->data = data;
    131        
    132164        tv.tv_sec = timeout / 1000;
    133165        tv.tv_usec = ( timeout % 1000 ) * 1000;
     
    136168        evtimer_add( &b_ev->evinfo, &tv );
    137169       
    138         event_debug( "b_timeout_add( %d, %d, 0x%x ) = %d\n", timeout, function, data, b_ev->id );
     170        event_debug( "b_timeout_add( %d, 0x%x, 0x%x ) = %d\n", timeout, function, data, b_ev->id );
    139171       
    140172        g_hash_table_insert( id_hash, &b_ev->id, b_ev );
     
    150182        if( b_ev )
    151183        {
     184                g_hash_table_remove( id_hash, &b_ev->id );
     185                if( b_ev->evinfo.ev_fd >= 0 )
     186                {
     187                        if( b_ev->evinfo.ev_events & EV_READ )
     188                                g_hash_table_remove( read_hash, &b_ev->evinfo.ev_fd );
     189                        if( b_ev->evinfo.ev_events & EV_WRITE )
     190                                g_hash_table_remove( write_hash, &b_ev->evinfo.ev_fd );
     191                }
     192               
    152193                event_del( &b_ev->evinfo );
    153                 g_hash_table_remove( id_hash, &b_ev->id );
    154194                g_free( b_ev );
    155195        }
    156196        else
    157197        {
    158                 event_debug( "Double remove?\n" );
     198                event_debug( "Already removed?\n" );
    159199        }
    160200}
Note: See TracChangeset for help on using the changeset viewer.