Navigation


Changeset 14:14cf6daf716d in freeDiameter for freeDiameter/p_psm.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_psm.c

    r13 r14  
    3636#include "fD.h"
    3737
     38const char *peer_state_str[] = {
     39          "STATE_ZOMBIE"
     40        , "STATE_OPEN"
     41        , "STATE_CLOSED"
     42        , "STATE_CLOSING"
     43        , "STATE_WAITCNXACK"
     44        , "STATE_WAITCNXACK_ELEC"
     45        , "STATE_WAITCEA"
     46        , "STATE_SUSPECT"
     47        , "STATE_REOPEN"
     48        };
     49
     50const char * fd_pev_str(int event)
     51{
     52        switch (event) {
     53        #define case_str( _val )\
     54                case _val : return #_val
     55                case_str(FDEVP_TERMINATE);
     56                case_str(FDEVP_DUMP_ALL);
     57                case_str(FDEVP_MSG_INCOMING);
     58                case_str(FDEVP_PSM_TIMEOUT);
     59               
     60                default:
     61                        TRACE_DEBUG(FULL, "Unknown event : %d", event);
     62                        return "Unknown event";
     63        }
     64}
     65
     66
    3867static int started = 0;
    3968static pthread_mutex_t  started_mtx = PTHREAD_MUTEX_INITIALIZER;
     
    5685}
    5786
     87/* Cancelation cleanup : set ZOMBIE state in the peer */
     88void cleanup_state(void * arg)
     89{
     90        struct fd_peer * peer = (struct fd_peer *)arg;
     91        CHECK_PARAMS_DO( CHECK_PEER(peer), return );
     92        peer->p_hdr.info.pi_state = STATE_ZOMBIE;
     93        return;
     94}
     95
     96/* Set timeout timer of next event */
     97static void psm_next_timeout(struct fd_peer * peer, int add_random, int delay)
     98{
     99        /* Initialize the timer */
     100        CHECK_POSIX_DO(  clock_gettime( CLOCK_REALTIME,  &peer->p_psm_timer ), ASSERT(0) );
     101       
     102        if (add_random) {
     103                if (delay > 2)
     104                        delay -= 2;
     105                else
     106                        delay = 0;
     107
     108                /* Add a random value between 0 and 4sec */
     109                peer->p_psm_timer.tv_sec += random() % 4;
     110                peer->p_psm_timer.tv_nsec+= random() % 1000000000L;
     111                if (peer->p_psm_timer.tv_nsec > 1000000000L) {
     112                        peer->p_psm_timer.tv_nsec -= 1000000000L;
     113                        peer->p_psm_timer.tv_sec ++;
     114                }
     115        }
     116       
     117        peer->p_psm_timer.tv_sec += delay;
     118       
     119#if 0
     120        /* temporary for debug */
     121        peer->p_psm_timer.tv_sec += 10;
     122#endif
     123}
     124
     125static int psm_ev_timedget(struct fd_peer * peer, int *code, void ** data)
     126{
     127        struct fd_event * ev;
     128        int ret = 0;
     129       
     130        TRACE_ENTRY("%p %p %p", peer, code, data);
     131       
     132        ret = fd_fifo_timedget(peer->p_events, &ev, &peer->p_psm_timer);
     133        if (ret == ETIMEDOUT) {
     134                *code = FDEVP_PSM_TIMEOUT;
     135                *data = NULL;
     136        } else {
     137                CHECK_FCT( ret );
     138                *code = ev->code;
     139                *data = ev->data;
     140                free(ev);
     141        }
     142       
     143        return 0;
     144}       
     145
     146/* The state machine thread */
     147static void * p_psm_th( void * arg )
     148{
     149        struct fd_peer * peer = (struct fd_peer *)arg;
     150        int created_started = started;
     151       
     152        CHECK_PARAMS_DO( CHECK_PEER(peer), ASSERT(0) );
     153       
     154        pthread_cleanup_push( cleanup_state, arg );
     155       
     156        /* Set the thread name */
     157        {
     158                char buf[48];
     159                sprintf(buf, "PSM/%.*s", sizeof(buf) - 5, peer->p_hdr.info.pi_diamid);
     160                fd_log_threadname ( buf );
     161        }
     162       
     163        /* Wait that the PSM are authorized to start in the daemon */
     164        CHECK_FCT_DO( fd_psm_waitstart(), goto end );
     165       
     166        /* The state machine starts in CLOSED state */
     167        peer->p_hdr.info.pi_state = STATE_CLOSED;
     168       
     169        /* Initialize the timer */
     170        if (peer->p_flags.pf_responder) {
     171                psm_next_timeout(peer, 0, INCNX_TIMEOUT);
     172        } else {
     173                psm_next_timeout(peer, created_started ? 0 : 1, 0);
     174        }
     175       
     176psm:
     177        do {
     178                int event;
     179                void * ev_data;
     180               
     181                /* Get next event */
     182                CHECK_FCT_DO( psm_ev_timedget(peer, &event, &ev_data), goto end );
     183                TRACE_DEBUG(FULL, "'%s'\t<-- '%s'\t(%p)\t'%s'",
     184                                STATE_STR(peer->p_hdr.info.pi_state),
     185                                fd_pev_str(event), ev_data,
     186                                peer->p_hdr.info.pi_diamid);
     187               
     188                /* Now, the action depends on the current state and the incoming event */
     189               
     190       
     191        } while (1);   
     192       
     193       
     194end:   
     195        /* set STATE_ZOMBIE */
     196        pthread_cleanup_pop(1);
     197        return NULL;
     198}       
     199       
     200       
     201
     202
     203/* Create the PSM thread of one peer structure */
     204int fd_psm_begin(struct fd_peer * peer )
     205{
     206        TRACE_ENTRY("%p", peer);
     207        TODO("");
     208        return ENOTSUP;
     209}
     210
     211/* End the PSM (clean ending) */
     212int fd_psm_terminate(struct fd_peer * peer )
     213{
     214        TRACE_ENTRY("%p", peer);
     215        CHECK_PARAMS( CHECK_PEER(peer) );
     216        CHECK_FCT( fd_event_send(peer->p_events, FDEVP_TERMINATE, NULL) );
     217        return 0;
     218}
     219
     220/* End the PSM violently */
     221void fd_psm_abord(struct fd_peer * peer )
     222{
     223        TRACE_ENTRY("%p", peer);
     224        TODO("Cancel PSM thread");
     225        TODO("Cancel IN thread");
     226        TODO("Cancel OUT thread");
     227        TODO("Cleanup the connection");
     228        return;
     229}
     230
    58231/* Allow the state machines to start */
    59232int fd_psm_start()
     
    67240}
    68241
    69 /* Create the PSM thread of one peer structure */
    70 int fd_psm_begin(struct fd_peer * peer )
    71 {
    72         TRACE_ENTRY("%p", peer);
    73         TODO("");
    74         return ENOTSUP;
    75 }
    76 
    77 /* End the PSM (clean ending) */
    78 int fd_psm_terminate(struct fd_peer * peer )
    79 {
    80         TRACE_ENTRY("%p", peer);
    81         TODO("");
    82         return ENOTSUP;
    83 }
    84 
    85 /* End the PSM violently */
    86 void fd_psm_abord(struct fd_peer * peer )
    87 {
    88         TRACE_ENTRY("%p", peer);
    89         TODO("");
    90         return;
    91 }
    92 
Note: See TracChangeset for help on using the changeset viewer.