Navigation


Changeset 14:14cf6daf716d in freeDiameter for freeDiameter/p_expiry.c


Ignore:
Timestamp:
Oct 1, 2009, 6:24:07 PM (15 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Some progress on peers module

File:
1 edited

Legend:

Unmodified
Added
Removed
  • freeDiameter/p_expiry.c

    r13 r14  
    3636#include "fD.h"
    3737
     38static pthread_t       exp_thr;
     39static struct fd_list  exp_list = FD_LIST_INITIALIZER( exp_list );
     40static pthread_cond_t  exp_cnd  = PTHREAD_COND_INITIALIZER;
     41static pthread_mutex_t exp_mtx  = PTHREAD_MUTEX_INITIALIZER;
    3842
     43static void * exp_th_fct(void * arg)
     44{
     45        fd_log_threadname ( "Peers/expire" );
     46        TRACE_ENTRY( "" );
     47       
     48        CHECK_POSIX_DO( pthread_mutex_lock(&exp_mtx),  goto error );
     49        pthread_cleanup_push( fd_cleanup_mutex, &exp_mtx );
     50       
     51        do {
     52                struct timespec now;
     53                struct fd_peer * first;
     54               
     55                /* Check if there are expiring sessions available */
     56                if (FD_IS_LIST_EMPTY(&exp_list)) {
     57                        /* Just wait for a change or cancelation */
     58                        CHECK_POSIX_DO( pthread_cond_wait( &exp_cnd, &exp_mtx ), goto error );
     59                        /* Restart the loop on wakeup */
     60                        continue;
     61                }
     62               
     63                /* Get the pointer to the peer that expires first */
     64                first = (struct fd_peer *)(exp_list.next->o);
     65                ASSERT( CHECK_PEER(first) );
     66               
     67                /* Get the current time */
     68                CHECK_SYS_DO(  clock_gettime(CLOCK_REALTIME, &now),  goto error  );
    3969
     70                /* If first peer is not expired, we just wait until it happens */
     71                if ( TS_IS_INFERIOR( &now, &first->p_exp_timer ) ) {
     72                       
     73                        CHECK_POSIX_DO2(  pthread_cond_timedwait( &exp_cnd, &exp_mtx, &first->p_exp_timer ), 
     74                                        ETIMEDOUT, /* ETIMEDOUT is a normal error, continue */,
     75                                        /* on other error, */ goto error );
     76       
     77                        /* on wakeup, loop */
     78                        continue;
     79                }
     80               
     81                /* Now, the first peer in the list is expired; signal it */
     82                fd_list_unlink( &first->p_expiry );
     83                CHECK_FCT_DO( fd_event_send(first->p_events, FDEVP_TERMINATE, NULL), goto error );
     84               
     85        } while (1);
     86       
     87        pthread_cleanup_pop( 1 );
     88error:
     89        TRACE_DEBUG(INFO, "An error occurred in peers module! Expiry thread is terminating...");
     90        ASSERT(0);
     91        CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_TERMINATE, NULL), );
     92        return NULL;
     93}
    4094
    4195/* Initialize peers expiry mechanism */
    4296int fd_p_expi_init(void)
    4397{
    44         TODO("");
    45         return ENOTSUP;
     98        TRACE_ENTRY();
     99        CHECK_FCT( pthread_create( &exp_thr, NULL, exp_th_fct, NULL ) );
     100        return 0;
    46101}
    47102
     
    49104int fd_p_expi_fini(void)
    50105{
    51         TODO("");
    52         return ENOTSUP;
     106        CHECK_FCT_DO( fd_thr_term(&exp_thr), );
     107        CHECK_POSIX( pthread_mutex_lock(&exp_mtx) );
     108       
     109        while (!FD_IS_LIST_EMPTY(&exp_list)) {
     110                struct fd_peer * peer = (struct fd_peer *)(exp_list.next->o);
     111                fd_list_unlink(&peer->p_expiry );
     112        }
     113       
     114        CHECK_POSIX( pthread_mutex_unlock(&exp_mtx) );
     115        return 0;
    53116}
    54117
    55 /* Add a peer in the expiry list if needed */
    56 int fd_p_expi_update(struct fd_peer * peer, int locked )
     118/* Add / requeue a peer in the expiry list */
     119int fd_p_expi_update(struct fd_peer * peer )
    57120{
    58         TODO("");
     121        TRACE_ENTRY("%p", peer);
     122        CHECK_PARAMS( CHECK_PEER(peer) );
     123       
     124        CHECK_POSIX( pthread_mutex_lock(&exp_mtx) );
     125       
     126        fd_list_unlink(&peer->p_expiry );
    59127       
    60128        /* if peer expires */
    61                 /* add to the expiry list in appropriate position */
    62                 /* increment peer refcount */
     129        if (peer->p_hdr.info.pi_flags.exp) {
     130                struct fd_list * li;
     131               
     132                /* update the p_exp_timer value */
     133                CHECK_SYS(  clock_gettime(CLOCK_REALTIME, &peer->p_exp_timer)  );
     134                peer->p_exp_timer.tv_sec += peer->p_hdr.info.pi_lft;
     135               
     136                /* add to the expiry list in appropriate position (probably around the end) */
     137                for (li = exp_list.prev; li != &exp_list; li = li->prev) {
     138                        struct fd_peer * p = (struct fd_peer *)(li->o);
     139                        if (TS_IS_INFERIOR( &p->p_exp_timer, &peer->p_exp_timer ) )
     140                                break;
     141                }
     142               
     143                fd_list_insert_after(li, &peer->p_expiry);
     144               
    63145                /* signal the expiry thread if we added in first position */
     146                if (li == &exp_list) {
     147                        CHECK_POSIX( pthread_cond_signal(&exp_cnd) );
     148                }
     149        }
    64150       
    65         return ENOTSUP;
     151        CHECK_POSIX( pthread_mutex_unlock(&exp_mtx) );
     152        return 0;
    66153}
    67154
    68 /* Remove a peer from expiry list if needed */
    69 int fd_p_expi_unlink(struct fd_peer * peer, int locked )
    70 {
    71         TODO("");
    72         /* if peer is in expiry list */
    73                 /* remove from the list */
    74                 /* decrement peer refcount */
    75                 /* no need to signal the expiry thread ... */
    76        
    77         return ENOTSUP;
    78 }
Note: See TracChangeset for help on using the changeset viewer.