Gtalk源码剖析之:sigslot源代码

Posted ouyangbuxiu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gtalk源码剖析之:sigslot源代码相关的知识,希望对你有一定的参考价值。

版权声明: 本文章由vt.buxiu发布在www.vtzone.org,版权归vtzone研究小组所有,转载请保持此声明!!! 

@@内容摘要:
sigslot源代码包含:single_threaded,multi_threaded_global,multi_threaded_local ,lock_block等用于控制线程安全的辅助类,以及has_slots,_connection相关类,_signal相关类;本文仅以参数个数为0的代码作为事例,其他大于0个参数的情况相同。 @@

/*single_threaded/multi_threaed...作为父类被has_slot继承*/
class single_threaded ;//单线程,空,所以相当于has_slot没有父类

// The multi threading policies only get compiled in if they are enabled.
class multi_threaded_global ;//全局多线程共享临界区,has_slot从这个类继承了锁

class multi_threaded_local ; //每个对象多线程共享临界区

template<class mt_policy>  //封装锁资源,用于
class lock_block;


has_slots模板类:[code]

template < class  mt_policy >
class  has_slots;
    template
< class  mt_policy  =  SIGSLOT_DEFAULT_MT_POLICY >
class  has_slots :  public  mt_policy 

private:
  typedef std::
set<_signal_base<mt_policy> *> sender_set; //发送者集合:signal集合
  typedef sender_set::const_iterator const_iterator;
public:
  has_slots()
  

   ;
  

  has_slots(
const has_slots& hs) //拷贝构造函数
   : mt_policy(hs)
  

   lock_block
<mt_policy> lock(this);
   const_iterator it 
= hs.m_senders.begin();
   const_iterator itEnd 
= hs.m_senders.end();
   
while(it != itEnd)
   

       
//signal->slot_duplicate(old,new);
    (*it)->slot_duplicate(&hs, this);
    m_senders.insert(
*it);
    
++it;
   

  

        
        
//将signal放入到sender集合中
  void signal_connect(_signal_base<mt_policy>* sender)
  

   lock_block
<mt_policy> lock(this);
   m_senders.insert(sender);
  

        
        
//从sender集合中删除指定的signal
  void signal_disconnect(_signal_base<mt_policy>* sender)
  

   lock_block
<mt_policy> lock(this);
   m_senders.erase(sender);
  

  
virtual ~has_slots()
  

   disconnect_all();
  

  
void disconnect_all()
  

   lock_block
<mt_policy> lock(this);
   const_iterator it 
= m_senders.begin();
   const_iterator itEnd 
= m_senders.end();
   
while(it != itEnd)
   

    (
*it)->slot_disconnect(this);
    
++it;
   

   m_senders.erase(m_senders.begin(), m_senders.end());
  

private:
  sender_set m_senders;
;[ / code]

_connection_base0模板类

[code]template < class  mt_policy > // conncetion_base定义抽象接口,要求connect必须实现该接口
class  _connection_base0

public:
  
virtual has_slots<mt_policy>* getdest() const = 0;
  
virtual void emit() = 0;
  
virtual _connection_base0* clone() = 0;
  
virtual _connection_base0* duplicate(has_slots<mt_policy>* pnewdest) = 0;
;[ / code]_connection0模板类[code] 
template
< class  dest_type,  class  mt_policy >
class  _connection0 :  public  _connection_base0 < mt_policy >

public:
  _connection0()
  

   pobject 
= NULL;
   pmemfun 
= NULL;
  

        
        
//connect构造函数,每个connect对象记录了(接受/发送)消息对象的地址和回调函数,
        
//而connect对象本身保存在signal中
  _connection0(dest_type* pobject, void (dest_type::*pmemfun)())
  

   m_pobject 
= pobject;
   m_pmemfun 
= pmemfun;
  

        
//克隆一个connect对象,即基于*this生成一个新的connect对象
  virtual _connection_base0<mt_policy>* clone()
  

   
return new _connection0<dest_type, mt_policy>(*this);
  

        
//生成一个新的connect对象,但内容为:新的(接受/发送)消息对象地址+老的回调函数
  virtual _connection_base0<mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
  

   
return new _connection0<dest_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
  

        
        
//发送消息,即调用connect中注册的回调函数(对象的成员函数)
  virtual void emit()
  

   (m_pobject
->*m_pmemfun)();
  

        
        
//返回目标对象地址
  virtual has_slots<mt_policy>* getdest() const
  

   
return m_pobject;
  

private:
  dest_type
* m_pobject;
  
void (dest_type::* m_pmemfun)();
;[ / code]

_signal_base模板类

[code]template < class  mt_policy >
class  _signal_base :  public  mt_policy   // signal基类,定义抽象接口

public:
  
virtual void slot_disconnect(has_slots<mt_policy>* pslot) = 0;
  
virtual void slot_duplicate(const has_slots<mt_policy>* poldslot, has_slots<mt_policy>* pnewslot) = 0;
;[ / code]_signal_base0 模板类[code] 
template
< class  mt_policy >
class  _signal_base0 :  public  _signal_base < mt_policy >   // 带有0个参数的signal

public:
  typedef std::list
<_connection_base0<mt_policy> *>  connections_list;
  _signal_base0()
  

   ;
  

  _signal_base0(
const _signal_base0& s)  //拷贝构造函数
   : _signal_base<mt_policy>(s)
  

   lock_block
<mt_policy> lock(this);
   connections_list::const_iterator it 
= s.m_connected_slots.begin();
   connections_list::const_iterator itEnd 
= s.m_connected_slots.end();
   
while(it != itEnd)
   

    (
*it)->getdest()->signal_connect(this);
    m_connected_slots.push_back((
*it)->clone());
    
++it;
   

  

  
~_signal_base0()
  

   disconnect_all();
  

  
void disconnect_all()
  

   lock_block
<mt_policy> lock(this);
   connections_list::const_iterator it 
= m_connected_slots.begin();
   connections_list::const_iterator itEnd 
= m_connected_slots.end();
   
while(it != itEnd)
   

    (
*it)->getdest()->signal_disconnect(this);
    delete 
*it;
    
++it;
   

   m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
  

         
        
//disconnect为什么不放到子类?connect放在子类
        
//根据传入的目标对象地址,在connect_list中查找到对应的connect,
        
//将该connect删除,并删除list中的该地址入口,
  void disconnect(has_slots<mt_policy>* pclass)
  

   lock_block
<mt_policy> lock(this);
   connections_list::iterator it 
= m_connected_slots.begin();
   connections_list::iterator itEnd 
= m_connected_slots.end();
   
while(it != itEnd)
   

    
if((*it)->getdest() == pclass)
    

     delete 
*it;
     m_connected_slots.erase(it);
     pclass
->signal_disconnect(this); //has_slots函数
     return;
    

    
++it;
   

  

  
void slot_disconnect(has_slots<mt_policy>* pslot)
  

   lock_block
<mt_policy> lock(this);
   connections_list::iterator it 
= m_connected_slots.begin();
   connections_list::iterator itEnd 
= m_connected_slots.end();
   
while(it != itEnd)
   

    connections_list::iterator itNext 
= it;
    
++itNext;
    
if((*it)->getdest() ==Gtalk源码剖析之:sigslot介绍

Gtalk源码剖析之:sigslot源代码

Gtalk源码剖析之:sigslot源代码

Gtalk源码剖析之:sigslot源代码

06 drf源码剖析之权限

05 drf源码剖析之认证