- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gmonitor.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2013 Graeme Walker <graeme_walker@users.sourceforge.net>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // gmonitor.cpp
19 //
20
21 #include "gdef.h"
22 #include "gnet.h"
23 #include "glimits.h"
24 #include "gmonitor.h"
25 #include "gstr.h"
26 #include "gassert.h"
27 #include <map>
28 #include <deque>
29 #include <algorithm> // std::swap
30 #include <utility> // std::swap
31
35 class GNet::MonitorImp
36 {
37 public:
38 explicit MonitorImp( Monitor & monitor ) ;
39 void add( const Connection & , bool is_client ) ;
40 void remove( const Connection & , bool is_client ) ;
41 void report( std::ostream & s , const std::string & px , const std::string & eol ) const ;
42 std::string certificateId( const std::string & certificiate ) ;
43 std::pair<std::string,bool> findCertificate( const std::string & certificate ) ;
44
45 private:
46 struct ConnectionInfo
47 {
48 bool is_client ;
49 explicit ConnectionInfo( bool is_client_ ) : is_client(is_client_) {}
50 } ;
51 struct CertificateInfo
52 {
53 std::string certificate ;
54 int id ;
55 CertificateInfo( const std::string & c , int id_ ) : certificate(c) , id(id_) {}
56 bool match( std::string s ) const { return s == certificate ; }
57 } ;
58 struct CertificateMatch
59 {
60 const std::string & m_s ;
61 explicit CertificateMatch( const std::string & s ) : m_s(s) {}
62 bool operator()( const CertificateInfo & o ) const { return o.match(m_s) ; }
63 } ;
64 typedef std::map<const Connection*,ConnectionInfo> ConnectionMap ;
65 typedef std::deque<CertificateInfo> Certificates ;
66 ConnectionMap m_connections ;
67 Certificates m_certificates ;
68 int m_id_generator ;
69 unsigned long m_client_adds ;
70 unsigned long m_client_removes ;
71 unsigned long m_server_peer_adds ;
72 unsigned long m_server_peer_removes ;
73 } ;
74
75 GNet::MonitorImp::MonitorImp( Monitor & monitor ) :
76 m_id_generator(0) ,
77 m_client_adds(0UL) ,
78 m_client_removes(0UL) ,
79 m_server_peer_adds(0UL) ,
80 m_server_peer_removes(0UL)
81 {
82 }
83
84 // ===
85
86 GNet::Monitor * & GNet::Monitor::pthis()
87 {
88 static GNet::Monitor * p = NULL ;
89 return p ;
90 }
91
92 GNet::Monitor::Monitor() :
93 m_imp( new MonitorImp(*this) )
94 {
95 G_ASSERT( pthis() == NULL ) ;
96 pthis() = this ;
97 }
98
99 GNet::Monitor::~Monitor()
100 {
101 delete m_imp ;
102 pthis() = NULL ;
103 }
104
105 GNet::Monitor * GNet::Monitor::instance()
106 {
107 return pthis() ;
108 }
109
110 G::Signal2<std::string,std::string> & GNet::Monitor::signal()
111 {
112 return m_signal ;
113 }
114
115 void GNet::Monitor::addClient( const Connection & client )
116 {
117 m_imp->add( client , true ) ;
118 m_signal.emit( "out" , "start" ) ;
119 }
120
121 void GNet::Monitor::removeClient( const Connection & client )
122 {
123 m_imp->remove( client , true ) ;
124 m_signal.emit( "out" , "end" ) ;
125 }
126
127 void GNet::Monitor::addServerPeer( const Connection & server_peer )
128 {
129 m_imp->add( server_peer , false ) ;
130 m_signal.emit( "in" , "start" ) ;
131 }
132
133
134 void GNet::Monitor::removeServerPeer( const Connection & server_peer )
135 {
136 m_imp->remove( server_peer , false ) ;
137 m_signal.emit( "in" , "end" ) ;
138 }
139
140 std::pair<std::string,bool> GNet::Monitor::findCertificate( const std::string & certificate )
141 {
142 return m_imp->findCertificate( certificate ) ;
143 }
144
145 void GNet::Monitor::report( std::ostream & s , const std::string & px , const std::string & eol ) const
146 {
147 m_imp->report( s , px , eol ) ;
148 }
149
150 // ==
151
152 void GNet::MonitorImp::add( const Connection & connection , bool is_client )
153 {
154 bool inserted = m_connections.insert(ConnectionMap::value_type(&connection,ConnectionInfo(is_client))).second ;
155 if( inserted )
156 {
157 if( is_client )
158 m_client_adds++ ;
159 else
160 m_server_peer_adds++ ;
161 }
162 }
163
164 void GNet::MonitorImp::remove( const Connection & connection , bool is_client )
165 {
166 bool removed = 0U != m_connections.erase( &connection ) ;
167 if( removed )
168 {
169 if( is_client )
170 m_client_removes++ ;
171 else
172 m_server_peer_removes++ ;
173 }
174 }
175
176 void GNet::MonitorImp::report( std::ostream & s , const std::string & px , const std::string & eol ) const
177 {
178 s << px << "OUT started: " << m_client_adds << eol ;
179 s << px << "OUT finished: " << m_client_removes << eol ;
180 {
181 for( ConnectionMap::const_iterator p = m_connections.begin() ; p != m_connections.end() ; ++p )
182 {
183 if( (*p).second.is_client )
184 {
185 s << px
186 << "OUT: "
187 << (*p).first->localAddress().second.displayString() << " -> "
188 << (*p).first->peerAddress().second.displayString() << eol ;
189 }
190 }
191 }
192
193 s << px << "IN started: " << m_server_peer_adds << eol ;
194 s << px << "IN finished: " << m_server_peer_removes << eol ;
195 {
196 for( ConnectionMap::const_iterator p = m_connections.begin() ; p != m_connections.end() ; ++p )
197 {
198 if( !(*p).second.is_client )
199 {
200 s << px
201 << "IN: "
202 << (*p).first->localAddress().second.displayString() << " <- "
203 << (*p).first->peerAddress().second.displayString() << eol ;
204 }
205 }
206 }
207 }
208
209 std::pair<std::string,bool> GNet::MonitorImp::findCertificate( const std::string & certificate )
210 {
211 std::pair<std::string,bool> result( std::string() , false ) ;
212 if( certificate.empty() )
213 return result ;
214
215 // lru cache
216 Certificates::iterator p = std::find_if( m_certificates.begin() , m_certificates.end() , CertificateMatch(certificate) ) ;
217 if( p != m_certificates.end() )
218 {
219 CertificateInfo tmp = *p ;
220 result.first = G::Str::fromInt( (*p).id ) ;
221 result.second = false ;
222 p = std::remove_if( m_certificates.begin() , m_certificates.end() , CertificateMatch(certificate) ) ;
223 G_ASSERT( p != m_certificates.end() ) ;
224 *p = tmp ;
225 }
226 else
227 {
228 const size_t limit = G::limits::net_certificate_cache_size ;
229 if( m_certificates.size() == limit && !m_certificates.empty() )
230 m_certificates.pop_front() ;
231 int id = ++m_id_generator ;
232 m_certificates.push_back( CertificateInfo(certificate,id) ) ;
233 result.first = G::Str::fromInt( id ) ;
234 result.second = true ;
235 }
236 return result ;
237 }
238
GNet::Monitor::removeServerPeer
void removeServerPeer(const Connection &server_peer)
Removes a server connection.
Definition: gmonitor.cpp:134
G::Signal2< std::string, std::string >
GNet::Monitor::report
void report(std::ostream &stream, const std::string &line_prefix=std::string(), const std::string &eol=std::string("\n")) const
Reports itself onto a stream.
Definition: gmonitor.cpp:145
GNet::MonitorImp::findCertificate
std::pair< std::string, bool > findCertificate(const std::string &certificate)
Definition: gmonitor.cpp:209
GNet::Monitor::signal
G::Signal2< std::string, std::string > & signal()
Provides a callback signal which can be connect()ed to a slot.
Definition: gmonitor.cpp:110
GNet::Monitor::addClient
void addClient(const Connection &simple_client)
Adds a client connection.
Definition: gmonitor.cpp:115
GNet::MonitorImp::remove
void remove(const Connection &, bool is_client)
Definition: gmonitor.cpp:164
G::Str::fromInt
static std::string fromInt(int i)
Converts int 'i' to a string.
Definition: gstr.cpp:236
G::limits::net_certificate_cache_size
Definition: glimits.h:51
GNet::MonitorImp::report
void report(std::ostream &s, const std::string &px, const std::string &eol) const
Definition: gmonitor.cpp:176
glimits.h
GNet::MonitorImp
A pimple pattern implementation class for GNet::Monitor.
Definition: gmonitor.cpp:35
G_ASSERT
#define G_ASSERT(test)
Definition: gassert.h:30
gstr.h
gassert.h
GNet::MonitorImp::certificateId
std::string certificateId(const std::string &certificiate)
GNet::Monitor
A singleton for monitoring SimpleClient and ServerPeer connections.
Definition: gmonitor.h:43
GNet::Monitor::instance
static Monitor * instance()
Returns the singleton pointer. Returns null if none.
Definition: gmonitor.cpp:105
GNet::Monitor::~Monitor
virtual ~Monitor()
Destructor.
Definition: gmonitor.cpp:99
GNet::Monitor::removeClient
void removeClient(const Connection &simple_client)
Removes a client connection.
Definition: gmonitor.cpp:121
gmonitor.h
GNet::Monitor::addServerPeer
void addServerPeer(const Connection &server_peer)
Adds a server connection.
Definition: gmonitor.cpp:127
GNet::Connection
An interface which provides address information for a network connection.
Definition: gconnection.h:39
GNet::Monitor::findCertificate
std::pair< std::string, bool > findCertificate(const std::string &certificate)
Returns a short id for the given certificate and a boolean flag to indicate if it is a new certificat...
Definition: gmonitor.cpp:140
GNet::MonitorImp::MonitorImp
MonitorImp(Monitor &monitor)
Definition: gmonitor.cpp:75
GNet::MonitorImp::add
void add(const Connection &, bool is_client)
Definition: gmonitor.cpp:152
GNet::Monitor::Monitor
Monitor()
Default constructor.
Definition: gmonitor.cpp:92