introduced the singleton pattern

- added singleton template class.
 - changed resolver, trans_layer & wheeltimer to use the singleton pattern.
sayer/1.4-spce2.6
Raphael Coeffic 16 years ago
parent b8444a196e
commit e7771d3f38

@ -35,27 +35,17 @@
#include <sys/socket.h>
#include <netinet/in.h>
resolver* resolver::_instance=0;
resolver::resolver()
_resolver::_resolver()
{
}
resolver::~resolver()
_resolver::~_resolver()
{
}
resolver* resolver::instance()
{
if(!_instance)
_instance = new resolver();
return _instance;
}
int resolver::resolve_name(const char* name, sockaddr_storage* sa,
int _resolver::resolve_name(const char* name, sockaddr_storage* sa,
const address_type types, const proto_type protos)
{
struct addrinfo hints,*res=0;

@ -27,6 +27,8 @@
#ifndef _resolver_h_
#define _resolver_h_
#include "singleton.h"
struct sockaddr_storage;
enum address_type {
@ -41,21 +43,19 @@ enum proto_type {
UDP=2
};
class resolver
class _resolver
{
static resolver* _instance;
resolver();
~resolver();
public:
static resolver* instance();
public:
int resolve_name(const char* name, sockaddr_storage* sa,
const address_type types, const proto_type protos);
protected:
_resolver();
~_resolver();
};
typedef singleton<_resolver> resolver;
#endif

@ -0,0 +1,47 @@
#ifndef _singleton_h_
#define _singleton_h_
#include "../AmThread.h"
template<class T>
class singleton
: public T
{
singleton() : T() {}
~singleton() {}
public:
static singleton<T>* instance()
{
_inst_m.lock();
if(!_instance) {
_instance = new singleton<T>();
}
singleton<T>* ret = _instance;
_inst_m.unlock();
return ret;
}
static void dispose()
{
_inst_m.lock();
_instance->dispose();
delete _instance;
_instance = NULL;
_inst_m.unlock();
}
private:
static singleton<T>* _instance;
static AmMutex _inst_m;
};
template<class T>
singleton<T>* singleton<T>::_instance = NULL;
template<class T>
AmMutex singleton<T>::_inst_m;
#endif

@ -55,46 +55,31 @@
#include <algorithm>
/**
* Singleton pointer.
* @see instance()
*/
trans_layer* trans_layer::_instance = NULL;
bool trans_layer::accept_fr_without_totag = false;
trans_layer* trans_layer::instance()
{
if(!_instance)
_instance = new trans_layer();
return _instance;
}
bool _trans_layer::accept_fr_without_totag = false;
trans_layer::trans_layer()
_trans_layer::_trans_layer()
: ua(NULL),
transport(NULL)
{
}
trans_layer::~trans_layer()
_trans_layer::~_trans_layer()
{}
void trans_layer::register_ua(sip_ua* ua)
void _trans_layer::register_ua(sip_ua* ua)
{
this->ua = ua;
}
void trans_layer::register_transport(trsp_socket* trsp)
void _trans_layer::register_transport(trsp_socket* trsp)
{
transport = trsp;
}
int trans_layer::send_reply(trans_ticket* tt,
int _trans_layer::send_reply(trans_ticket* tt,
int reply_code, const cstring& reason,
const cstring& to_tag, const cstring& hdrs,
const cstring& body)
@ -397,7 +382,7 @@ int trans_layer::send_reply(trans_ticket* tt,
return err;
}
int trans_layer::send_sl_reply(sip_msg* req, int reply_code,
int _trans_layer::send_sl_reply(sip_msg* req, int reply_code,
const cstring& reason, const cstring& hdrs,
const cstring& body)
{
@ -542,7 +527,7 @@ int trans_layer::send_sl_reply(sip_msg* req, int reply_code,
//
// Ref. RFC 3261 "12.2.1.1 Generating the Request"
//
int trans_layer::set_next_hop(sip_msg* msg)
int _trans_layer::set_next_hop(sip_msg* msg)
{
assert(msg);
@ -708,7 +693,7 @@ int trans_layer::set_next_hop(sip_msg* msg)
return 0;
}
void trans_layer::timeout(trans_bucket* bucket, sip_trans* t)
void _trans_layer::timeout(trans_bucket* bucket, sip_trans* t)
{
t->reset_all_timers();
t->state = TS_TERMINATED;
@ -733,7 +718,7 @@ void trans_layer::timeout(trans_bucket* bucket, sip_trans* t)
bucket->remove(t);
}
int trans_layer::send_request(sip_msg* msg, trans_ticket* tt)
int _trans_layer::send_request(sip_msg* msg, trans_ticket* tt)
{
// Request-URI
// To
@ -848,7 +833,7 @@ int trans_layer::send_request(sip_msg* msg, trans_ticket* tt)
return send_err;
}
int trans_layer::cancel(trans_ticket* tt)
int _trans_layer::cancel(trans_ticket* tt)
{
assert(tt);
assert(tt->_bucket && tt->_t);
@ -984,7 +969,7 @@ int trans_layer::cancel(trans_ticket* tt)
}
void trans_layer::received_msg(sip_msg* msg)
void _trans_layer::received_msg(sip_msg* msg)
{
#define DROP_MSG \
delete msg;\
@ -1161,7 +1146,7 @@ void trans_layer::received_msg(sip_msg* msg)
}
int trans_layer::update_uac_reply(trans_bucket* bucket, sip_trans* t, sip_msg* msg)
int _trans_layer::update_uac_reply(trans_bucket* bucket, sip_trans* t, sip_msg* msg)
{
assert(msg->type == SIP_REPLY);
@ -1321,7 +1306,7 @@ int trans_layer::update_uac_reply(trans_bucket* bucket, sip_trans* t, sip_msg* m
return 0;
}
int trans_layer::update_uac_request(trans_bucket* bucket, sip_trans*& t, sip_msg* msg)
int _trans_layer::update_uac_request(trans_bucket* bucket, sip_trans*& t, sip_msg* msg)
{
if(msg->u.request->method != sip_request::ACK){
t = bucket->add_trans(msg,TT_UAC);
@ -1369,7 +1354,7 @@ int trans_layer::update_uac_request(trans_bucket* bucket, sip_trans*& t, sip_msg
return 0;
}
int trans_layer::update_uas_reply(trans_bucket* bucket, sip_trans* t, int reply_code)
int _trans_layer::update_uas_reply(trans_bucket* bucket, sip_trans* t, int reply_code)
{
if(t->reply_status >= 200){
ERROR("Transaction has already been closed with a final reply\n");
@ -1435,7 +1420,7 @@ int trans_layer::update_uas_reply(trans_bucket* bucket, sip_trans* t, int reply_
return t->state;
}
int trans_layer::update_uas_request(trans_bucket* bucket, sip_trans* t, sip_msg* msg)
int _trans_layer::update_uas_request(trans_bucket* bucket, sip_trans* t, sip_msg* msg)
{
if(msg->u.request->method != sip_request::ACK &&
msg->u.request->method != sip_request::PRACK){
@ -1475,7 +1460,7 @@ int trans_layer::update_uas_request(trans_bucket* bucket, sip_trans* t, sip_msg*
return -1;
}
void trans_layer::send_non_200_ack(sip_msg* reply, sip_trans* t)
void _trans_layer::send_non_200_ack(sip_msg* reply, sip_trans* t)
{
sip_msg* inv = t->msg;
@ -1528,7 +1513,7 @@ void trans_layer::send_non_200_ack(sip_msg* reply, sip_trans* t)
}
}
void trans_layer::retransmit(sip_trans* t)
void _trans_layer::retransmit(sip_trans* t)
{
assert(transport);
if(!t->retr_buf || !t->retr_len){
@ -1542,7 +1527,7 @@ void trans_layer::retransmit(sip_trans* t)
}
}
void trans_layer::retransmit(sip_msg* msg)
void _trans_layer::retransmit(sip_msg* msg)
{
assert(transport);
int send_err = transport->send(&msg->remote_ip,msg->buf,msg->len);
@ -1551,7 +1536,7 @@ void trans_layer::retransmit(sip_msg* msg)
}
}
void trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr)
void _trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr)
{
int n = t->type >> 16;
int type = t->type & 0xFFFF;

@ -28,6 +28,7 @@
#define _trans_layer_h_
#include "cstring.h"
#include "singleton.h"
#include <list>
using std::list;
@ -38,49 +39,82 @@ struct sip_trans;
struct sip_header;
struct sockaddr_storage;
class trans_ticket;
class trans_bucket;
class trsp_socket;
class sip_ua;
class timer;
class trans_ticket
/**
* The transaction layer object.
* Uses the singleton pattern.
*/
class _trans_layer
{
sip_trans* _t;
trans_bucket* _bucket;
friend class trans_layer;
friend class AmSipDialog;
friend class SipCtrlInterface; //TODO: make _t, _bucket public??
public:
trans_ticket()
: _t(0), _bucket(0) {}
trans_ticket(sip_trans* t, trans_bucket* bucket)
: _t(t), _bucket(bucket) {}
/**
* Config option: if true, final replies without
* a to-tag will be accepted for requests which do not
* create a dialog.
*/
static bool accept_fr_without_totag;
trans_ticket(const trans_ticket& ticket)
: _t(ticket._t), _bucket(ticket._bucket) {}
};
/**
* Register a SIP UA.
* This method MUST be called ONCE.
*/
void register_ua(sip_ua* ua);
class trans_layer
{
/**
* Singleton pointer.
* @see instance()
/**
* Register a transport instance.
* This method MUST be called ONCE.
*/
static trans_layer* _instance;
void register_transport(trsp_socket* trsp);
sip_ua* ua;
trsp_socket* transport;
/**
* Sends a UAS reply.
* If a body is included, the hdrs parameter should
* include a well-formed 'Content-Type', but no
* 'Content-Length' header.
*/
int send_reply(trans_ticket* tt,
int reply_code, const cstring& reason,
const cstring& to_tag, const cstring& hdrs,
const cstring& body);
/**
* Sends a UAC request.
* Caution: Route headers should not be added to the
* general header list (msg->hdrs).
* @param [in] msg Pre-built message.
* @param [out] tt transaction ticket (needed for replies & CANCEL)
*/
int send_request(sip_msg* msg, trans_ticket* tt);
/**
* Cancels a request.
* A CANCEL request is sent if necessary.
* @param tt transaction ticket from the original INVITE.
*/
int cancel(trans_ticket* tt);
/** Avoid external instantiation. @see instance(). */
trans_layer();
/**
* Called by the transport layer
* when a new message has been recived.
*/
void received_msg(sip_msg* msg);
/** Avoid external instantiation. @see instance(). */
~trans_layer();
/**
* This is called by the transaction timer callback.
* At this place, the bucket is already locked, so
* please be quick.
*/
void timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr);
sip_ua* ua;
trsp_socket* transport;
/**
* Implements the state changes for the UAC state machine
* @return -1 if errors
@ -131,75 +165,34 @@ class trans_layer
*/
void timeout(trans_bucket* bucket, sip_trans* t);
public:
/**
* Config option: if true, final replies without
* a to-tag will be accepted for requests which do not
* create a dialog.
*/
static bool accept_fr_without_totag;
/**
* Retrieve the singleton instance.
*/
static trans_layer* instance();
/**
* Register a SIP UA.
* This method MUST be called ONCE.
*/
void register_ua(sip_ua* ua);
/**
* Register a transport instance.
* This method MUST be called ONCE.
*/
void register_transport(trsp_socket* trsp);
protected:
/** Avoid external instantiation. @see singleton. */
_trans_layer();
~_trans_layer();
};
/**
* Sends a UAS reply.
* If a body is included, the hdrs parameter should
* include a well-formed 'Content-Type', but no
* 'Content-Length' header.
*/
int send_reply(trans_ticket* tt,
int reply_code, const cstring& reason,
const cstring& to_tag, const cstring& hdrs,
const cstring& body);
typedef singleton<_trans_layer> trans_layer;
/**
* Sends a UAC request.
* Caution: Route headers should not be added to the
* general header list (msg->hdrs).
* @param [in] msg Pre-built message.
* @param [out] tt transaction ticket (needed for replies & CANCEL)
*/
int send_request(sip_msg* msg, trans_ticket* tt);
/**
* Cancels a request.
* A CANCEL request is sent if necessary.
* @param tt transaction ticket from the original INVITE.
*/
int cancel(trans_ticket* tt);
class trans_ticket
{
sip_trans* _t;
trans_bucket* _bucket;
friend class _trans_layer;
friend class AmSipDialog;
friend class SipCtrlInterface; //TODO: make _t, _bucket public??
/**
* Called by the transport layer
* when a new message has been recived.
*/
void received_msg(sip_msg* msg);
/**
* This is called by the transaction timer callback.
* At this place, the bucket is already locked, so
* please be quick.
*/
void timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr);
};
public:
trans_ticket()
: _t(0), _bucket(0) {}
trans_ticket(sip_trans* t, trans_bucket* bucket)
: _t(t), _bucket(bucket) {}
trans_ticket(const trans_ticket& ticket)
: _t(ticket._t), _bucket(ticket._bucket) {}
};
#endif // _trans_layer_h_

@ -42,26 +42,26 @@ timer::~timer()
wheeltimer* wheeltimer::_instance=NULL;
//wheeltimer* wheeltimer::_instance=NULL;
wheeltimer* wheeltimer::instance()
{
if(!_instance)
_instance = new wheeltimer();
// wheeltimer* wheeltimer::instance()
// {
// if(!_instance)
// _instance = new wheeltimer();
return _instance;
}
// return _instance;
// }
wheeltimer::wheeltimer()
_wheeltimer::_wheeltimer()
: wall_clock(0)
{
}
wheeltimer::~wheeltimer()
_wheeltimer::~_wheeltimer()
{
}
void wheeltimer::insert_timer(timer* t)
void _wheeltimer::insert_timer(timer* t)
{
//add new timer to user request list
utimer_add_m.lock();
@ -69,7 +69,7 @@ void wheeltimer::insert_timer(timer* t)
utimer_add_m.unlock();
}
void wheeltimer::remove_timer(timer* t)
void _wheeltimer::remove_timer(timer* t)
{
//add new timer to user request list
utimer_rem_m.lock();
@ -77,7 +77,7 @@ void wheeltimer::remove_timer(timer* t)
utimer_rem_m.unlock();
}
void wheeltimer::run()
void _wheeltimer::run()
{
struct timeval now,next_tick,diff,tick;
@ -113,7 +113,7 @@ void wheeltimer::run()
void wheeltimer::update_wheel(int wheel)
void _wheeltimer::update_wheel(int wheel)
{
// do not try do update wheel 0
if(!wheel)
@ -136,7 +136,7 @@ void wheeltimer::update_wheel(int wheel)
}
}
void wheeltimer::turn_wheel()
void _wheeltimer::turn_wheel()
{
u_int32_t mask = ((1<<BITS_PER_WHEEL)-1); // 0x00 00 00 FF
int i=0;
@ -182,7 +182,7 @@ void wheeltimer::turn_wheel()
process_current_timers();
}
void wheeltimer::process_current_timers()
void _wheeltimer::process_current_timers()
{
timer *t = (timer *)wheels[0][wall_clock & 0xFF].next;
@ -207,7 +207,7 @@ inline bool less_ts(unsigned int t1, unsigned int t2)
return (t1 - t2 > (unsigned int)(1<<31));
}
void wheeltimer::place_timer(timer* t)
void _wheeltimer::place_timer(timer* t)
{
if(less_ts(t->expires,wall_clock)){
@ -220,7 +220,7 @@ void wheeltimer::place_timer(timer* t)
place_timer(t,WHEELS-1);
}
void wheeltimer::place_timer(timer* t, int wheel)
void _wheeltimer::place_timer(timer* t, int wheel)
{
unsigned int pos;
unsigned int clock_mask = t->expires ^ wall_clock;
@ -239,7 +239,7 @@ void wheeltimer::place_timer(timer* t, int wheel)
add_timer_to_wheel(t,wheel,pos);
}
void wheeltimer::add_timer_to_wheel(timer* t, int wheel, unsigned int pos)
void _wheeltimer::add_timer_to_wheel(timer* t, int wheel, unsigned int pos)
{
t->next = wheels[wheel][pos].next;
wheels[wheel][pos].next = t;
@ -251,7 +251,7 @@ void wheeltimer::add_timer_to_wheel(timer* t, int wheel, unsigned int pos)
t->prev = &(wheels[wheel][pos]);
}
void wheeltimer::delete_timer(timer* t)
void _wheeltimer::delete_timer(timer* t)
{
if(t->prev)
t->prev->next = t->next;

@ -81,11 +81,11 @@ public:
};
#include "singleton.h"
class wheeltimer: public AmThread
class _wheeltimer:
public AmThread
{
static wheeltimer* _instance;
//the timer wheel
base_timer wheels[WHEELS][ELMTS_PER_WHEEL];
@ -104,9 +104,6 @@ class wheeltimer: public AmThread
//list with expired timers
base_timer utimer_expired;
wheeltimer();
~wheeltimer();
void turn_wheel();
void update_wheel(int wheel);
@ -122,10 +119,10 @@ protected:
void run();
void on_stop(){}
public:
static wheeltimer* instance();
_wheeltimer();
~_wheeltimer();
public:
//clock reference
volatile u_int32_t wall_clock; // 32 bits
@ -134,6 +131,7 @@ public:
void remove_timer(timer* t);
};
typedef singleton<_wheeltimer> wheeltimer;
#endif

Loading…
Cancel
Save