Navigation


Changeset 924:877592751fee in freeDiameter for libfdproto/sessions.c


Ignore:
Timestamp:
Feb 15, 2013, 1:52:57 AM (11 years ago)
Author:
Sebastien Decugis <sdecugis@freediameter.net>
Branch:
default
Children:
925:e5a09fab5ef3, 950:51c15f98a965
Phase:
public
Message:

Fix (tentative) for invalid handling of sessions fast creation/destruction as pointed by Yusuke Okura -- http://lists.freediameter.net/pipermail/help/2013-February/000584.html and http://lists.freediameter.net/pipermail/help/2013-February/000589.html -- Thank you very much

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libfdproto/sessions.c

    r788 r924  
    360360
    361361
    362 /* Create a new session object with the default timeout value, and link it */
     362/* Create a new session object with the default timeout value, and link it. The refcount is increased by 1, whether the session existed or not */
    363363int fd_sess_new ( struct session ** session, DiamId_t diamid, size_t diamidlen, uint8_t * opt, size_t optlen )
    364364{
     
    461461       
    462462                fd_list_insert_before(li, &sess->chain_h); /* hash table */
     463                sess->msg_cnt++;
    463464        } else {
    464465                free(sid);
     466               
     467                CHECK_POSIX( pthread_mutex_lock(&(*session)->stlock) );
     468                (*session)->msg_cnt++;
     469                CHECK_POSIX( pthread_mutex_unlock(&(*session)->stlock) );
     470               
    465471                /* it was found: was it previously destroyed? */
    466472                if ((*session)->is_destroyed == 0) {
     
    469475                } else {
    470476                        /* the session was marked destroyed, let's re-activate it. */
    471                         TODO("Re-creating a deleted session. Should investigate if this can lead to an issue... (need more feedback)");
    472477                        sess = *session;
     478                        sess->is_destroyed = 0;
    473479                       
    474480                        /* update the expiry time */
     
    501507
    502508out:
    503         ;       
     509        ;
    504510        pthread_cleanup_pop(0);
    505511        CHECK_POSIX( pthread_mutex_unlock( H_LOCK(hash) ) );
     
    512518}
    513519
    514 /* Find or create a session */
    515 int fd_sess_fromsid ( uint8_t * sid, size_t len, struct session ** session, int * new)
     520/* Find or create a session -- the msg refcount is increased */
     521int fd_sess_fromsid_msg ( uint8_t * sid, size_t len, struct session ** session, int * new)
    516522{
    517523        int ret;
     
    802808
    803809/* For the messages module */
    804 int fd_sess_fromsid_msg ( uint8_t * sid, size_t len, struct session ** session, int * new)
     810int fd_sess_fromsid ( uint8_t * sid, size_t len, struct session ** session, int * new)
    805811{
    806812        TRACE_ENTRY("%p %zd %p %p", sid, len, session, new);
     
    808814       
    809815        /* Get the session object */
    810         CHECK_FCT( fd_sess_fromsid ( sid, len, session, new) );
    811        
    812         /* Increase count */
    813         CHECK_FCT( fd_sess_ref_msg ( *session ) );
    814        
     816        CHECK_FCT( fd_sess_fromsid_msg ( sid, len, session, new) );
     817       
     818        /* Decrease the refcount */
     819        CHECK_POSIX( pthread_mutex_lock(&(*session)->stlock) );
     820        (*session)->msg_cnt--; /* was increased in fd_sess_new */
     821        CHECK_POSIX( pthread_mutex_unlock(&(*session)->stlock) );
     822               
    815823        /* Done */
    816824        return 0;
     
    833841{
    834842        int reclaim;
     843        uint32_t hash;
    835844       
    836845        TRACE_ENTRY("%p", session);
    837846        CHECK_PARAMS( session && VALIDATE_SI(*session) );
    838847       
     848        /* Lock the hash line to avoid possibility that session is freed while we are reclaiming */
     849        hash = (*session)->hash;
     850        CHECK_POSIX( pthread_mutex_lock( H_LOCK(hash)) );
     851        pthread_cleanup_push( fd_cleanup_mutex, H_LOCK(hash) );
     852
    839853        /* Update the msg refcount */
    840854        CHECK_POSIX( pthread_mutex_lock(&(*session)->stlock) );
     
    843857        CHECK_POSIX( pthread_mutex_unlock(&(*session)->stlock) );
    844858       
     859        /* Ok, now unlock the hash line */
     860        pthread_cleanup_pop( 0 );
     861        CHECK_POSIX( pthread_mutex_unlock( H_LOCK(hash) ) );
     862       
     863        /* and reclaim if no message references the session anymore */
    845864        if (reclaim == 1) {
    846865                CHECK_FCT(fd_sess_reclaim ( session ));
Note: See TracChangeset for help on using the changeset viewer.