Changeset 038d17f


Ignore:
Timestamp:
2006-10-08T16:11:16Z (14 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
861c199
Parents:
36e9f62
Message:

Implemented a better node cache using a GLib hash, and preparing to add
event handlers that can be set when sending a packet to handle the reply
to this specific packet. This should allow me to make the iq handler a
lot cleaner.

Location:
protocols/jabber
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • protocols/jabber/io.c

    r36e9f62 r038d17f  
    360360                xt_add_attr( reply, "xmlns", "urn:ietf:params:xml:ns:xmpp-bind" );
    361361                reply = jabber_make_packet( "iq", "set", NULL, reply );
    362                 jabber_cache_packet( gc, reply );
     362                jabber_cache_add( gc, reply );
    363363               
    364364                if( !jabber_write_packet( gc, reply ) )
     
    373373                xt_add_attr( reply, "xmlns", "urn:ietf:params:xml:ns:xmpp-session" );
    374374                reply = jabber_make_packet( "iq", "set", NULL, reply );
    375                 jabber_cache_packet( gc, reply );
     375                jabber_cache_add( gc, reply );
    376376               
    377377                if( !jabber_write_packet( gc, reply ) )
  • protocols/jabber/iq.c

    r36e9f62 r038d17f  
    4141       
    4242        if( ( s = xt_find_attr( node, "id" ) ) )
    43                 orig = jabber_packet_from_cache( gc, s );
     43                orig = jabber_cache_get( gc, s );
    4444       
    4545        if( strcmp( type, "result" ) == 0 && xmlns && strcmp( xmlns, "jabber:iq:auth" ) == 0 )
     
    8585               
    8686                reply = jabber_make_packet( "iq", "set", NULL, reply );
    87                 jabber_cache_packet( gc, reply );
     87                jabber_cache_add( gc, reply );
    8888                st = jabber_write_packet( gc, reply );
    8989               
  • protocols/jabber/jabber.c

    r36e9f62 r038d17f  
    7979        jd->server ++;
    8080       
    81         jd->node_cache = xt_new_node( "cache", NULL, NULL );
     81        jd->node_cache = g_hash_table_new_full( g_str_hash, g_str_equal, NULL, jabber_cache_entry_free );
    8282       
    8383        /* Figure out the hostname to connect to. */
     
    125125                g_free( jd->txq );
    126126       
    127         xt_free_node( jd->node_cache );
     127        g_hash_table_destroy( jd->node_cache );
     128       
    128129        xt_free( jd->xt );
    129130       
     
    164165       
    165166        return l;
     167}
     168
     169static void jabber_get_info( struct gaim_connection *gc, char *who )
     170{
     171        struct xt_node *node;
     172       
     173        node = xt_new_node( "query", NULL, NULL );
     174        xt_add_attr( node, "xmlns", "http://jabber.org/protocol/disco#info" );
     175        node = jabber_make_packet( "iq", "get", who, node );
     176        jabber_cache_add( gc, node );
     177       
     178        jabber_write_packet( gc, node );
    166179}
    167180
     
    194207static void jabber_keepalive( struct gaim_connection *gc )
    195208{
    196         struct jabber_data *jd = gc->proto_data;
    197         struct xt_node *c, *tmp;
    198        
    199209        /* Just any whitespace character is enough as a keepalive for XMPP sessions. */
    200210        jabber_write( gc, "\n", 1 );
    201211       
    202         /* Let's abuse this keepalive for garbage collection of the node cache too.
    203            It runs every minute, so let's mark every node with a special flag the
    204            first time we see it, and clean it up the second time (clean up all
    205            packets with the flag set).
    206            
    207            node->flags is normally only used by xmltree itself for parsing/handling,
    208            so it should be safe to use the variable for gc. */
    209        
    210         /* This horrible loop is explained in xmltree.c. Makes me wonder if maybe I
    211            didn't choose the perfect data structure... */
    212         for( c = jd->node_cache->children; c; c =  c->next )
    213                 if( !( c->flags & XT_SEEN ) )
    214                         break;
    215        
    216         /* Now c points at the first unflagged node (or at NULL). Clean up
    217            everything until that point. */
    218         while( jd->node_cache->children != c )
    219         {
    220                 /*
    221                 printf( "Cleaning up:\n" );
    222                 xt_print( jd->node_cache->children );
    223                 */
    224                
    225                 tmp = jd->node_cache->children->next;
    226                 xt_free_node( jd->node_cache->children );
    227                 jd->node_cache->children = tmp;
    228         }
    229        
    230         /* Now flag the ones that were still unflagged. */
    231         for( c = jd->node_cache->children; c; c = c->next )
    232         {
    233                 /*
    234                 printf( "Flagged:\n" );
    235                 xt_print( c );
    236                 */
    237                
    238                 c->flags |= XT_SEEN;
    239         }
     212        /* This runs the garbage collection every minute, which means every packet
     213           is in the cache for about a minute (which should be enough AFAIK). */
     214        jabber_cache_clean( gc );
    240215}
    241216
     
    253228        ret->set_away = jabber_set_away;
    254229//      ret->set_info = jabber_set_info;
    255 //      ret->get_info = jabber_get_info;
     230        ret->get_info = jabber_get_info;
    256231        ret->add_buddy = jabber_add_buddy;
    257232        ret->remove_buddy = jabber_remove_buddy;
  • protocols/jabber/jabber.h

    r36e9f62 r038d17f  
    6060        char *away_message;
    6161       
    62         struct xt_node *node_cache;
     62        GHashTable *node_cache;
    6363};
    6464
     
    6767        char code[5];
    6868        char *full_name;
     69};
     70
     71typedef xt_status (*jabber_cache_event) ( struct gaim_connection *gc, struct xt_node *packet );
     72
     73struct jabber_cache_entry
     74{
     75        struct xt_node *node;
     76        jabber_cache_event func;
    6977};
    7078
     
    8896char *set_eval_tls( set_t *set, char *value );
    8997struct xt_node *jabber_make_packet( char *name, char *type, char *to, struct xt_node *children );
    90 void jabber_cache_packet( struct gaim_connection *gc, struct xt_node *node );
    91 struct xt_node *jabber_packet_from_cache( struct gaim_connection *gc, char *id );
     98void jabber_cache_add( struct gaim_connection *gc, struct xt_node *node );
     99struct xt_node *jabber_cache_get( struct gaim_connection *gc, char *id );
     100void jabber_cache_entry_free( gpointer entry );
     101void jabber_cache_clean( struct gaim_connection *gc );
    92102const struct jabber_away_state *jabber_away_state_by_code( char *code );
    93103const struct jabber_away_state *jabber_away_state_by_name( char *name );
  • protocols/jabber/jabber_util.c

    r36e9f62 r038d17f  
    8282   them when you receive the response. Use this BEFORE sending the packet so
    8383   it'll get an id= tag, and do NOT free() the packet after writing it! */
    84 void jabber_cache_packet( struct gaim_connection *gc, struct xt_node *node )
     84void jabber_cache_add( struct gaim_connection *gc, struct xt_node *node )
    8585{
    8686        struct jabber_data *jd = gc->proto_data;
    8787        char *id = g_strdup_printf( "BeeX%04x", next_id++ );
    88        
    89         /* FIXME: Maybe start using g_error() here if nodes still have a parent, for example? */
     88        struct jabber_cache_entry *entry = g_new0( struct jabber_cache_entry, 1 );
    9089       
    9190        xt_add_attr( node, "id", id );
    92         xt_add_child( jd->node_cache, node );
    9391        g_free( id );
    94 }
    95 
    96 /* Emptying this cache is a BIG TODO! */
    97 struct xt_node *jabber_packet_from_cache( struct gaim_connection *gc, char *id )
     92       
     93        entry->node = node;
     94        g_hash_table_insert( jd->node_cache, xt_find_attr( node, "id" ), entry );
     95}
     96
     97struct xt_node *jabber_cache_get( struct gaim_connection *gc, char *id )
    9898{
    9999        struct jabber_data *jd = gc->proto_data;
    100         struct xt_node *node;
    101         char *s;
    102        
    103         for( node = jd->node_cache->children; node; node = node->next )
    104                 if( ( s = xt_find_attr( node, "id" ) ) && strcmp( id, s ) == 0 )
    105                         break;
    106        
    107         return node;
     100        struct jabber_cache_entry *entry = g_hash_table_lookup( jd->node_cache, id );
     101       
     102        return entry ? entry->node : NULL;
     103}
     104
     105void jabber_cache_entry_free( gpointer data )
     106{
     107        struct jabber_cache_entry *entry = data;
     108       
     109        xt_free_node( entry->node );
     110        g_free( entry );
     111}
     112
     113gboolean jabber_cache_clean_entry( gpointer key, gpointer entry, gpointer nullpointer );
     114
     115void jabber_cache_clean( struct gaim_connection *gc )
     116{
     117        struct jabber_data *jd = gc->proto_data;
     118       
     119        g_hash_table_foreach_remove( jd->node_cache, jabber_cache_clean_entry, NULL );
     120}
     121
     122gboolean jabber_cache_clean_entry( gpointer key, gpointer entry_, gpointer nullpointer )
     123{
     124        struct jabber_cache_entry *entry = entry_;
     125        struct xt_node *node = entry->node;
     126       
     127        if( node->flags & XT_SEEN )
     128                return TRUE;
     129        else
     130        {
     131                node->flags |= XT_SEEN;
     132                return FALSE;
     133        }
    108134}
    109135
Note: See TracChangeset for help on using the changeset viewer.