diff options
Diffstat (limited to '')
-rw-r--r-- | docs/doxygen/nel/buf__server_8cpp-source.html | 1240 |
1 files changed, 1240 insertions, 0 deletions
diff --git a/docs/doxygen/nel/buf__server_8cpp-source.html b/docs/doxygen/nel/buf__server_8cpp-source.html new file mode 100644 index 00000000..dc97cae7 --- /dev/null +++ b/docs/doxygen/nel/buf__server_8cpp-source.html @@ -0,0 +1,1240 @@ +<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> +<HTML> +<HEAD> + <TITLE>nevrax.org : docs</TITLE> + <LINK REL=stylesheet TYPE="text/css" HREF="http://www.nevrax.org/inc/css/nevrax.css"> + <link href="doxygen.css" rel="stylesheet" type="text/css"> +</HEAD> +<BODY MARGINHEIGHT="0" MARGINWIDTH="0"> + +<!-- uplinks --> +<TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0> + <TR> + <TD WIDTH=16><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="16" HEIGHT="16" BORDER=0 ALT=""></TD> + <TD WIDTH=140 BGCOLOR=#dddddd><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="140" HEIGHT="16" BORDER=0 ALT=""></TD> + <TD WIDTH=16><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="16" HEIGHT="16" BORDER=0 ALT=""></TD> + <TD><IMG width=6 height=14 SRC="http://www.nevrax.org/inc/img/reddots.gif" ALT="#" VSPACE=2 HSPACE=2 BORDER=0 ></TD><TD VALIGN=middle> <A CLASS=uplinks HREF=http://www.nevrax.org><b>Home</B></FONT></A> </TD> + <TD><IMG width=6 height=14 SRC="http://www.nevrax.org/inc/img/reddots.gif" ALT="#" VSPACE=2 HSPACE=2 BORDER=0 ></TD><TD VALIGN=middle> <A CLASS=uplinks HREF=http://www.nevrax.com><b>nevrax.com</B></FONT></A> </TD> + </TR> +</TABLE> + +<!-- banner Nevrax --> +<TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=100%> + <TR><TD BGCOLOR="#000000" BACKGROUND="http://www.nevrax.org/inc/img/black_banner.jpg"><A HREF="http://www.nevrax.org"><IMG SRC="http://www.nevrax.org/inc/img/nevrax.gif" WIDTH="170" HEIGHT="45" BORDER=0 ALT="Nevrax" ></A></TD></TR> +</TABLE> + +<!-- main table --> +<TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 height=100%> + <TR> + <TD WIDTH=16><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="16" HEIGHT="10" BORDER=0 ALT=""></TD> + <TD WIDTH=140 BGCOLOR=#dddddd VALIGN=TOP ALIGN=middle><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="140" HEIGHT="10" BORDER=0 ALT=""> + + <!------ Begin Box ------> + <TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 BGCOLOR=black><TR><TD><TABLE border=0 cellspacing=2 cellpadding=0 width=120><tr><TD ALIGN=middle bgcolor=black> + <FONT COLOR=white FACE="sans-serif"><B>Nevrax.org</B></FONT></TD></TR><tr><td colspan=2 bgcolor=#FFFFFF> + <TABLE cellspacing=0 cellpadding=1 border=0> + <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/news/" TITLE="Rubrique news"><img width=13 height=15 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-news.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/news/" TITLE="News">News</a></td></tr> + <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/mail/" TITLE="Rubrique mail"><img width=15 height=11 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-mail.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/mail/" TITLE="Mailing list archive">Mailing-list</a></td></tr> + <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/docs/" TITLE="Rubrique docs"><img width=14 height=16 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-docs.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/docs/" TITLE="Documentation">Documentation</a></td></tr> + <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/cvs/" TITLE="Rubrique cvs"><img width=13 height=17 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-cvs.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/cvs/" TITLE="CVS Web">CVS</a></td></tr> + <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/bugs/" TITLE="Rubrique bugs"><img width=20 height=16 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-bugs.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/bugs/" TITLE="Bugtracking">Bugs</a></td></tr> + <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/GPL.php3" TITLE="Rubrique license"><img width=18 height=12 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-gpl.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/GPL.php3" TITLE="License">License</a></td></tr> + </TABLE> + </TD></TR></TABLE></TD></TR></TABLE> + <!------ End Box ------> + + </TD> + <TD WIDTH=15><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="16" HEIGHT="16" BORDER=0 ALT=""></TD> + <TD ALIGN=left valign=top><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="140" HEIGHT="10" BORDER=0 ALT=""> + +<!-- title --> +<TABLE background="http://www.nevrax.org/inc/img/redline.gif" CELLSPACING=0 CELLPADDING=0 BORDER=0 width=100%><tr><td> +<A HREF="http://www.nevrax.org/docs/"><img src="http://www.nevrax.org/inc/img/t_docs.gif" ALT="Docs" HEIGHT=20 BORDER=0></A> +</td><td><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="1" HEIGHT="1" BORDER=0 ALT=""> +</td></tr></table> + + +<!-- block --> +<TABLE bgcolor="#dddddd" CELLSPACING=0 CELLPADDING=0 BORDER=0 width=100%><tr><td width=1% valign=middle><img width=6 height=14 hspace=2 vspace=2 src="http://www.nevrax.org/inc/img/reddots.gif"></TD> + <TD><B>Documentation</B></TD> + <TD ALIGN=RIGHT> </td> +</tr></table> +<!-- Generated by Doxygen 1.2.14 --> +<center> +<a class="qindex" href="index.html">Main Page</a> <a class="qindex" href="namespaces.html">Namespace List</a> <a class="qindex" href="hierarchy.html">Class Hierarchy</a> <a class="qindex" href="classes.html">Alphabetical List</a> <a class="qindex" href="annotated.html">Compound List</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="namespacemembers.html">Namespace Members</a> <a class="qindex" href="functions.html">Compound Members</a> <a class="qindex" href="globals.html">File Members</a> <a class="qindex" href="pages.html">Related Pages</a> <a class="qindexRef" doxygen="_cgi:http://www.nevrax.org/cgi-bin/nel-search.cgi" href="http://www.nevrax.org/cgi-bin/nel-search.cgi">Search</a> </center> +<hr><h1>buf_server.cpp</h1><a href="buf__server_8cpp.html">Go to the documentation of this file.</a><div class="fragment"><pre>00001 +00007 <font class="comment">/* Copyright, 2001 Nevrax Ltd.</font> +00008 <font class="comment"> *</font> +00009 <font class="comment"> * This file is part of NEVRAX NEL.</font> +00010 <font class="comment"> * NEVRAX NEL is free software; you can redistribute it and/or modify</font> +00011 <font class="comment"> * it under the terms of the GNU General Public License as published by</font> +00012 <font class="comment"> * the Free Software Foundation; either version 2, or (at your option)</font> +00013 <font class="comment"> * any later version.</font> +00014 <font class="comment"></font> +00015 <font class="comment"> * NEVRAX NEL is distributed in the hope that it will be useful, but</font> +00016 <font class="comment"> * WITHOUT ANY WARRANTY; without even the implied warranty of</font> +00017 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU</font> +00018 <font class="comment"> * General Public License for more details.</font> +00019 <font class="comment"></font> +00020 <font class="comment"> * You should have received a copy of the GNU General Public License</font> +00021 <font class="comment"> * along with NEVRAX NEL; see the file COPYING. If not, write to the</font> +00022 <font class="comment"> * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,</font> +00023 <font class="comment"> * MA 02111-1307, USA.</font> +00024 <font class="comment"> */</font> +00025 +00026 <font class="preprocessor">#include "<a class="code" href="stdnet_8h.html">stdnet.h</a>"</font> +00027 +00028 <font class="preprocessor">#include "<a class="code" href="hierarchical__timer_8h.html">nel/misc/hierarchical_timer.h</a>"</font> +00029 +00030 <font class="preprocessor">#include "<a class="code" href="buf__server_8h.html">nel/net/buf_server.h</a>"</font> +00031 +00032 <font class="preprocessor">#ifdef NL_OS_WINDOWS</font> +00033 <font class="preprocessor"></font><font class="preprocessor">#include <winsock2.h></font> +00034 <font class="comment">//typedef sint socklen_t;</font> +00035 +00036 <font class="preprocessor">#elif defined NL_OS_UNIX</font> +00037 <font class="preprocessor"></font><font class="preprocessor">#include <<a class="code" href="unistd_8h.html">unistd.h</a>></font> +00038 <font class="preprocessor">#include <sys/types.h></font> +00039 <font class="preprocessor">#include <sys/time.h></font> +00040 <font class="preprocessor">#endif</font> +00041 <font class="preprocessor"></font> +00042 +00043 <font class="keyword">using</font> <font class="keyword">namespace </font>NLMISC; +00044 <font class="keyword">using</font> <font class="keyword">namespace </font>std; +00045 +00046 <font class="keyword">namespace </font>NLNET { +00047 +00048 +00049 <font class="comment">/***************************************************************************************************</font> +00050 <font class="comment"> * User main thread (initialization)</font> +00051 <font class="comment"> **************************************************************************************************/</font> +00052 +00053 +00054 <font class="comment">/*</font> +00055 <font class="comment"> * Constructor</font> +00056 <font class="comment"> */</font> +<a name="l00057"></a><a class="code" href="classNLNET_1_1CBufServer.html#a0">00057</a> CBufServer::CBufServer( TThreadStategy strategy, +00058 uint16 max_threads, uint16 max_sockets_per_thread, <font class="keywordtype">bool</font> nodelay, <font class="keywordtype">bool</font> replaymode ) : +00059 CBufNetBase(), +00060 _NoDelay( nodelay ), +00061 _ThreadStrategy( strategy ), +00062 _MaxThreads( max_threads ), +00063 _MaxSocketsPerThread( max_sockets_per_thread ), +00064 _ListenTask( NULL ), +00065 _ListenThread( NULL ), +00066 _ThreadPool("CBufServer::_ThreadPool"), +00067 _ConnectionCallback( NULL ), +00068 _ConnectionCbArg( NULL ), +00069 _BytesPushedOut( 0 ), +00070 _BytesPoppedIn( 0 ), +00071 _PrevBytesPoppedIn( 0 ), +00072 _PrevBytesPushedOut( 0 ), +00073 _NbConnections (0), +00074 _ReplayMode( replaymode ) +00075 { +00076 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"CBufServer::CBufServer"</font> ); +00077 <font class="keywordflow">if</font> ( ! <a class="code" href="classNLNET_1_1CBufServer.html#o14">_ReplayMode</a> ) +00078 { +00079 <a class="code" href="classNLNET_1_1CBufServer.html#o4">_ListenTask</a> = <font class="keyword">new</font> <a class="code" href="classNLNET_1_1CBufServer.html#l1">CListenTask</a>( <font class="keyword">this</font> ); +00080 <a class="code" href="classNLNET_1_1CBufServer.html#o5">_ListenThread</a> = IThread::create( <a class="code" href="classNLNET_1_1CBufServer.html#o4">_ListenTask</a> ); +00081 } +00082 <font class="comment">/*{</font> +00083 <font class="comment"> CSynchronized<uint32>::CAccessor syncbpi ( &_BytesPushedIn );</font> +00084 <font class="comment"> syncbpi.value() = 0;</font> +00085 <font class="comment"> }*/</font> +00086 } +00087 +00088 +00089 <font class="comment">/*</font> +00090 <font class="comment"> * Listens on the specified port</font> +00091 <font class="comment"> */</font> +<a name="l00092"></a><a class="code" href="classNLNET_1_1CBufServer.html#a2">00092</a> <font class="keywordtype">void</font> CBufServer::init( uint16 port ) +00093 { +00094 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"CBufServer::init"</font> ); +00095 <font class="keywordflow">if</font> ( ! <a class="code" href="classNLNET_1_1CBufServer.html#o14">_ReplayMode</a> ) +00096 { +00097 <a class="code" href="classNLNET_1_1CBufServer.html#o4">_ListenTask</a>->init( port ); +00098 <a class="code" href="classNLNET_1_1CBufServer.html#o5">_ListenThread</a>-><a class="code" href="classNLMISC_1_1IThread.html#a1">start</a>(); +00099 } +00100 <font class="keywordflow">else</font> +00101 { +00102 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL0: Binding listen socket to any address, port %hu"</font>, port ); +00103 } +00104 } +00105 +00106 +00107 <font class="comment">/*</font> +00108 <font class="comment"> * Begins to listen on the specified port (call before running thread)</font> +00109 <font class="comment"> */</font> +<a name="l00110"></a><a class="code" href="classNLNET_1_1CListenTask.html#a1">00110</a> <font class="keywordtype">void</font> CListenTask::init( uint16 port ) +00111 { +00112 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"CListenTask::init"</font> ); +00113 <a class="code" href="classNLNET_1_1CListenTask.html#o1">_ListenSock</a>.init( port ); +00114 } +00115 +00116 +00117 <font class="comment">/***************************************************************************************************</font> +00118 <font class="comment"> * User main thread (running)</font> +00119 <font class="comment"> **************************************************************************************************/</font> +00120 +00121 +00122 <font class="comment">/*</font> +00123 <font class="comment"> * Constructor</font> +00124 <font class="comment"> */</font> +<a name="l00125"></a><a class="code" href="classNLNET_1_1CServerTask.html#b0">00125</a> CServerTask::CServerTask() : _ExitRequired(false) +00126 { +00127 <font class="preprocessor">#ifdef NL_OS_UNIX</font> +00128 <font class="preprocessor"></font> pipe( _WakeUpPipeHandle ); +00129 <font class="preprocessor">#endif</font> +00130 <font class="preprocessor"></font>} +00131 +00132 +00133 +00134 <font class="preprocessor">#ifdef NL_OS_UNIX</font> +00135 <font class="preprocessor"></font><font class="comment">/*</font> +00136 <font class="comment"> * Wake the thread up, when blocked in select (Unix only)</font> +00137 <font class="comment"> */</font> +00138 <font class="keywordtype">void</font> CServerTask::wakeUp() +00139 { +00140 uint8 b; +00141 <font class="keywordflow">if</font> ( write( _WakeUpPipeHandle[PipeWrite], &b, 1 ) == -1 ) +00142 { +00143 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: In CServerTask::wakeUp(): write() failed"</font> ); +00144 } +00145 } +00146 <font class="preprocessor">#endif</font> +00147 <font class="preprocessor"></font> +00148 +00149 <font class="comment">/*</font> +00150 <font class="comment"> * Destructor</font> +00151 <font class="comment"> */</font> +<a name="l00152"></a><a class="code" href="classNLNET_1_1CServerTask.html#a0">00152</a> CServerTask::~CServerTask() +00153 { +00154 <font class="preprocessor">#ifdef NL_OS_UNIX</font> +00155 <font class="preprocessor"></font> close( _WakeUpPipeHandle[PipeRead] ); +00156 close( _WakeUpPipeHandle[PipeWrite] ); +00157 <font class="preprocessor">#endif</font> +00158 <font class="preprocessor"></font>} +00159 +00160 +00161 <font class="comment">/*</font> +00162 <font class="comment"> * Destructor</font> +00163 <font class="comment"> */</font> +<a name="l00164"></a><a class="code" href="classNLNET_1_1CBufServer.html#a1">00164</a> CBufServer::~CBufServer() +00165 { +00166 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"CBufServer::~CBufServer"</font> ); +00167 +00168 <font class="comment">// Clean listen thread exit</font> +00169 <font class="keywordflow">if</font> ( ! <a class="code" href="classNLNET_1_1CBufServer.html#o14">_ReplayMode</a> ) +00170 { +00171 ((<a class="code" href="classNLNET_1_1CBufServer.html#l1">CListenTask</a>*)(<a class="code" href="classNLNET_1_1CBufServer.html#o5">_ListenThread</a>-><a class="code" href="classNLMISC_1_1IThread.html#a4">getRunnable</a>()))->requireExit(); +00172 ((<a class="code" href="classNLNET_1_1CBufServer.html#l1">CListenTask</a>*)(<a class="code" href="classNLNET_1_1CBufServer.html#o5">_ListenThread</a>-><a class="code" href="classNLMISC_1_1IThread.html#a4">getRunnable</a>()))->close(); +00173 <font class="preprocessor">#ifdef NL_OS_UNIX</font> +00174 <font class="preprocessor"></font> <a class="code" href="classNLNET_1_1CBufServer.html#o4">_ListenTask</a>->wakeUp(); +00175 <font class="preprocessor">#endif</font> +00176 <font class="preprocessor"></font> <a class="code" href="classNLNET_1_1CBufServer.html#o5">_ListenThread</a>-><a class="code" href="classNLMISC_1_1IThread.html#a3">wait</a>(); +00177 <font class="keyword">delete</font> <a class="code" href="classNLNET_1_1CBufServer.html#o5">_ListenThread</a>; +00178 <font class="keyword">delete</font> <a class="code" href="classNLNET_1_1CBufServer.html#o4">_ListenTask</a>; +00179 +00180 <font class="comment">// Clean receive thread exits</font> +00181 CThreadPool::iterator ipt; +00182 { +00183 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: Waiting for end of threads..."</font> ); +00184 CSynchronized<CThreadPool>::CAccessor poolsync( &<a class="code" href="classNLNET_1_1CBufServer.html#o6">_ThreadPool</a> ); +00185 <font class="keywordflow">for</font> ( ipt=poolsync.value().begin(); ipt!=poolsync.value().end(); ++ipt ) +00186 { +00187 <font class="comment">// Tell the threads to exit and wake them up</font> +00188 <a class="code" href="classNLNET_1_1CBufServer.html#l2">CServerReceiveTask</a> *task = <a class="code" href="classNLNET_1_1CBufServer.html#b2">receiveTask</a>(ipt); +00189 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"Requiring exit"</font> ); +00190 task->requireExit(); +00191 +00192 <font class="comment">// Wake the threads up</font> +00193 <font class="preprocessor"> #ifdef NL_OS_UNIX</font> +00194 <font class="preprocessor"></font> task->wakeUp(); +00195 <font class="preprocessor"> #else</font> +00196 <font class="preprocessor"></font> CConnections::iterator ipb; +00197 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"Closing sockets (Win32)"</font> ); +00198 { +00199 CSynchronized<CConnections>::CAccessor connectionssync( &task->_Connections ); +00200 <font class="keywordflow">for</font> ( ipb=connectionssync.value().begin(); ipb!=connectionssync.value().end(); ++ipb ) +00201 { +00202 (*ipb)->Sock->close(); +00203 } +00204 } +00205 <font class="preprocessor"> #endif</font> +00206 <font class="preprocessor"></font> +00207 } +00208 +00209 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"Waiting"</font> ); +00210 <font class="keywordflow">for</font> ( ipt=poolsync.value().begin(); ipt!=poolsync.value().end(); ++ipt ) +00211 { +00212 <font class="comment">// Wait until the threads have exited</font> +00213 (*ipt)->wait(); +00214 } +00215 +00216 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: Deleting sockets, tasks and threads..."</font> ); +00217 <font class="keywordflow">for</font> ( ipt=poolsync.value().begin(); ipt!=poolsync.value().end(); ++ipt ) +00218 { +00219 <font class="comment">// Delete the socket objects</font> +00220 <a class="code" href="classNLNET_1_1CBufServer.html#l2">CServerReceiveTask</a> *task = <a class="code" href="classNLNET_1_1CBufServer.html#b2">receiveTask</a>(ipt); +00221 CConnections::iterator ipb; +00222 { +00223 CSynchronized<CConnections>::CAccessor connectionssync( &task->_Connections ); +00224 <font class="keywordflow">for</font> ( ipb=connectionssync.value().begin(); ipb!=connectionssync.value().end(); ++ipb ) +00225 { +00226 <font class="keyword">delete</font> (*ipb); +00227 } +00228 } +00229 +00230 <font class="preprocessor"> #ifdef NL_OS_UNIX</font> +00231 <font class="preprocessor"></font> <font class="comment">// Under Unix, close the sockets now</font> +00232 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"Closing sockets (Unix)"</font> ); +00233 { +00234 CSynchronized<CConnections>::CAccessor connectionssync( &task->_Connections ); +00235 <font class="keywordflow">for</font> ( ipb=connectionssync.value().begin(); ipb!=connectionssync.value().end(); ++ipb ) +00236 { +00237 (*ipb)->Sock->close(); +00238 } +00239 } +00240 <font class="preprocessor"> #endif</font> +00241 <font class="preprocessor"></font> +00242 <font class="comment">// Delete the task objects</font> +00243 <font class="keyword">delete</font> task; +00244 +00245 <font class="comment">// Delete the thread objects</font> +00246 <font class="keyword">delete</font> (*ipt); +00247 } +00248 } +00249 } +00250 +00251 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"Exiting CBufServer::~CBufServer"</font> ); +00252 } +00253 +00254 +00255 <font class="comment">/*</font> +00256 <font class="comment"> * Disconnect the specified host</font> +00257 <font class="comment"> * Set hostid to NULL to disconnect all connections.</font> +00258 <font class="comment"> * If hostid is not null and the socket is not connected, the method does nothing.</font> +00259 <font class="comment"> * If quick is true, any pending data will not be sent before disconnecting.</font> +00260 <font class="comment"> */</font> +<a name="l00261"></a><a class="code" href="classNLNET_1_1CBufServer.html#a3">00261</a> <font class="keywordtype">void</font> CBufServer::disconnect( <a class="code" href="namespaceNLNET.html#a0">TSockId</a> hostid, <font class="keywordtype">bool</font> quick ) +00262 { +00263 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"CBufServer::disconnect"</font> ); +00264 <font class="keywordflow">if</font> ( hostid != InvalidSockId ) +00265 { +00266 <font class="comment">// Disconnect only if physically connected</font> +00267 <font class="keywordflow">if</font> ( hostid->Sock->connected() ) +00268 { +00269 <font class="keywordflow">if</font> ( ! quick ) +00270 { +00271 hostid->flush(); +00272 } +00273 hostid->Sock->disconnect(); <font class="comment">// the connection will be removed by the next call of update()</font> +00274 } +00275 } +00276 <font class="keywordflow">else</font> +00277 { +00278 <font class="comment">// Disconnect all</font> +00279 CThreadPool::iterator ipt; +00280 { +00281 CSynchronized<CThreadPool>::CAccessor poolsync( &<a class="code" href="classNLNET_1_1CBufServer.html#o6">_ThreadPool</a> ); +00282 <font class="keywordflow">for</font> ( ipt=poolsync.value().begin(); ipt!=poolsync.value().end(); ++ipt ) +00283 { +00284 <a class="code" href="classNLNET_1_1CBufServer.html#l2">CServerReceiveTask</a> *task = <a class="code" href="classNLNET_1_1CBufServer.html#b2">receiveTask</a>(ipt); +00285 CConnections::iterator ipb; +00286 { +00287 CSynchronized<CConnections>::CAccessor connectionssync( &task->_Connections ); +00288 <font class="keywordflow">for</font> ( ipb=connectionssync.value().begin(); ipb!=connectionssync.value().end(); ++ipb ) +00289 { +00290 <font class="keywordflow">if</font> ( (*ipb)->Sock->connected() ) +00291 { +00292 <font class="keywordflow">if</font> ( ! quick ) +00293 { +00294 (*ipb)->flush(); +00295 } +00296 (*ipb)->Sock->disconnect(); +00297 } +00298 } +00299 } +00300 } +00301 } +00302 } +00303 } +00304 +00305 +00306 <font class="comment">/*</font> +00307 <font class="comment"> * Send a message to the specified host</font> +00308 <font class="comment"> */</font> +00309 <font class="keywordtype">void</font> CBufServer::send( <font class="keyword">const</font> CMemStream& buffer, <a class="code" href="namespaceNLNET.html#a0">TSockId</a> hostid ) +00310 { +00311 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"CBufServer::send"</font> ); +00312 <a class="code" href="debug_8h.html#a6">nlassert</a>( buffer.length() > 0); +00313 <a class="code" href="debug_8h.html#a6">nlassert</a>( buffer.length() <= <a class="code" href="classNLNET_1_1CBufNetBase.html#a6">maxSentBlockSize</a>() ); +00314 +00315 <font class="comment">// slow down the layer H_AUTO (CBufServer_send);</font> +00316 +00317 <font class="keywordflow">if</font> ( hostid != InvalidSockId ) +00318 { +00319 <font class="comment">// debug features, we number all packet to be sure that they are all sent and received</font> +00320 <font class="comment">// \todo remove this debug feature when ok</font> +00321 <font class="comment">// nldebug ("send message number %u", hostid->SendNextValue);</font> +00322 <font class="preprocessor">#ifdef NL_BIG_ENDIAN</font> +00323 <font class="preprocessor"></font> uint32 val = <a class="code" href="stream_8h.html#a1">NLMISC_BSWAP32</a>(hostid->SendNextValue); +00324 <font class="preprocessor">#else</font> +00325 <font class="preprocessor"></font> uint32 val = hostid->SendNextValue; +00326 <font class="preprocessor">#endif</font> +00327 <font class="preprocessor"></font> +00328 *(uint32*)buffer.buffer() = val; +00329 hostid->SendNextValue++; +00330 +00331 <a class="code" href="classNLNET_1_1CBufServer.html#b3">pushBufferToHost</a>( buffer, hostid ); +00332 } +00333 <font class="keywordflow">else</font> +00334 { +00335 <font class="comment">// Push into all send queues</font> +00336 CThreadPool::iterator ipt; +00337 { +00338 CSynchronized<CThreadPool>::CAccessor poolsync( &<a class="code" href="classNLNET_1_1CBufServer.html#o6">_ThreadPool</a> ); +00339 <font class="keywordflow">for</font> ( ipt=poolsync.value().begin(); ipt!=poolsync.value().end(); ++ipt ) +00340 { +00341 <a class="code" href="classNLNET_1_1CBufServer.html#l2">CServerReceiveTask</a> *task = <a class="code" href="classNLNET_1_1CBufServer.html#b2">receiveTask</a>(ipt); +00342 CConnections::iterator ipb; +00343 { +00344 CSynchronized<CConnections>::CAccessor connectionssync( &task->_Connections ); +00345 <font class="keywordflow">for</font> ( ipb=connectionssync.value().begin(); ipb!=connectionssync.value().end(); ++ipb ) +00346 { +00347 <font class="comment">// Send only if the socket is logically connected</font> +00348 <font class="keywordflow">if</font> ( (*ipb)->connectedState() ) +00349 { +00350 <font class="comment">// debug features, we number all packet to be sure that they are all sent and received</font> +00351 <font class="comment">// \todo remove this debug feature when ok</font> +00352 <font class="comment">// nldebug ("send message number %u", (*ipb)->SendNextValue);</font> +00353 <font class="preprocessor">#ifdef NL_BIG_ENDIAN</font> +00354 <font class="preprocessor"></font> uint32 val = <a class="code" href="stream_8h.html#a1">NLMISC_BSWAP32</a>((*ipb)->SendNextValue); +00355 <font class="preprocessor">#else</font> +00356 <font class="preprocessor"></font> uint32 val = (*ipb)->SendNextValue; +00357 <font class="preprocessor">#endif</font> +00358 <font class="preprocessor"></font> *(uint32*)buffer.buffer() = val; +00359 (*ipb)->SendNextValue++; +00360 +00361 <a class="code" href="classNLNET_1_1CBufServer.html#b3">pushBufferToHost</a>( buffer, *ipb ); +00362 } +00363 } +00364 } +00365 } +00366 } +00367 } +00368 } +00369 +00370 +00371 <font class="comment">/*</font> +00372 <font class="comment"> * Checks if there are some data to receive</font> +00373 <font class="comment"> */</font> +<a name="l00374"></a><a class="code" href="classNLNET_1_1CBufServer.html#a6">00374</a> <font class="keywordtype">bool</font> CBufServer::dataAvailable() +00375 { +00376 <font class="comment">// slow down the layer H_AUTO (CBufServer_dataAvailable);</font> +00377 { +00378 <font class="comment">/* If no data available, enter the 'while' loop and return false (1 volatile test)</font> +00379 <font class="comment"> * If there are user data available, enter the 'while' and return true immediately (1 volatile test + 1 short locking)</font> +00380 <font class="comment"> * If there is a connection/disconnection event (rare), call the callback and loop</font> +00381 <font class="comment"> */</font> +00382 <font class="keywordflow">while</font> ( <a class="code" href="classNLNET_1_1CBufNetBase.html#b7">dataAvailableFlag</a>() ) +00383 { +00384 <font class="comment">// Because _DataAvailable is true, the receive queue is not empty at this point</font> +00385 vector<uint8> buffer; +00386 uint8 val; +00387 { +00388 <a class="code" href="namespaceNLNET.html#a5">CFifoAccessor</a> recvfifo( &<a class="code" href="classNLNET_1_1CBufNetBase.html#b1">receiveQueue</a>() ); +00389 val = recvfifo.value().frontLast(); +00390 <font class="keywordflow">if</font> ( val != CBufNetBase::User ) +00391 { +00392 recvfifo.value().front( buffer ); +00393 } +00394 } +00395 +00396 <font class="comment">/*sint32 mbsize = recvfifo.value().size() / 1048576;</font> +00397 <font class="comment"> if ( mbsize > 0 )</font> +00398 <font class="comment"> {</font> +00399 <font class="comment"> nlwarning( "The receive queue size exceeds %d MB", mbsize );</font> +00400 <font class="comment"> }*/</font> +00401 +00402 <font class="comment">/*vector<uint8> buffer;</font> +00403 <font class="comment"> recvfifo.value().front( buffer );*/</font> +00404 +00405 <font class="comment">// Test if it the next block is a system event</font> +00406 <font class="comment">//switch ( buffer[buffer.size()-1] )</font> +00407 <font class="keywordflow">switch</font> ( val ) +00408 { +00409 +00410 <font class="comment">// Normal message available</font> +00411 <font class="keywordflow">case</font> CBufNetBase::User: +00412 <font class="keywordflow">return</font> <font class="keyword">true</font>; <font class="comment">// return immediatly, do not extract the message</font> +00413 +00414 <font class="comment">// Process disconnection event</font> +00415 <font class="keywordflow">case</font> CBufNetBase::Disconnection: +00416 { +00417 <a class="code" href="namespaceNLNET.html#a0">TSockId</a> sockid = *((<a class="code" href="namespaceNLNET.html#a0">TSockId</a>*)(&*buffer.begin())); +00418 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: Disconnection event for %p %s"</font>, sockid, sockid->asString().c_str()); +00419 +00420 sockid->setConnectedState( <font class="keyword">false</font> ); +00421 +00422 <font class="comment">// Call callback if needed</font> +00423 <font class="keywordflow">if</font> ( <a class="code" href="classNLNET_1_1CBufNetBase.html#b2">disconnectionCallback</a>() != NULL ) +00424 { +00425 <a class="code" href="classNLNET_1_1CBufNetBase.html#b2">disconnectionCallback</a>()( sockid, <a class="code" href="classNLNET_1_1CBufNetBase.html#b3">argOfDisconnectionCallback</a>() ); +00426 } +00427 +00428 <font class="comment">// Add socket object into the synchronized remove list</font> +00429 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: Adding the connection to the remove list"</font> ); +00430 <a class="code" href="debug_8h.html#a6">nlassert</a>( ((<a class="code" href="classNLNET_1_1CBufServer.html#l0">CServerBufSock</a>*)sockid)->ownerTask() != NULL ); +00431 ((<a class="code" href="classNLNET_1_1CBufServer.html#l0">CServerBufSock</a>*)sockid)->ownerTask()->addToRemoveSet( sockid ); +00432 <font class="keywordflow">break</font>; +00433 } +00434 <font class="comment">// Process connection event</font> +00435 <font class="keywordflow">case</font> CBufNetBase::Connection: +00436 { +00437 <a class="code" href="namespaceNLNET.html#a0">TSockId</a> sockid = *((<a class="code" href="namespaceNLNET.html#a0">TSockId</a>*)(&*buffer.begin())); +00438 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: Connection event for %p %s"</font>, sockid, sockid->asString().c_str()); +00439 +00440 sockid->setConnectedState( <font class="keyword">true</font> ); +00441 +00442 <font class="comment">// Call callback if needed</font> +00443 <font class="keywordflow">if</font> ( <a class="code" href="classNLNET_1_1CBufServer.html#b5">connectionCallback</a>() != NULL ) +00444 { +00445 <a class="code" href="classNLNET_1_1CBufServer.html#b5">connectionCallback</a>()( sockid, <a class="code" href="classNLNET_1_1CBufServer.html#b6">argOfConnectionCallback</a>() ); +00446 } +00447 <font class="keywordflow">break</font>; +00448 } +00449 <font class="keywordflow">default</font>: <font class="comment">// should not occur</font> +00450 <a class="code" href="debug_8h.html#a1">nlinfo</a>( <font class="stringliteral">"LNETL1: Invalid block type: %hu (should be = to %hu"</font>, (uint16)(buffer[buffer.size()-1]), (uint16)(val) ); +00451 <a class="code" href="debug_8h.html#a1">nlinfo</a>( <font class="stringliteral">"LNETL1: Buffer (%d B): [%s]"</font>, buffer.size(), stringFromVector(buffer).c_str() ); +00452 <a class="code" href="debug_8h.html#a1">nlinfo</a>( <font class="stringliteral">"LNETL1: Receive queue:"</font> ); +00453 { +00454 <a class="code" href="namespaceNLNET.html#a5">CFifoAccessor</a> recvfifo( &<a class="code" href="classNLNET_1_1CBufNetBase.html#b1">receiveQueue</a>() ); +00455 recvfifo.value().display(); +00456 } +00457 <a class="code" href="debug_8h.html#a3">nlerror</a>( <font class="stringliteral">"LNETL1: Invalid system event type in server receive queue"</font> ); +00458 +00459 } +00460 +00461 <font class="comment">// Extract system event</font> +00462 { +00463 <a class="code" href="namespaceNLNET.html#a5">CFifoAccessor</a> recvfifo( &<a class="code" href="classNLNET_1_1CBufNetBase.html#b1">receiveQueue</a>() ); +00464 recvfifo.value().pop(); +00465 <a class="code" href="classNLNET_1_1CBufNetBase.html#b6">setDataAvailableFlag</a>( ! recvfifo.value().empty() ); +00466 } +00467 } +00468 <font class="comment">// _DataAvailable is false here</font> +00469 <font class="keywordflow">return</font> <font class="keyword">false</font>; +00470 } +00471 } +00472 +00473 +00474 <font class="comment">/* // OLD VERSION</font> +00475 <font class="comment">bool CBufServer::dataAvailable()</font> +00476 <font class="comment">{</font> +00477 <font class="comment"> // slow down the layer H_AUTO (CBufServer_dataAvailable);</font> +00478 <font class="comment"> {</font> +00479 <font class="comment"> CFifoAccessor recvfifo( &receiveQueue() );</font> +00480 <font class="comment"> do</font> +00481 <font class="comment"> {</font> +00482 <font class="comment"> // Check if the receive queue is empty</font> +00483 <font class="comment"> if ( recvfifo.value().empty() )</font> +00484 <font class="comment"> {</font> +00485 <font class="comment"> return false;</font> +00486 <font class="comment"> }</font> +00487 <font class="comment"> else</font> +00488 <font class="comment"> {</font> +00489 <font class="comment"> //sint32 mbsize = recvfifo.value().size() / 1048576;</font> +00490 <font class="comment"> //if ( mbsize > 0 )</font> +00491 <font class="comment"> //{</font> +00492 <font class="comment"> // nlwarning( "The receive queue size exceeds %d MB", mbsize );</font> +00493 <font class="comment"> //}</font> +00494 <font class="comment"></font> +00495 <font class="comment"> uint8 val = recvfifo.value().frontLast();</font> +00496 <font class="comment"> </font> +00497 <font class="comment"> //vector<uint8> buffer;</font> +00498 <font class="comment"> //recvfifo.value().front( buffer );</font> +00499 <font class="comment"></font> +00500 <font class="comment"> // Test if it the next block is a system event</font> +00501 <font class="comment"> //switch ( buffer[buffer.size()-1] )</font> +00502 <font class="comment"> switch ( val )</font> +00503 <font class="comment"> {</font> +00504 <font class="comment"> </font> +00505 <font class="comment"> // Normal message available</font> +00506 <font class="comment"> case CBufNetBase::User:</font> +00507 <font class="comment"> return true; // return immediatly, do not extract the message</font> +00508 <font class="comment"></font> +00509 <font class="comment"> // Process disconnection event</font> +00510 <font class="comment"> case CBufNetBase::Disconnection:</font> +00511 <font class="comment"> {</font> +00512 <font class="comment"> vector<uint8> buffer;</font> +00513 <font class="comment"> recvfifo.value().front( buffer );</font> +00514 <font class="comment"></font> +00515 <font class="comment"> TSockId sockid = *((TSockId*)(&*buffer.begin()));</font> +00516 <font class="comment"> nldebug( "LNETL1: Disconnection event for %p %s", sockid, sockid->asString().c_str());</font> +00517 <font class="comment"></font> +00518 <font class="comment"> sockid->setConnectedState( false );</font> +00519 <font class="comment"></font> +00520 <font class="comment"> // Call callback if needed</font> +00521 <font class="comment"> if ( disconnectionCallback() != NULL )</font> +00522 <font class="comment"> {</font> +00523 <font class="comment"> disconnectionCallback()( sockid, argOfDisconnectionCallback() );</font> +00524 <font class="comment"> }</font> +00525 <font class="comment"></font> +00526 <font class="comment"> // Add socket object into the synchronized remove list</font> +00527 <font class="comment"> nldebug( "LNETL1: Adding the connection to the remove list" );</font> +00528 <font class="comment"> nlassert( ((CServerBufSock*)sockid)->ownerTask() != NULL );</font> +00529 <font class="comment"> ((CServerBufSock*)sockid)->ownerTask()->addToRemoveSet( sockid );</font> +00530 <font class="comment"> break;</font> +00531 <font class="comment"> }</font> +00532 <font class="comment"> // Process connection event</font> +00533 <font class="comment"> case CBufNetBase::Connection:</font> +00534 <font class="comment"> {</font> +00535 <font class="comment"> vector<uint8> buffer;</font> +00536 <font class="comment"> recvfifo.value().front( buffer );</font> +00537 <font class="comment"></font> +00538 <font class="comment"> TSockId sockid = *((TSockId*)(&*buffer.begin()));</font> +00539 <font class="comment"> nldebug( "LNETL1: Connection event for %p %s", sockid, sockid->asString().c_str());</font> +00540 <font class="comment"></font> +00541 <font class="comment"> sockid->setConnectedState( true );</font> +00542 <font class="comment"> </font> +00543 <font class="comment"> // Call callback if needed</font> +00544 <font class="comment"> if ( connectionCallback() != NULL )</font> +00545 <font class="comment"> {</font> +00546 <font class="comment"> connectionCallback()( sockid, argOfConnectionCallback() );</font> +00547 <font class="comment"> }</font> +00548 <font class="comment"> break;</font> +00549 <font class="comment"> }</font> +00550 <font class="comment"> default:</font> +00551 <font class="comment"> vector<uint8> buffer;</font> +00552 <font class="comment"> recvfifo.value().front( buffer );</font> +00553 <font class="comment"></font> +00554 <font class="comment"> nlinfo( "LNETL1: Invalid block type: %hu (should be = to %hu", (uint16)(buffer[buffer.size()-1]), (uint16)(val) );</font> +00555 <font class="comment"> nlinfo( "LNETL1: Buffer (%d B): [%s]", buffer.size(), stringFromVector(buffer).c_str() );</font> +00556 <font class="comment"> nlinfo( "LNETL1: Receive queue:" );</font> +00557 <font class="comment"> recvfifo.value().display();</font> +00558 <font class="comment"> nlerror( "LNETL1: Invalid system event type in server receive queue" );</font> +00559 <font class="comment"></font> +00560 <font class="comment"> }</font> +00561 <font class="comment"></font> +00562 <font class="comment"> // Extract system event</font> +00563 <font class="comment"> recvfifo.value().pop();</font> +00564 <font class="comment"> }</font> +00565 <font class="comment"> }</font> +00566 <font class="comment"> while ( true );</font> +00567 <font class="comment"> }</font> +00568 <font class="comment">}</font> +00569 <font class="comment">*/</font> +00570 +00571 <font class="comment">/*</font> +00572 <font class="comment"> * Receives next block of data in the specified. The length and hostid are output arguments.</font> +00573 <font class="comment"> * Precond: dataAvailable() has returned true, phostid not null</font> +00574 <font class="comment"> */</font> +<a name="l00575"></a><a class="code" href="classNLNET_1_1CBufServer.html#a7">00575</a> <font class="keywordtype">void</font> CBufServer::receive( CMemStream& buffer, <a class="code" href="namespaceNLNET.html#a0">TSockId</a>* phostid ) +00576 { +00577 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"CBufServer::receive"</font> ); +00578 <font class="comment">//nlassert( dataAvailable() );</font> +00579 <a class="code" href="debug_8h.html#a6">nlassert</a>( phostid != NULL ); +00580 { +00581 <a class="code" href="namespaceNLNET.html#a5">CFifoAccessor</a> recvfifo( &<a class="code" href="classNLNET_1_1CBufNetBase.html#b1">receiveQueue</a>() ); +00582 <a class="code" href="debug_8h.html#a6">nlassert</a>( ! recvfifo.value().empty() ); +00583 recvfifo.value().front( buffer ); +00584 recvfifo.value().pop(); +00585 <a class="code" href="classNLNET_1_1CBufNetBase.html#b6">setDataAvailableFlag</a>( ! recvfifo.value().empty() ); +00586 } +00587 +00588 <font class="comment">// Extract hostid (and event type)</font> +00589 *phostid = *((<a class="code" href="namespaceNLNET.html#a0">TSockId</a>*)&(buffer.buffer()[buffer.length()-<font class="keyword">sizeof</font>(TSockId)-1])); +00590 <a class="code" href="debug_8h.html#a6">nlassert</a>( buffer.buffer()[buffer.length()-1] == CBufNetBase::User ); +00591 +00592 <font class="comment">// debug features, we number all packet to be sure that they are all sent and received</font> +00593 <font class="comment">// \todo remove this debug feature when ok</font> +00594 <font class="preprocessor">#ifdef NL_BIG_ENDIAN</font> +00595 <font class="preprocessor"></font> uint32 val = <a class="code" href="stream_8h.html#a1">NLMISC_BSWAP32</a>(*(uint32*)buffer.buffer()); +00596 <font class="preprocessor">#else</font> +00597 <font class="preprocessor"></font> uint32 val = *(uint32*)buffer.buffer(); +00598 <font class="preprocessor">#endif</font> +00599 <font class="preprocessor"></font> +00600 <font class="comment">// nldebug ("receive message number %u", val);</font> +00601 <font class="keywordflow">if</font> ((*phostid)->ReceiveNextValue != val) +00602 { +00603 <a class="code" href="debug_8h.html#a2">nlwarning</a> ((<font class="stringliteral">"LNETL1: !!!LOST A MESSAGE!!! I received the message number %u but I'm waiting the message number %u (cnx %s), warn lecroart@nevrax.com with the log now please"</font>, val, (*phostid)->ReceiveNextValue, (*phostid)->asString().c_str())); +00604 <font class="comment">// resync the message number</font> +00605 (*phostid)->ReceiveNextValue = val; +00606 } +00607 +00608 (*phostid)->ReceiveNextValue++; +00609 +00610 buffer.resize( buffer.length()-<font class="keyword">sizeof</font>(TSockId)-1 ); +00611 +00612 <font class="comment">// TODO OPTIM remove the nldebug for speed</font> +00613 <font class="comment">//commented for optimisation nldebug( "LNETL1: Read buffer (%d+%d B) from %s", buffer.length(), sizeof(TSockId)+1, /*stringFromVector(buffer).c_str(), */(*phostid)->asString().c_str() );</font> +00614 +00615 <font class="comment">// Statistics</font> +00616 <a class="code" href="classNLNET_1_1CBufServer.html#o10">_BytesPoppedIn</a> += buffer.length() + <font class="keyword">sizeof</font>(TBlockSize); +00617 } +00618 +00619 +00620 <font class="comment">/*</font> +00621 <font class="comment"> * Update the network (call this method evenly)</font> +00622 <font class="comment"> */</font> +<a name="l00623"></a><a class="code" href="classNLNET_1_1CBufServer.html#a8">00623</a> <font class="keywordtype">void</font> CBufServer::update() +00624 { +00625 <font class="comment">//nlnettrace( "CBufServer::update-BEGIN" );</font> +00626 +00627 <a class="code" href="classNLNET_1_1CBufServer.html#o13">_NbConnections</a> = 0; +00628 +00629 <font class="comment">// For each thread</font> +00630 CThreadPool::iterator ipt; +00631 { +00632 <font class="comment">//nldebug( "UPD: Acquiring the Thread Pool" );</font> +00633 CSynchronized<CThreadPool>::CAccessor poolsync( &<a class="code" href="classNLNET_1_1CBufServer.html#o6">_ThreadPool</a> ); +00634 <font class="comment">//nldebug( "UPD: Acquired." );</font> +00635 <font class="keywordflow">for</font> ( ipt=poolsync.value().begin(); ipt!=poolsync.value().end(); ++ipt ) +00636 { +00637 <font class="comment">// For each thread of the pool</font> +00638 <a class="code" href="classNLNET_1_1CBufServer.html#l2">CServerReceiveTask</a> *task = <a class="code" href="classNLNET_1_1CBufServer.html#b2">receiveTask</a>(ipt); +00639 CConnections::iterator ipb; +00640 { +00641 CSynchronized<CConnections>::CAccessor connectionssync( &task->_Connections ); +00642 <font class="keywordflow">for</font> ( ipb=connectionssync.value().begin(); ipb!=connectionssync.value().end(); ++ipb ) +00643 { +00644 <font class="comment">// For each socket of the thread, update sending</font> +00645 <font class="keywordflow">if</font> ( ! ((*ipb)->Sock->connected() && (*ipb)->update()) ) +00646 { +00647 <font class="comment">// Update did not work or the socket is not connected anymore</font> +00648 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: Socket %s is disconnected"</font>, (*ipb)->asString().c_str() ); +00649 <font class="comment">// Disconnection event if disconnected (known either from flush (in update) or when receiving data)</font> +00650 (*ipb)->advertiseDisconnection( <font class="keyword">this</font>, *ipb ); +00651 +00652 <font class="comment">/*if ( (*ipb)->advertiseDisconnection( this, *ipb ) )</font> +00653 <font class="comment"> {</font> +00654 <font class="comment"> // Now the connection removal is in dataAvailable()</font> +00655 <font class="comment"> // POLL6</font> +00656 <font class="comment"> }*/</font> +00657 } +00658 <font class="keywordflow">else</font> +00659 { +00660 <a class="code" href="classNLNET_1_1CBufServer.html#o13">_NbConnections</a>++; +00661 } +00662 } +00663 } +00664 } +00665 } +00666 +00667 <font class="comment">//nlnettrace( "CBufServer::update-END" );</font> +00668 } +00669 +<a name="l00670"></a><a class="code" href="classNLNET_1_1CBufServer.html#a9">00670</a> uint32 CBufServer::getSendQueueSize( <a class="code" href="namespaceNLNET.html#a0">TSockId</a> destid ) +00671 { +00672 <font class="keywordflow">if</font> ( destid != InvalidSockId ) +00673 { +00674 <font class="keywordflow">return</font> destid->SendFifo.size(); +00675 } +00676 <font class="keywordflow">else</font> +00677 { +00678 <font class="comment">// add all client buffers</font> +00679 +00680 uint32 total = 0; +00681 +00682 <font class="comment">// For each thread</font> +00683 CThreadPool::iterator ipt; +00684 { +00685 CSynchronized<CThreadPool>::CAccessor poolsync( &<a class="code" href="classNLNET_1_1CBufServer.html#o6">_ThreadPool</a> ); +00686 <font class="keywordflow">for</font> ( ipt=poolsync.value().begin(); ipt!=poolsync.value().end(); ++ipt ) +00687 { +00688 <font class="comment">// For each thread of the pool</font> +00689 <a class="code" href="classNLNET_1_1CBufServer.html#l2">CServerReceiveTask</a> *task = <a class="code" href="classNLNET_1_1CBufServer.html#b2">receiveTask</a>(ipt); +00690 CConnections::iterator ipb; +00691 { +00692 CSynchronized<CConnections>::CAccessor connectionssync( &task->_Connections ); +00693 <font class="keywordflow">for</font> ( ipb=connectionssync.value().begin(); ipb!=connectionssync.value().end(); ++ipb ) +00694 { +00695 <font class="comment">// For each socket of the thread, update sending</font> +00696 total = (*ipb)->SendFifo.size (); +00697 } +00698 } +00699 } +00700 } +00701 <font class="keywordflow">return</font> total; +00702 } +00703 } +00704 +00705 +00706 <font class="comment">/*</font> +00707 <font class="comment"> * Returns the number of bytes received since the previous call to this method</font> +00708 <font class="comment"> */</font> +<a name="l00709"></a><a class="code" href="classNLNET_1_1CBufServer.html#a16">00709</a> uint64 CBufServer::newBytesReceived() +00710 { +00711 uint64 b = <a class="code" href="classNLNET_1_1CBufServer.html#a15">bytesReceived</a>(); +00712 uint64 nbrecvd = b - <a class="code" href="classNLNET_1_1CBufServer.html#o11">_PrevBytesPoppedIn</a>; +00713 <font class="comment">//nlinfo( "b: %"NL_I64"u new: %"NL_I64"u", b, nbrecvd );</font> +00714 <a class="code" href="classNLNET_1_1CBufServer.html#o11">_PrevBytesPoppedIn</a> = b; +00715 <font class="keywordflow">return</font> nbrecvd; +00716 } +00717 +00718 <font class="comment">/*</font> +00719 <font class="comment"> * Returns the number of bytes sent since the previous call to this method</font> +00720 <font class="comment"> */</font> +<a name="l00721"></a><a class="code" href="classNLNET_1_1CBufServer.html#a18">00721</a> uint64 CBufServer::newBytesSent() +00722 { +00723 uint64 b = <a class="code" href="classNLNET_1_1CBufServer.html#a17">bytesSent</a>(); +00724 uint64 nbsent = b - <a class="code" href="classNLNET_1_1CBufServer.html#o12">_PrevBytesPushedOut</a>; +00725 <font class="comment">//nlinfo( "b: %"NL_I64"u new: %"NL_I64"u", b, nbsent );</font> +00726 <a class="code" href="classNLNET_1_1CBufServer.html#o12">_PrevBytesPushedOut</a> = b; +00727 <font class="keywordflow">return</font> nbsent; +00728 } +00729 +00730 +00731 <font class="comment">/***************************************************************************************************</font> +00732 <font class="comment"> * Listen thread</font> +00733 <font class="comment"> **************************************************************************************************/</font> +00734 +00735 +00736 <font class="comment">/*</font> +00737 <font class="comment"> * Code of listening thread</font> +00738 <font class="comment"> */</font> +<a name="l00739"></a><a class="code" href="classNLNET_1_1CListenTask.html#a2">00739</a> <font class="keywordtype">void</font> CListenTask::run() +00740 { +00741 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"CListenTask::run"</font> ); +00742 +00743 <font class="preprocessor">#ifdef NL_OS_UNIX</font> +00744 <font class="preprocessor"></font> SOCKET descmax; +00745 fd_set readers; +00746 timeval tv; +00747 descmax = <a class="code" href="classNLNET_1_1CListenTask.html#o1">_ListenSock</a>.descriptor()>_WakeUpPipeHandle[PipeRead]?<a class="code" href="classNLNET_1_1CListenTask.html#o1">_ListenSock</a>.descriptor():_WakeUpPipeHandle[PipeRead]; +00748 <font class="preprocessor">#endif</font> +00749 <font class="preprocessor"></font> +00750 <font class="comment">// Accept connections</font> +00751 <font class="keywordflow">while</font> ( ! <a class="code" href="classNLNET_1_1CServerTask.html#b1">exitRequired</a>() ) +00752 { +00753 <font class="keywordflow">try</font> +00754 { +00755 <font class="comment">// Get and setup the new socket</font> +00756 <font class="preprocessor">#ifdef NL_OS_UNIX</font> +00757 <font class="preprocessor"></font> FD_ZERO( &readers ); +00758 FD_SET( <a class="code" href="classNLNET_1_1CListenTask.html#o1">_ListenSock</a>.descriptor(), &readers ); +00759 FD_SET( _WakeUpPipeHandle[PipeRead], &readers ); +00760 tv.tv_sec = 60; +00761 tv.tv_usec = 0; +00762 <font class="keywordtype">int</font> <a class="code" href="driver__opengl__extension__def_8h.html#a400">res</a> = ::select( descmax+1, &readers, NULL, NULL, &tv ); +00763 +00764 <font class="keywordflow">switch</font> ( res ) +00765 { +00766 <font class="keywordflow">case</font> 0 : <font class="keywordflow">continue</font>; <font class="comment">// time-out expired, no results</font> +00767 <font class="keywordflow">case</font> -1 : +00768 <font class="comment">// we'll ignore message (Interrupted system call) caused by a CTRL-C</font> +00769 <font class="keywordflow">if</font> (CSock::getLastError() == 4) +00770 { +00771 <a class="code" href="debug_8h.html#a0">nldebug</a> (<font class="stringliteral">"LNETL1: Select failed (in listen thread): %s (code %u) but IGNORED"</font>, CSock::errorString( CSock::getLastError() ).c_str(), CSock::getLastError()); +00772 <font class="keywordflow">continue</font>; +00773 } +00774 <a class="code" href="debug_8h.html#a3">nlerror</a>( <font class="stringliteral">"LNETL1: Select failed (in listen thread): %s (code %u)"</font>, CSock::errorString( CSock::getLastError() ).c_str(), CSock::getLastError() ); +00775 } +00776 +00777 <font class="keywordflow">if</font> ( FD_ISSET( _WakeUpPipeHandle[PipeRead], &readers ) ) +00778 { +00779 uint8 b; +00780 <font class="keywordflow">if</font> ( read( _WakeUpPipeHandle[PipeRead], &b, 1 ) == -1 ) <font class="comment">// we were woken-up by the wake-up pipe</font> +00781 { +00782 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: In CListenTask::run(): read() failed"</font> ); +00783 } +00784 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: listen thread select woken-up"</font> ); +00785 <font class="keywordflow">continue</font>; +00786 } +00787 <font class="preprocessor">#endif</font> +00788 <font class="preprocessor"></font> <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: Waiting incoming connection..."</font> ); +00789 CServerBufSock *bufsock = <font class="keyword">new</font> CServerBufSock( <a class="code" href="classNLNET_1_1CListenTask.html#o1">_ListenSock</a>.accept() ); +00790 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"New connection : %s"</font>, bufsock->asString().c_str() ); +00791 bufsock->Sock->setNonBlockingMode( <font class="keyword">true</font> ); +00792 <font class="keywordflow">if</font> ( <a class="code" href="classNLNET_1_1CListenTask.html#o0">_Server</a>->noDelay() ) +00793 { +00794 bufsock->Sock->setNoDelay( <font class="keyword">true</font> ); +00795 } +00796 +00797 <font class="comment">// Notify the new connection</font> +00798 bufsock->advertiseConnection( <a class="code" href="classNLNET_1_1CListenTask.html#o0">_Server</a> ); +00799 +00800 <font class="comment">// Dispatch the socket into the thread pool</font> +00801 <a class="code" href="classNLNET_1_1CListenTask.html#o0">_Server</a>->dispatchNewSocket( bufsock ); +00802 } +00803 <font class="keywordflow">catch</font> ( ESocket& e ) +00804 { +00805 <a class="code" href="debug_8h.html#a1">nlinfo</a>( <font class="stringliteral">"Exception in listen thread: %s"</font>, e.what() ); <font class="comment">// It can occur in normal behavior (e.g. when exiting)</font> +00806 <font class="comment">// It can also occur when too many sockets are open (e.g. 885 connections)</font> +00807 } +00808 } +00809 +00810 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"Exiting CListenTask::run"</font> ); +00811 } +00812 +00813 +00814 <font class="comment">/*</font> +00815 <font class="comment"> * Binds a new socket and send buffer to an existing or a new thread</font> +00816 <font class="comment"> * Note: this method is called in the listening thread.</font> +00817 <font class="comment"> */</font> +<a name="l00818"></a><a class="code" href="classNLNET_1_1CBufServer.html#b1">00818</a> <font class="keywordtype">void</font> CBufServer::dispatchNewSocket( CServerBufSock *bufsock ) +00819 { +00820 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"CBufServer::dispatchNewSocket"</font> ); +00821 +00822 CSynchronized<CThreadPool>::CAccessor poolsync( &<a class="code" href="classNLNET_1_1CBufServer.html#o6">_ThreadPool</a> ); +00823 <font class="keywordflow">if</font> ( <a class="code" href="classNLNET_1_1CBufServer.html#o1">_ThreadStrategy</a> == <a class="code" href="classNLNET_1_1CBufServer.html#s2s0">SpreadSockets</a> ) +00824 { +00825 <font class="comment">// Find the thread with the smallest number of connections and check if all</font> +00826 <font class="comment">// threads do not have the same number of connections</font> +00827 uint <a class="code" href="bit__set_8cpp.html#a0">min</a> = 0xFFFFFFFF; +00828 uint max = 0; +00829 CThreadPool::iterator ipt, iptmin, iptmax; +00830 <font class="keywordflow">for</font> ( iptmin=iptmax=ipt=poolsync.value().begin(); ipt!=poolsync.value().end(); ++ipt ) +00831 { +00832 uint noc = <a class="code" href="classNLNET_1_1CBufServer.html#b2">receiveTask</a>(ipt)->numberOfConnections(); +00833 <font class="keywordflow">if</font> ( noc < <a class="code" href="bit__set_8cpp.html#a0">min</a> ) +00834 { +00835 <a class="code" href="bit__set_8cpp.html#a0">min</a> = noc; +00836 iptmin = ipt; +00837 } +00838 <font class="keywordflow">if</font> ( noc > max ) +00839 { +00840 max = noc; +00841 iptmax = ipt; +00842 } +00843 } +00844 +00845 <font class="comment">// Check if we make the pool of threads grow (if we have not found vacant room</font> +00846 <font class="comment">// and if it is allowed to)</font> +00847 <font class="keywordflow">if</font> ( (poolsync.value().empty()) || +00848 ((<a class="code" href="bit__set_8cpp.html#a0">min</a> == max) && (poolsync.value().size() < <a class="code" href="classNLNET_1_1CBufServer.html#o2">_MaxThreads</a>)) ) +00849 { +00850 <a class="code" href="classNLNET_1_1CBufServer.html#b4">addNewThread</a>( poolsync.value(), bufsock ); +00851 } +00852 <font class="keywordflow">else</font> +00853 { +00854 <font class="comment">// Dispatch socket to an existing thread of the pool</font> +00855 <a class="code" href="classNLNET_1_1CBufServer.html#l2">CServerReceiveTask</a> *task = <a class="code" href="classNLNET_1_1CBufServer.html#b2">receiveTask</a>(iptmin); +00856 bufsock->setOwnerTask( task ); +00857 task->addNewSocket( bufsock ); +00858 <font class="preprocessor">#ifdef NL_OS_UNIX</font> +00859 <font class="preprocessor"></font> task->wakeUp(); +00860 <font class="preprocessor">#endif </font> +00861 <font class="preprocessor"></font> +00862 <font class="keywordflow">if</font> ( <a class="code" href="bit__set_8cpp.html#a0">min</a> >= (uint)<a class="code" href="classNLNET_1_1CBufServer.html#o3">_MaxSocketsPerThread</a> ) +00863 { +00864 <a class="code" href="debug_8h.html#a2">nlwarning</a>( <font class="stringliteral">"LNETL1: Exceeding the maximum number of sockets per thread"</font> ); +00865 } +00866 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: New socket dispatched to thread %d"</font>, iptmin-poolsync.value().begin() ); +00867 } +00868 +00869 } +00870 <font class="keywordflow">else</font> <font class="comment">// _ThreadStrategy == FillThreads</font> +00871 { +00872 CThreadPool::iterator ipt; +00873 <font class="keywordflow">for</font> ( ipt=poolsync.value().begin(); ipt!=poolsync.value().end(); ++ipt ) +00874 { +00875 uint noc = <a class="code" href="classNLNET_1_1CBufServer.html#b2">receiveTask</a>(ipt)->numberOfConnections(); +00876 <font class="keywordflow">if</font> ( noc < <a class="code" href="classNLNET_1_1CBufServer.html#o3">_MaxSocketsPerThread</a> ) +00877 { +00878 <font class="keywordflow">break</font>; +00879 } +00880 } +00881 +00882 <font class="comment">// Check if we have to make the thread pool grow (if we have not found vacant room)</font> +00883 <font class="keywordflow">if</font> ( ipt == poolsync.value().end() ) +00884 { +00885 <font class="keywordflow">if</font> ( poolsync.value().size() == <a class="code" href="classNLNET_1_1CBufServer.html#o2">_MaxThreads</a> ) +00886 { +00887 <a class="code" href="debug_8h.html#a2">nlwarning</a>( <font class="stringliteral">"LNETL1: Exceeding the maximum number of threads"</font> ); +00888 } +00889 <a class="code" href="classNLNET_1_1CBufServer.html#b4">addNewThread</a>( poolsync.value(), bufsock ); +00890 } +00891 <font class="keywordflow">else</font> +00892 { +00893 <font class="comment">// Dispatch socket to an existing thread of the pool</font> +00894 <a class="code" href="classNLNET_1_1CBufServer.html#l2">CServerReceiveTask</a> *task = <a class="code" href="classNLNET_1_1CBufServer.html#b2">receiveTask</a>(ipt); +00895 bufsock->setOwnerTask( task ); +00896 task->addNewSocket( bufsock ); +00897 <font class="preprocessor">#ifdef NL_OS_UNIX</font> +00898 <font class="preprocessor"></font> task->wakeUp(); +00899 <font class="preprocessor">#endif </font> +00900 <font class="preprocessor"></font> <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: New socket dispatched to thread %d"</font>, ipt-poolsync.value().begin() ); +00901 } +00902 } +00903 } +00904 +00905 +00906 <font class="comment">/*</font> +00907 <font class="comment"> * Creates a new task and run a new thread for it</font> +00908 <font class="comment"> * Precond: bufsock not null</font> +00909 <font class="comment"> */</font> +<a name="l00910"></a><a class="code" href="classNLNET_1_1CBufServer.html#b4">00910</a> <font class="keywordtype">void</font> CBufServer::addNewThread( <a class="code" href="namespaceNLNET.html#a7">CThreadPool</a>& threadpool, CServerBufSock *bufsock ) +00911 { +00912 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"CBufServer::addNewThread"</font> ); +00913 <a class="code" href="debug_8h.html#a6">nlassert</a>( bufsock != NULL ); +00914 +00915 <font class="comment">// Create new task and dispatch the socket to it</font> +00916 <a class="code" href="classNLNET_1_1CBufServer.html#l2">CServerReceiveTask</a> *task = <font class="keyword">new</font> <a class="code" href="classNLNET_1_1CBufServer.html#l2">CServerReceiveTask</a>( <font class="keyword">this</font> ); +00917 bufsock->setOwnerTask( task ); +00918 task->addNewSocket( bufsock ); +00919 +00920 <font class="comment">// Add a new thread to the pool, with this task</font> +00921 IThread *thr = IThread::create( task ); +00922 { +00923 threadpool.push_back( thr ); +00924 thr->start(); +00925 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: Added a new thread; pool size is %d"</font>, threadpool.size() ); +00926 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: New socket dispatched to thread %d"</font>, threadpool.size()-1 ); +00927 } +00928 } +00929 +00930 +00931 <font class="comment">/***************************************************************************************************</font> +00932 <font class="comment"> * Receive threads</font> +00933 <font class="comment"> **************************************************************************************************/</font> +00934 +00935 +00936 <font class="comment">/*</font> +00937 <font class="comment"> * Code of receiving threads for servers</font> +00938 <font class="comment"> */</font> +<a name="l00939"></a><a class="code" href="classNLNET_1_1CServerReceiveTask.html#a1">00939</a> <font class="keywordtype">void</font> CServerReceiveTask::run() +00940 { +00941 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"CServerReceiveTask::run"</font> ); +00942 +00943 SOCKET descmax; +00944 fd_set readers; +00945 +00946 <font class="comment">// Time-out value for select (it can be long because we do not do any thing else in this thread)</font> +00947 timeval tv; +00948 <font class="preprocessor">#if defined NL_OS_UNIX</font> +00949 <font class="preprocessor"></font> <font class="comment">// POLL7</font> +00950 nice( 2 ); +00951 <font class="preprocessor">#endif // NL_OS_UNIX</font> +00952 <font class="preprocessor"></font> +00953 <font class="comment">// Copy of _Connections</font> +00954 vector<TSockId> connections_copy; +00955 +00956 <font class="keywordflow">while</font> ( ! <a class="code" href="classNLNET_1_1CServerTask.html#b1">exitRequired</a>() ) +00957 { +00958 <font class="comment">// 1. Remove closed connections</font> +00959 <a class="code" href="classNLNET_1_1CServerReceiveTask.html#a5">clearClosedConnections</a>(); +00960 +00961 <font class="comment">// POLL8</font> +00962 +00963 <font class="comment">// 2-SELECT-VERSION : select() on the sockets handled in the present thread</font> +00964 +00965 descmax = 0; +00966 FD_ZERO( &readers ); +00967 <font class="keywordtype">bool</font> skip; +00968 <font class="keywordtype">bool</font> alldisconnected = <font class="keyword">true</font>; +00969 CConnections::iterator ipb; +00970 { +00971 <font class="comment">// Lock _Connections</font> +00972 CSynchronized<CConnections>::CAccessor connectionssync( &<a class="code" href="classNLNET_1_1CServerReceiveTask.html#o1">_Connections</a> ); +00973 +00974 <font class="comment">// Prepare to avoid select if there is no connection</font> +00975 skip = connectionssync.value().empty(); +00976 +00977 <font class="comment">// Fill the select array and copy _Connections</font> +00978 connections_copy.clear(); +00979 <font class="keywordflow">for</font> ( ipb=connectionssync.value().begin(); ipb!=connectionssync.value().end(); ++ipb ) +00980 { +00981 <font class="keywordflow">if</font> ( (*ipb)->Sock->connected() ) <font class="comment">// exclude disconnected sockets that are not deleted</font> +00982 { +00983 alldisconnected = <font class="keyword">false</font>; +00984 <font class="comment">// Copy _Connections element</font> +00985 connections_copy.push_back( *ipb ); +00986 +00987 <font class="comment">// Add socket descriptor to the select array</font> +00988 FD_SET( (*ipb)->Sock->descriptor(), &readers ); +00989 +00990 <font class="comment">// Calculate descmax for select</font> +00991 <font class="keywordflow">if</font> ( (*ipb)->Sock->descriptor() > descmax ) +00992 { +00993 descmax = (*ipb)->Sock->descriptor(); +00994 } +00995 } +00996 } +00997 +00998 <font class="preprocessor">#ifdef NL_OS_UNIX</font> +00999 <font class="preprocessor"></font> <font class="comment">// Add the wake-up pipe into the select array</font> +01000 FD_SET( _WakeUpPipeHandle[PipeRead], &readers ); +01001 <font class="keywordflow">if</font> ( _WakeUpPipeHandle[PipeRead]>descmax ) +01002 { +01003 descmax = _WakeUpPipeHandle[PipeRead]; +01004 } +01005 <font class="preprocessor">#endif</font> +01006 <font class="preprocessor"></font> +01007 <font class="comment">// Unlock _Connections, use connections_copy instead</font> +01008 } +01009 +01010 <font class="preprocessor">#ifndef NL_OS_UNIX</font> +01011 <font class="preprocessor"></font> <font class="comment">// Avoid select if there is no connection (Windows only)</font> +01012 <font class="keywordflow">if</font> ( skip || alldisconnected ) +01013 { +01014 <a class="code" href="namespaceNLMISC.html#a236">nlSleep</a>( 1 ); <font class="comment">// nice</font> +01015 <font class="keywordflow">continue</font>; +01016 } +01017 <font class="preprocessor">#endif</font> +01018 <font class="preprocessor"></font> +01019 <font class="preprocessor">#ifdef NL_OS_WINDOWS</font> +01020 <font class="preprocessor"></font> tv.tv_sec = 0; <font class="comment">// short time because the newly added connections can't be added to the select fd_set</font> +01021 tv.tv_usec = 10000; <font class="comment">// NEW: set to 500ms because otherwise new connections handling are too slow</font> +01022 <font class="preprocessor">#elif defined NL_OS_UNIX</font> +01023 <font class="preprocessor"></font> <font class="comment">// POLL7</font> +01024 tv.tv_sec = 3600; <font class="comment">// 1 hour (=> 1 select every 3.6 second for 1000 connections)</font> +01025 tv.tv_usec = 0; +01026 <font class="preprocessor">#endif // NL_OS_WINDOWS</font> +01027 <font class="preprocessor"></font> +01028 <font class="comment">// Call select</font> +01029 <font class="keywordtype">int</font> <a class="code" href="driver__opengl__extension__def_8h.html#a400">res</a> = ::select( descmax+1, &readers, NULL, NULL, &tv ); +01030 +01031 <font class="comment">// POLL9</font> +01032 +01033 <font class="comment">// 3. Test the result</font> +01034 <font class="keywordflow">switch</font> ( res ) +01035 { +01036 <font class="keywordflow">case</font> 0 : <font class="keywordflow">continue</font>; <font class="comment">// time-out expired, no results</font> +01037 +01039 <font class="keywordflow">case</font> -1 : +01040 <font class="comment">// we'll ignore message (Interrupted system call) caused by a CTRL-C</font> +01041 <font class="comment">/*if (CSock::getLastError() == 4)</font> +01042 <font class="comment"> {</font> +01043 <font class="comment"> nldebug ("LNETL1: Select failed (in receive thread): %s (code %u) but IGNORED", CSock::errorString( CSock::getLastError() ).c_str(), CSock::getLastError());</font> +01044 <font class="comment"> continue;</font> +01045 <font class="comment"> }*/</font> +01046 <font class="comment">//nlerror( "LNETL1: Select failed (in receive thread): %s (code %u)", CSock::errorString( CSock::getLastError() ).c_str(), CSock::getLastError() );</font> +01047 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: Select failed (in receive thread): %s (code %u)"</font>, CSock::errorString( CSock::getLastError() ).c_str(), CSock::getLastError() ); +01048 <font class="keywordflow">return</font>; +01049 } +01050 +01051 <font class="comment">// 4. Get results</font> +01052 +01053 vector<TSockId>::iterator ic; +01054 <font class="keywordflow">for</font> ( ic=connections_copy.begin(); ic!=connections_copy.end(); ++ic ) +01055 { +01056 <font class="keywordflow">if</font> ( FD_ISSET( (*ic)->Sock->descriptor(), &readers ) != 0 ) +01057 { +01058 CServerBufSock *serverbufsock = static_cast<CServerBufSock*>(static_cast<CBufSock*>(*ic)); +01059 <font class="keywordflow">try</font> +01060 { +01061 <font class="comment">// 4. Receive data</font> +01062 <font class="keywordflow">if</font> ( serverbufsock->receivePart() ) +01063 { +01064 <font class="comment">// Copy sockid</font> +01065 vector<uint8> hidvec; +01066 hidvec.resize( <font class="keyword">sizeof</font>(<a class="code" href="namespaceNLNET.html#a0">TSockId</a>)+1 ); +01067 memcpy( &*hidvec.begin(), &(*ic), <font class="keyword">sizeof</font>(TSockId) ); +01068 +01069 <font class="comment">// Add event type to hidvec</font> +01070 hidvec[<font class="keyword">sizeof</font>(TSockId)] = (uint8)CBufNetBase::User; +01071 +01072 <font class="comment">// Push message into receive queue</font> +01073 <font class="comment">//uint32 bufsize;</font> +01074 <font class="comment">//sint32 mbsize;</font> +01075 { +01076 <font class="comment">//nldebug( "RCV: Acquiring the receive queue... ");</font> +01077 <a class="code" href="namespaceNLNET.html#a5">CFifoAccessor</a> recvfifo( &<a class="code" href="classNLNET_1_1CServerReceiveTask.html#o0">_Server</a>->receiveQueue() ); +01078 <font class="comment">//nldebug( "RCV: Acquired, pushing the received buffer... ");</font> +01079 recvfifo.value().push( serverbufsock->receivedBuffer(), hidvec ); +01080 <a class="code" href="classNLNET_1_1CServerReceiveTask.html#o0">_Server</a>->setDataAvailableFlag( <font class="keyword">true</font> ); +01081 <font class="comment">//nldebug( "RCV: Pushed, releasing the receive queue..." );</font> +01082 <font class="comment">//recvfifo.value().display();</font> +01083 <font class="comment">//bufsize = serverbufsock->receivedBuffer().size();</font> +01084 <font class="comment">//mbsize = recvfifo.value().size() / 1048576;</font> +01085 } +01086 <font class="comment">//nldebug( "RCV: Released." );</font> +01087 <font class="comment">/*if ( mbsize > 1 )</font> +01088 <font class="comment"> {</font> +01089 <font class="comment"> nlwarning( "The receive queue size exceeds %d MB", mbsize );</font> +01090 <font class="comment"> }*/</font> +01091 <font class="comment">/*</font> +01092 <font class="comment"> // Statistics</font> +01093 <font class="comment"> {</font> +01094 <font class="comment"> CSynchronized<uint32>::CAccessor syncbpi ( &_Server->syncBytesPushedIn() );</font> +01095 <font class="comment"> syncbpi.value() += bufsize;</font> +01096 <font class="comment"> }</font> +01097 <font class="comment"> */</font> +01098 } +01099 } +01100 <font class="keywordflow">catch</font> ( ESocketConnectionClosed& ) +01101 { +01102 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: Connection %s closed"</font>, serverbufsock->asString().c_str() ); +01103 <font class="comment">// The socket went to _Connected=false when throwing the exception</font> +01104 } +01105 <font class="keywordflow">catch</font> ( ESocket& ) +01106 { +01107 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: Connection %s broken"</font>, serverbufsock->asString().c_str() ); +01108 (*ic)->Sock->disconnect(); +01109 } +01110 <font class="comment">/*</font> +01111 <font class="comment">#ifdef NL_OS_UNIX</font> +01112 <font class="comment"> skip = true; // don't check _WakeUpPipeHandle (yes, check it to read any written byte)</font> +01113 <font class="comment">#endif</font> +01114 <font class="comment"></font> +01115 <font class="comment">*/</font> +01116 } +01117 +01118 } +01119 +01120 <font class="preprocessor">#ifdef NL_OS_UNIX</font> +01121 <font class="preprocessor"></font> <font class="comment">// Test wake-up pipe</font> +01122 <font class="keywordflow">if</font> ( (!skip) && (FD_ISSET( _WakeUpPipeHandle[PipeRead], &readers )) ) +01123 { +01124 uint8 b; +01125 <font class="keywordflow">if</font> ( read( _WakeUpPipeHandle[PipeRead], &b, 1 ) == -1 ) <font class="comment">// we were woken-up by the wake-up pipe</font> +01126 { +01127 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: In CServerReceiveTask::run(): read() failed"</font> ); +01128 } +01129 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: Receive thread select woken-up"</font> ); +01130 } +01131 <font class="preprocessor">#endif</font> +01132 <font class="preprocessor"></font> +01133 } +01134 <a class="code" href="buf__sock_8h.html#a0">nlnettrace</a>( <font class="stringliteral">"Exiting CServerReceiveTask::run"</font> ); +01135 } +01136 +01137 +01138 <font class="comment">/*</font> +01139 <font class="comment"> * Delete all connections referenced in the remove list (double-mutexed)</font> +01140 <font class="comment"> */</font> +01141 +<a name="l01142"></a><a class="code" href="classNLNET_1_1CServerReceiveTask.html#a5">01142</a> <font class="keywordtype">void</font> CServerReceiveTask::clearClosedConnections() +01143 { +01144 CConnections::iterator ic; +01145 { +01146 NLMISC::CSynchronized<CConnections>::CAccessor removesetsync( &<a class="code" href="classNLNET_1_1CServerReceiveTask.html#o2">_RemoveSet</a> ); +01147 { +01148 <font class="keywordflow">if</font> ( ! removesetsync.value().empty() ) +01149 { +01150 <font class="comment">// Delete closed connections</font> +01151 NLMISC::CSynchronized<CConnections>::CAccessor connectionssync( &<a class="code" href="classNLNET_1_1CServerReceiveTask.html#o1">_Connections</a> ); +01152 <font class="keywordflow">for</font> ( ic=removesetsync.value().begin(); ic!=removesetsync.value().end(); ++ic ) +01153 { +01154 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: Removing a connection"</font> ); +01155 +01156 <a class="code" href="namespaceNLNET.html#a0">TSockId</a> sid = (*ic); +01157 +01158 <font class="comment">// Remove from the connection list</font> +01159 connectionssync.value().erase( *ic ); +01160 +01161 <font class="comment">// Delete the socket object</font> +01162 <font class="keyword">delete</font> sid; +01163 } +01164 <font class="comment">// Clear remove list</font> +01165 removesetsync.value().clear(); +01166 } +01167 } +01168 } +01169 } +01170 +01171 +01172 } <font class="comment">// NLNET</font> +</pre></div> + +<!-- footer --> +<BR><FONT Size=+5> </FONT> +</TD> +<TD WIDTH=15><IMG SRC=http://www.nevrax.org/inc/img/pixel.gif WIDTH=15 HEIGHT=15 BORDER=0 ALT=""></TD> +</TR> +</TABLE> +</BODY> +</HTML> |