Changeset 939370c


Ignore:
Timestamp:
2008-12-14T10:19:41Z (16 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
c0c43fb
Parents:
e1720ce
Message:

events_libevent now detects when the event currently being handled is
removed. This could otherwise cause unpredictable behaviour, especially
for timers.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/events_libevent.c

    re1720ce r939370c  
    3737
    3838static void b_main_restart();
    39 static guint id_next = 1;
     39static guint id_next = 1; /* Next ID to be allocated to an event handler. */
     40static guint id_cur = 0; /* Event ID that we're currently handling. */
     41static guint id_dead; /* Set to 1 if b_event_remove removes id_cur. */
    4042static GHashTable *id_hash;
    41 static int quitting = 0;
     43static int quitting = 0; /* Prepare to quit, stop handling events. */
    4244
    4345/* Since libevent doesn't handle two event handlers for one fd-condition
     
    119121        struct b_event_data *b_ev = data;
    120122        b_input_condition cond = 0;
    121         int id;
     123        gboolean st;
    122124       
    123125        if( fd >= 0 )
     
    133135        /* Since the called function might cancel this handler already
    134136           (which free()s b_ev), we have to remember the ID here. */
    135         id = b_ev->id;
     137        id_cur = b_ev->id;
     138        id_dead = 0;
    136139       
    137140        if( quitting )
    138141        {
    139                 b_event_remove( id );
     142                b_event_remove( id_cur );
    140143                return;
    141144        }
    142145       
    143         if( !b_ev->function( b_ev->data, fd, cond ) )
     146        st = b_ev->function( b_ev->data, fd, cond );
     147        if( id_dead )
     148        {
     149                /* This event was killed already, don't touch it! */
     150                return;
     151        }
     152        else if( !st )
    144153        {
    145154                event_debug( "Handler returned FALSE: " );
    146                 b_event_remove( id );
     155                b_event_remove( id_cur );
    147156        }
    148157        else if( fd == -1 )
    149158        {
     159                /* fd == -1 means it was a timer. These can't be auto-repeated
     160                   so it has to be recreated every time. */
    150161                struct timeval tv;
    151162               
     
    236247        if( b_ev )
    237248        {
     249                if( id == id_cur )
     250                        id_dead = TRUE;
     251               
    238252                g_hash_table_remove( id_hash, &b_ev->id );
    239253                if( b_ev->evinfo.ev_fd >= 0 )
Note: See TracChangeset for help on using the changeset viewer.