aboutsummaryrefslogtreecommitdiff
path: root/docs/doxygen/nel/buf__server_8cpp-source.html
diff options
context:
space:
mode:
authorneodarz <neodarz@neodarz.net>2018-08-11 20:21:34 +0200
committerneodarz <neodarz@neodarz.net>2018-08-11 20:21:34 +0200
commit0ea5fc66924303d1bf73ba283a383e2aadee02f2 (patch)
tree2568e71a7ccc44ec23b8bb3f0ff97fb6bf2ed709 /docs/doxygen/nel/buf__server_8cpp-source.html
downloadnevrax-website-self-hostable-0ea5fc66924303d1bf73ba283a383e2aadee02f2.tar.xz
nevrax-website-self-hostable-0ea5fc66924303d1bf73ba283a383e2aadee02f2.zip
Initial commit
Diffstat (limited to 'docs/doxygen/nel/buf__server_8cpp-source.html')
-rw-r--r--docs/doxygen/nel/buf__server_8cpp-source.html1240
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>&nbsp;<A CLASS=uplinks HREF=http://www.nevrax.org><b>Home</B></FONT></A>&nbsp;&nbsp;&nbsp;</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>&nbsp;<A CLASS=uplinks HREF=http://www.nevrax.com><b>nevrax.com</B></FONT></A>&nbsp;&nbsp;&nbsp;</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>
+&nbsp;
+
+<!-- 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>&nbsp;</td>
+</tr></table>
+<!-- Generated by Doxygen 1.2.14 -->
+<center>
+<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="namespaces.html">Namespace List</a> &nbsp; <a class="qindex" href="hierarchy.html">Class Hierarchy</a> &nbsp; <a class="qindex" href="classes.html">Alphabetical List</a> &nbsp; <a class="qindex" href="annotated.html">Compound List</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="namespacemembers.html">Namespace Members</a> &nbsp; <a class="qindex" href="functions.html">Compound Members</a> &nbsp; <a class="qindex" href="globals.html">File Members</a> &nbsp; <a class="qindex" href="pages.html">Related Pages</a> &nbsp; <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> &nbsp; </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 &lt;winsock2.h&gt;</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 &lt;<a class="code" href="unistd_8h.html">unistd.h</a>&gt;</font>
+00038 <font class="preprocessor">#include &lt;sys/types.h&gt;</font>
+00039 <font class="preprocessor">#include &lt;sys/time.h&gt;</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&lt;uint32&gt;::CAccessor syncbpi ( &amp;_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>-&gt;init( port );
+00098 <a class="code" href="classNLNET_1_1CBufServer.html#o5">_ListenThread</a>-&gt;<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], &amp;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>-&gt;<a class="code" href="classNLMISC_1_1IThread.html#a4">getRunnable</a>()))-&gt;requireExit();
+00172 ((<a class="code" href="classNLNET_1_1CBufServer.html#l1">CListenTask</a>*)(<a class="code" href="classNLNET_1_1CBufServer.html#o5">_ListenThread</a>-&gt;<a class="code" href="classNLMISC_1_1IThread.html#a4">getRunnable</a>()))-&gt;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>-&gt;wakeUp();
+00175 <font class="preprocessor">#endif</font>
+00176 <font class="preprocessor"></font> <a class="code" href="classNLNET_1_1CBufServer.html#o5">_ListenThread</a>-&gt;<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&lt;CThreadPool&gt;::CAccessor poolsync( &amp;<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-&gt;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-&gt;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&lt;CConnections&gt;::CAccessor connectionssync( &amp;task-&gt;_Connections );
+00200 <font class="keywordflow">for</font> ( ipb=connectionssync.value().begin(); ipb!=connectionssync.value().end(); ++ipb )
+00201 {
+00202 (*ipb)-&gt;Sock-&gt;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)-&gt;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&lt;CConnections&gt;::CAccessor connectionssync( &amp;task-&gt;_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&lt;CConnections&gt;::CAccessor connectionssync( &amp;task-&gt;_Connections );
+00235 <font class="keywordflow">for</font> ( ipb=connectionssync.value().begin(); ipb!=connectionssync.value().end(); ++ipb )
+00236 {
+00237 (*ipb)-&gt;Sock-&gt;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-&gt;Sock-&gt;connected() )
+00268 {
+00269 <font class="keywordflow">if</font> ( ! quick )
+00270 {
+00271 hostid-&gt;flush();
+00272 }
+00273 hostid-&gt;Sock-&gt;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&lt;CThreadPool&gt;::CAccessor poolsync( &amp;<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&lt;CConnections&gt;::CAccessor connectionssync( &amp;task-&gt;_Connections );
+00288 <font class="keywordflow">for</font> ( ipb=connectionssync.value().begin(); ipb!=connectionssync.value().end(); ++ipb )
+00289 {
+00290 <font class="keywordflow">if</font> ( (*ipb)-&gt;Sock-&gt;connected() )
+00291 {
+00292 <font class="keywordflow">if</font> ( ! quick )
+00293 {
+00294 (*ipb)-&gt;flush();
+00295 }
+00296 (*ipb)-&gt;Sock-&gt;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&amp; 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() &gt; 0);
+00313 <a class="code" href="debug_8h.html#a6">nlassert</a>( buffer.length() &lt;= <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-&gt;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-&gt;SendNextValue);
+00324 <font class="preprocessor">#else</font>
+00325 <font class="preprocessor"></font> uint32 val = hostid-&gt;SendNextValue;
+00326 <font class="preprocessor">#endif</font>
+00327 <font class="preprocessor"></font>
+00328 *(uint32*)buffer.buffer() = val;
+00329 hostid-&gt;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&lt;CThreadPool&gt;::CAccessor poolsync( &amp;<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&lt;CConnections&gt;::CAccessor connectionssync( &amp;task-&gt;_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)-&gt;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)-&gt;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)-&gt;SendNextValue);
+00355 <font class="preprocessor">#else</font>
+00356 <font class="preprocessor"></font> uint32 val = (*ipb)-&gt;SendNextValue;
+00357 <font class="preprocessor">#endif</font>
+00358 <font class="preprocessor"></font> *(uint32*)buffer.buffer() = val;
+00359 (*ipb)-&gt;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&lt;uint8&gt; buffer;
+00386 uint8 val;
+00387 {
+00388 <a class="code" href="namespaceNLNET.html#a5">CFifoAccessor</a> recvfifo( &amp;<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 &gt; 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&lt;uint8&gt; 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>*)(&amp;*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-&gt;asString().c_str());
+00419
+00420 sockid-&gt;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)-&gt;ownerTask() != NULL );
+00431 ((<a class="code" href="classNLNET_1_1CBufServer.html#l0">CServerBufSock</a>*)sockid)-&gt;ownerTask()-&gt;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>*)(&amp;*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-&gt;asString().c_str());
+00439
+00440 sockid-&gt;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( &amp;<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( &amp;<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( &amp;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 &gt; 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&lt;uint8&gt; 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&lt;uint8&gt; buffer;</font>
+00513 <font class="comment"> recvfifo.value().front( buffer );</font>
+00514 <font class="comment"></font>
+00515 <font class="comment"> TSockId sockid = *((TSockId*)(&amp;*buffer.begin()));</font>
+00516 <font class="comment"> nldebug( "LNETL1: Disconnection event for %p %s", sockid, sockid-&gt;asString().c_str());</font>
+00517 <font class="comment"></font>
+00518 <font class="comment"> sockid-&gt;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)-&gt;ownerTask() != NULL );</font>
+00529 <font class="comment"> ((CServerBufSock*)sockid)-&gt;ownerTask()-&gt;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&lt;uint8&gt; buffer;</font>
+00536 <font class="comment"> recvfifo.value().front( buffer );</font>
+00537 <font class="comment"></font>
+00538 <font class="comment"> TSockId sockid = *((TSockId*)(&amp;*buffer.begin()));</font>
+00539 <font class="comment"> nldebug( "LNETL1: Connection event for %p %s", sockid, sockid-&gt;asString().c_str());</font>
+00540 <font class="comment"></font>
+00541 <font class="comment"> sockid-&gt;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&lt;uint8&gt; 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&amp; 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( &amp;<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>*)&amp;(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)-&gt;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)-&gt;ReceiveNextValue, (*phostid)-&gt;asString().c_str()));
+00604 <font class="comment">// resync the message number</font>
+00605 (*phostid)-&gt;ReceiveNextValue = val;
+00606 }
+00607
+00608 (*phostid)-&gt;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)-&gt;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&lt;CThreadPool&gt;::CAccessor poolsync( &amp;<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&lt;CConnections&gt;::CAccessor connectionssync( &amp;task-&gt;_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)-&gt;Sock-&gt;connected() &amp;&amp; (*ipb)-&gt;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)-&gt;asString().c_str() );
+00649 <font class="comment">// Disconnection event if disconnected (known either from flush (in update) or when receiving data)</font>
+00650 (*ipb)-&gt;advertiseDisconnection( <font class="keyword">this</font>, *ipb );
+00651
+00652 <font class="comment">/*if ( (*ipb)-&gt;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-&gt;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&lt;CThreadPool&gt;::CAccessor poolsync( &amp;<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&lt;CConnections&gt;::CAccessor connectionssync( &amp;task-&gt;_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)-&gt;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()&gt;_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( &amp;readers );
+00758 FD_SET( <a class="code" href="classNLNET_1_1CListenTask.html#o1">_ListenSock</a>.descriptor(), &amp;readers );
+00759 FD_SET( _WakeUpPipeHandle[PipeRead], &amp;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, &amp;readers, NULL, NULL, &amp;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], &amp;readers ) )
+00778 {
+00779 uint8 b;
+00780 <font class="keywordflow">if</font> ( read( _WakeUpPipeHandle[PipeRead], &amp;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-&gt;asString().c_str() );
+00791 bufsock-&gt;Sock-&gt;setNonBlockingMode( <font class="keyword">true</font> );
+00792 <font class="keywordflow">if</font> ( <a class="code" href="classNLNET_1_1CListenTask.html#o0">_Server</a>-&gt;noDelay() )
+00793 {
+00794 bufsock-&gt;Sock-&gt;setNoDelay( <font class="keyword">true</font> );
+00795 }
+00796
+00797 <font class="comment">// Notify the new connection</font>
+00798 bufsock-&gt;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>-&gt;dispatchNewSocket( bufsock );
+00802 }
+00803 <font class="keywordflow">catch</font> ( ESocket&amp; 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&lt;CThreadPool&gt;::CAccessor poolsync( &amp;<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)-&gt;numberOfConnections();
+00833 <font class="keywordflow">if</font> ( noc &lt; <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 &gt; 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) &amp;&amp; (poolsync.value().size() &lt; <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-&gt;setOwnerTask( task );
+00857 task-&gt;addNewSocket( bufsock );
+00858 <font class="preprocessor">#ifdef NL_OS_UNIX</font>
+00859 <font class="preprocessor"></font> task-&gt;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> &gt;= (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)-&gt;numberOfConnections();
+00876 <font class="keywordflow">if</font> ( noc &lt; <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-&gt;setOwnerTask( task );
+00896 task-&gt;addNewSocket( bufsock );
+00897 <font class="preprocessor">#ifdef NL_OS_UNIX</font>
+00898 <font class="preprocessor"></font> task-&gt;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>&amp; 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-&gt;setOwnerTask( task );
+00918 task-&gt;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-&gt;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&lt;TSockId&gt; 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( &amp;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&lt;CConnections&gt;::CAccessor connectionssync( &amp;<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)-&gt;Sock-&gt;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)-&gt;Sock-&gt;descriptor(), &amp;readers );
+00989
+00990 <font class="comment">// Calculate descmax for select</font>
+00991 <font class="keywordflow">if</font> ( (*ipb)-&gt;Sock-&gt;descriptor() &gt; descmax )
+00992 {
+00993 descmax = (*ipb)-&gt;Sock-&gt;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], &amp;readers );
+01001 <font class="keywordflow">if</font> ( _WakeUpPipeHandle[PipeRead]&gt;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 (=&gt; 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, &amp;readers, NULL, NULL, &amp;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&lt;TSockId&gt;::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)-&gt;Sock-&gt;descriptor(), &amp;readers ) != 0 )
+01057 {
+01058 CServerBufSock *serverbufsock = static_cast&lt;CServerBufSock*&gt;(static_cast&lt;CBufSock*&gt;(*ic));
+01059 <font class="keywordflow">try</font>
+01060 {
+01061 <font class="comment">// 4. Receive data</font>
+01062 <font class="keywordflow">if</font> ( serverbufsock-&gt;receivePart() )
+01063 {
+01064 <font class="comment">// Copy sockid</font>
+01065 vector&lt;uint8&gt; hidvec;
+01066 hidvec.resize( <font class="keyword">sizeof</font>(<a class="code" href="namespaceNLNET.html#a0">TSockId</a>)+1 );
+01067 memcpy( &amp;*hidvec.begin(), &amp;(*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( &amp;<a class="code" href="classNLNET_1_1CServerReceiveTask.html#o0">_Server</a>-&gt;receiveQueue() );
+01078 <font class="comment">//nldebug( "RCV: Acquired, pushing the received buffer... ");</font>
+01079 recvfifo.value().push( serverbufsock-&gt;receivedBuffer(), hidvec );
+01080 <a class="code" href="classNLNET_1_1CServerReceiveTask.html#o0">_Server</a>-&gt;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-&gt;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 &gt; 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&lt;uint32&gt;::CAccessor syncbpi ( &amp;_Server-&gt;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&amp; )
+01101 {
+01102 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: Connection %s closed"</font>, serverbufsock-&gt;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&amp; )
+01106 {
+01107 <a class="code" href="debug_8h.html#a0">nldebug</a>( <font class="stringliteral">"LNETL1: Connection %s broken"</font>, serverbufsock-&gt;asString().c_str() );
+01108 (*ic)-&gt;Sock-&gt;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) &amp;&amp; (FD_ISSET( _WakeUpPipeHandle[PipeRead], &amp;readers )) )
+01123 {
+01124 uint8 b;
+01125 <font class="keywordflow">if</font> ( read( _WakeUpPipeHandle[PipeRead], &amp;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&lt;CConnections&gt;::CAccessor removesetsync( &amp;<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&lt;CConnections&gt;::CAccessor connectionssync( &amp;<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>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </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>