From b8444a196ee0983c756b36b74a520dfc0d7e613a Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Tue, 17 Aug 2010 10:45:17 +0200 Subject: [PATCH] - 'template-ized' the hash table mechanism so that it can be used by others as well (until now, only for sip transactions). - moved the transaction table and related items into trans_table.{h,cpp}. --- core/sip/hash_table.h | 147 ++++++++++--------- core/sip/sip_trans.cpp | 8 +- core/sip/sip_trans.h | 2 + core/sip/trans_layer.cpp | 12 +- core/sip/{hash_table.cpp => trans_table.cpp} | 78 ++-------- core/sip/trans_table.h | 62 ++++++++ 6 files changed, 169 insertions(+), 140 deletions(-) rename core/sip/{hash_table.cpp => trans_table.cpp} (89%) create mode 100644 core/sip/trans_table.h diff --git a/core/sip/hash_table.h b/core/sip/hash_table.h index e146b712..dce8864c 100644 --- a/core/sip/hash_table.h +++ b/core/sip/hash_table.h @@ -30,8 +30,8 @@ #define _hash_table_h #include "cstring.h" - -#include +#include "../AmThread.h" +#include "../log.h" #include using std::list; @@ -40,104 +40,115 @@ struct sip_trans; struct sip_msg; -#define H_TABLE_POWER 10 -#define H_TABLE_ENTRIES (1< +class ht_bucket: public AmMutex { public: - typedef list trans_list; + typedef list value_list; -private: - - unsigned long id; - - pthread_mutex_t m; - trans_list elmts; + ht_bucket(unsigned long id) : id(id) {} + ~ht_bucket() {} /** - * Finds a transaction ptr in this bucket. - * This is used to check if the transaction - * still exists. - * - * @return iterator pointing at the transaction. + * Caution: The bucket MUST be locked before you can + * do anything with it. */ - trans_list::iterator find_trans(sip_trans* t); - - sip_trans* match_200_ack(sip_trans* t,sip_msg* msg); - sip_trans* match_1xx_prack(sip_trans* t,sip_msg* msg); - -public: /** - * Kept public to allow for static construction. - * !!! DO CREATE ANY BUCKETS ON YOUR OWN !!! + * Searches for the value ptr in this bucket. + * This is used to check if the value + * still exists. + * + * @return true if the value still exists. */ - trans_bucket(); - ~trans_bucket(); + bool exist(Value* t) { + return find(t) != elmts.end(); + } /** - * The bucket MUST be locked before you can - * do anything with it. + * Remove the value from this bucket, + * if it was still present. */ - void lock(); + void remove(Value* t) { + typename value_list::iterator it = find(t); + + if(it != elmts.end()){ + elmts.erase(it); + delete t; + DBG("~sip_trans()\n"); + } + } /** - * Unlocks the bucket after work has been done. + * Returns the bucket id, which should be an index + * into the corresponding hash table. */ - void unlock(); - - // Match a request to UAS transactions - // in this bucket - sip_trans* match_request(sip_msg* msg); - - // Match a reply to UAC transactions - // in this bucket - sip_trans* match_reply(sip_msg* msg); + unsigned long get_id() const { + return id; + } - sip_trans* add_trans(sip_msg* msg, int ttype); + // debug method + void dump() const { + + if(elmts.empty()) + return; + + DBG("*** Bucket ID: %i ***\n",(int)get_id()); + + for(typename value_list::const_iterator it = elmts.begin(); it != elmts.end(); ++it) { + + (*it)->dump(); + } + } +protected: /** - * Searches for a transaction ptr in this bucket. + * Finds a transaction ptr in this bucket. * This is used to check if the transaction * still exists. * - * @return true if the transaction still exists. + * @return iterator pointing at the value. */ - bool exist(sip_trans* t); - - /** - * Remove a transaction from this bucket, - * if it was still present. - */ - void remove_trans(sip_trans* t); - - unsigned long get_id() { - return id; + typename value_list::iterator find(Value* t) + { + typename value_list::iterator it = elmts.begin(); + for(;it!=elmts.end();++it) + if(*it == t) + break; + + return it; } - - // debug method - void dump(); + unsigned long id; + value_list elmts; }; -trans_bucket* get_trans_bucket(const cstring& callid, const cstring& cseq_num); -trans_bucket* get_trans_bucket(unsigned int h); - -unsigned int hash(const cstring& ci, const cstring& cs); +template +class hash_table +{ + Bucket* _table[size]; +public: + hash_table() { + for(unsigned long i=0; ihandle_sip_reply(&msg); - bucket->remove_trans(t); + bucket->remove(t); } int trans_layer::send_request(sip_msg* msg, trans_ticket* tt) @@ -877,7 +877,7 @@ int trans_layer::cancel(trans_ticket* tt) case TS_CALLING: // do not send a request: // just remove the transaction - bucket->remove_trans(t); + bucket->remove(t); bucket->unlock(); return 0; @@ -1465,7 +1465,7 @@ int trans_layer::update_uas_request(trans_bucket* bucket, sip_trans* t, sip_msg* case TS_TERMINATED_200: // remove transaction - bucket->remove_trans(t); + bucket->remove(t); return TS_REMOVED; default: @@ -1610,7 +1610,7 @@ void trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr) tr->clear_timer(type); ////ua->timer_expired(tr,STIMER_H); ua->handle_reply_timeout(AmSipTimeoutEvent::noACK, tr); - bucket->remove_trans(tr); + bucket->remove(tr); handled = true; break; @@ -1633,7 +1633,7 @@ void trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr) // else, send ACK & BYE. tr->clear_timer(type); - bucket->remove_trans(tr); + bucket->remove(tr); break; case STIMER_E: // Trying/Proceeding: (re-)send request diff --git a/core/sip/hash_table.cpp b/core/sip/trans_table.cpp similarity index 89% rename from core/sip/hash_table.cpp rename to core/sip/trans_table.cpp index 873f9881..f6777b76 100644 --- a/core/sip/hash_table.cpp +++ b/core/sip/trans_table.cpp @@ -25,10 +25,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "hash_table.h" -#include "hash.h" -#include "AmSipHeaders.h" +#include "trans_table.h" #include "sip_parser.h" #include "parse_header.h" #include "parse_cseq.h" @@ -36,43 +34,32 @@ #include "parse_from_to.h" #include "parse_100rel.h" #include "sip_trans.h" +#include "hash.h" #include "log.h" -#include -#include - #include // // Global transaction table // -trans_bucket _trans_table[H_TABLE_ENTRIES]; - - +//trans_bucket _trans_table[H_TABLE_ENTRIES]; +hash_table _trans_table; -trans_bucket::trans_bucket() +trans_bucket::trans_bucket(unsigned long id) + : ht_bucket::ht_bucket(id) { - id = (unsigned long)(trans_bucket*)(this - _trans_table); - pthread_mutex_init(&m,NULL); } -trans_bucket::~trans_bucket() -{ - pthread_mutex_destroy(&m); -} +// trans_bucket::trans_bucket() +// : ht_bucket::ht_bucket((unsigned long)this - (unsigned long)_trans_table) +// { +// } -void trans_bucket::lock() -{ - pthread_mutex_lock(&m); -} - -void trans_bucket::unlock() +trans_bucket::~trans_bucket() { - pthread_mutex_unlock(&m); } - sip_trans* trans_bucket::match_request(sip_msg* msg) { // assert(msg && msg->cseq && msg->callid); @@ -421,31 +408,6 @@ sip_trans* trans_bucket::add_trans(sip_msg* msg, int ttype) return t; } -trans_bucket::trans_list::iterator trans_bucket::find_trans(sip_trans* t) -{ - trans_list::iterator it = elmts.begin(); - for(;it!=elmts.end();++it) - if(*it == t) - break; - - return it; -} - -bool trans_bucket::exist(sip_trans* t) -{ - return find_trans(t) != elmts.end(); -} - -void trans_bucket::remove_trans(sip_trans* t) -{ - trans_list::iterator it = find_trans(t); - - if(it != elmts.end()){ - elmts.erase(it); - delete t; - DBG("~sip_trans()\n"); - } -} unsigned int hash(const cstring& ci, const cstring& cs) { @@ -532,13 +494,13 @@ void compute_branch(char* branch/*[8]*/, const cstring& callid, const cstring& c trans_bucket* get_trans_bucket(const cstring& callid, const cstring& cseq_num) { - return &_trans_table[hash(callid,cseq_num)]; + return /*&*/_trans_table[hash(callid,cseq_num)]; } trans_bucket* get_trans_bucket(unsigned int h) { assert(h < H_TABLE_ENTRIES); - return &_trans_table[h]; + return /*&*/_trans_table[h]; } void dumps_transactions() @@ -553,20 +515,6 @@ void dumps_transactions() } } -void trans_bucket::dump() -{ - if(elmts.empty()) - return; - - DBG("*** Bucket ID: %i ***\n",(int)get_id()); - - for(trans_list::iterator it = elmts.begin(); it != elmts.end(); ++it) { - - DBG("type=0x%x; msg=%p; to_tag=%.*s; reply_status=%i; state=%i; retr_buf=%p\n", - (*it)->type,(*it)->msg,(*it)->to_tag.len,(*it)->to_tag.s,(*it)->reply_status,(*it)->state,(*it)->retr_buf); - } -} - /** EMACS ** * Local variables: diff --git a/core/sip/trans_table.h b/core/sip/trans_table.h new file mode 100644 index 00000000..3e7dd501 --- /dev/null +++ b/core/sip/trans_table.h @@ -0,0 +1,62 @@ +#ifndef _trans_table_h_ +#define _trans_table_h_ + +#include "hash_table.h" + +#define H_TABLE_POWER 10 +#define H_TABLE_ENTRIES (1< +{ +public: + typedef ht_bucket::value_list trans_list; + + /** + * Kept public to allow for static construction. + * !!! DO CREATE ANY BUCKETS ON YOUR OWN !!! + */ + // trans_bucket(); + trans_bucket(unsigned long id); + ~trans_bucket(); + + // Match a request to UAS transactions + // in this bucket + sip_trans* match_request(sip_msg* msg); + + // Match a reply to UAC transactions + // in this bucket + sip_trans* match_reply(sip_msg* msg); + + sip_trans* add_trans(sip_msg* msg, int ttype); + + // /** + // * Remove a transaction from this bucket, + // * if it was still present. + // */ + // void remove_trans(sip_trans* t); + +private: + sip_trans* match_200_ack(sip_trans* t,sip_msg* msg); + sip_trans* match_1xx_prack(sip_trans* t,sip_msg* msg); +}; + +trans_bucket* get_trans_bucket(const cstring& callid, const cstring& cseq_num); +trans_bucket* get_trans_bucket(unsigned int h); + +unsigned int hash(const cstring& ci, const cstring& cs); + + +#define BRANCH_BUF_LEN 8 + +void compute_branch(char* branch/*[BRANCH_BUF_LEN]*/, + const cstring& callid, const cstring& cseq); + +#define SL_TOTAG_LEN BRANCH_BUF_LEN + +void compute_sl_to_tag(char* to_tag/*[SL_TOTAG_LEN]*/, sip_msg* msg); + +void dumps_transactions(); + + +#endif