Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VsnetTCPSocket Class Reference

#include <vsnet_sockettcp.h>

Inheritance diagram for VsnetTCPSocket:
VsnetSocket VsnetSocketBase

Classes

struct  Blob
 
struct  Header
 
class  SqQueues
 

Public Types

typedef boost::shared_ptr< PacketPacketPtr
 

Public Member Functions

 VsnetTCPSocket (int sock, const AddressIP &remote_ip, SocketSet &set)
 
virtual ~VsnetTCPSocket ()
 
virtual bool isTcp () const
 
virtual int optPayloadSize () const
 
virtual int queueLen (int pri)
 
virtual int sendbuf (Packet *packet, const AddressIP *to, int pcktflags)
 
virtual int recvbuf (Packet *p, AddressIP *ipadr)
 
virtual void dump (std::ostream &ostr) const
 
virtual bool isActive ()
 
virtual bool lower_selected (int datalen=-1)
 
virtual bool need_test_writable ()
 
virtual int get_write_fd () const
 
virtual int lower_sendbuf ()
 
virtual void lower_clean_sendbuf ()
 
- Public Member Functions inherited from VsnetSocket
 VsnetSocket (int sock, const AddressIP &remote_ip, const char *socktype, SocketSet &set)
 
virtual ~VsnetSocket ()
 
bool eq (const VsnetSocket &r) const
 
bool lt (const VsnetSocket &r) const
 
bool sameAddress (const VsnetSocket &r) const
 
const AddressIPgetRemoteAddress () const
 
virtual bool setRemoteAddress (const AddressIP &)
 
const AddressIPgetLocalAddress () const
 
bool setLocalAddress (const AddressIP &lip)
 
- Public Member Functions inherited from VsnetSocketBase
 VsnetSocketBase (int fd, const char *socktype, SocketSet &set)
 
virtual ~VsnetSocketBase ()
 
bool valid () const
 
int get_fd () const
 
int close_fd ()
 
const char * get_socktype () const
 
bool set_block ()
 
bool set_nonblock ()
 
bool get_nonblock () const
 
void disconnect (const char *s)
 
virtual bool write_on_negative ()
 
virtual bool isReadyToSend (fd_set *)
 
void setSet (SocketSet *set)
 

Protected Types

typedef std::queue< PacketPtrSqQueue
 
typedef std::queue< PacketMemSqQueueP
 

Protected Member Functions

virtual void child_disconnect (const char *s)
 
void inc_pending ()
 
void dec_pending ()
 
void inner_complete_a_packet (Blob *b)
 
void private_nothread_conditional_write ()
 

Protected Attributes

Blob_incomplete_packet
 
std::queue< PacketPtr_cpq
 cpq = completed packet queue More...
 
VSMutex _cpq_mx
 
int _incomplete_header
 
Header _header
 
bool _connection_closed
 
SqQueues _sq
 
SqQueueP _sq_current
 
size_t _sq_off
 
VSMutex _sq_mx
 
int _sq_fd
 
- Protected Attributes inherited from VsnetSocket
AddressIP _remote_ip
 
AddressIP _local_ip
 
- Protected Attributes inherited from VsnetSocketBase
int _fd
 
SocketSet_set
 

Detailed Description

Definition at line 26 of file vsnet_sockettcp.h.

Member Typedef Documentation

typedef boost::shared_ptr< Packet > VsnetTCPSocket::PacketPtr

Definition at line 30 of file vsnet_sockettcp.h.

typedef std::queue< PacketPtr > VsnetTCPSocket::SqQueue
protected

TCP may refuse to send all bytes at once, hence we have to queue packets for sending. In addition, we use the same thread for sending and receiving, thus it would be advantageous to use asynchronous sending. For both, we need a send queue. _sq is the a of priority queues. _sq_current is the queue (with up to two entries) for sending the current packet, which consists of the packet length and the packet payload. _sq.off is the number of bytes that have already been sent from PacketMem _sq_current.front(). _sq_mx protects the queues.

Definition at line 138 of file vsnet_sockettcp.h.

typedef std::queue< PacketMem > VsnetTCPSocket::SqQueueP
protected

Definition at line 139 of file vsnet_sockettcp.h.

Constructor & Destructor Documentation

VsnetTCPSocket::VsnetTCPSocket ( int  sock,
const AddressIP remote_ip,
SocketSet set 
)

Definition at line 63 of file vsnet_sockettcp.cpp.

References _sq_fd, COUT, and VsnetTCPSocket().

Referenced by VsnetTCPSocket().

63  :
64  VsnetSocket( sock, remote_ip, "VsnetTCPSocket", sets )
65  , _incomplete_packet( 0 )
66  , _incomplete_header( 0 )
67  , _connection_closed( false )
68  , _sq_off( 0 )
69  , _mtu_size_estimation( 1024 )
70 {
71  COUT<<"enter "<<__PRETTY_FUNCTION__<<endl;
72  _sq_fd = sock;
73 }
VsnetTCPSocket::~VsnetTCPSocket ( )
virtual

Definition at line 75 of file vsnet_sockettcp.cpp.

References _connection_closed, _incomplete_packet, VsnetSocketBase::close_fd(), COUT, VsnetSocketBase::get_fd(), and VsnetSocketBase::valid().

76 {
77  COUT<<"enter "<<__PRETTY_FUNCTION__<<endl;
79  delete _incomplete_packet;
80  if (valid() && !_connection_closed && get_fd() >= 0)
81  close_fd();
82 }

Member Function Documentation

void VsnetTCPSocket::child_disconnect ( const char *  s)
protectedvirtual

Reimplemented from VsnetSocketBase.

Definition at line 295 of file vsnet_sockettcp.cpp.

References VsnetSocketBase::close_fd(), COUT, and VsnetSocketBase::get_fd().

296 {
297  if (get_fd() > 0) {
298  if (close_fd() < 0)
299  COUT<<s<<" :\tWarning: disconnect error: "<<strerror( errno )<<endl;
300  else
301  COUT<<s<<" :\tWarning: disconnected"<<endl;
302  } else {
303  COUT<<s<<" :\tWarning: disconnect null socket: "<<strerror( errno )<<endl;
304  }
305 }
void VsnetTCPSocket::dec_pending ( )
protected
void VsnetTCPSocket::dump ( std::ostream &  ostr) const
virtual

Implements VsnetSocket.

Definition at line 307 of file vsnet_sockettcp.cpp.

References VsnetSocket::_remote_ip, and VsnetSocketBase::get_fd().

308 {
309  ostr<<"( s="<<get_fd()<<" TCP r="<<_remote_ip<<" )";
310 }
int VsnetTCPSocket::get_write_fd ( ) const
virtual

Reimplemented from VsnetSocketBase.

Definition at line 146 of file vsnet_sockettcp.cpp.

References _sq_fd.

147 {
148  return _sq_fd;
149 }
void VsnetTCPSocket::inc_pending ( )
protected

The number of pending packets reported to the set.

void VsnetTCPSocket::inner_complete_a_packet ( Blob b)
protected

Definition at line 457 of file vsnet_sockettcp.cpp.

References _cpq, _cpq_mx, VsnetSocketBase::_set, _sq_fd, SocketSet::add_pending(), b, VsnetTCPSocket::Blob::buf, VsnetTCPSocket::Blob::expected_len, VSMutex::lock(), VsnetTCPSocket::Blob::present_len, and VSMutex::unlock().

Referenced by lower_selected().

458 {
459  assert( b );
460  assert( b->present_len == b->expected_len );
461 
462  PacketMem mem( b->buf, b->present_len, PacketMem::TakeOwnership );
463  PacketPtr ptr = PacketPtr( new Packet( mem ) );
464  //if (ptr->getCommand()!=CMD_POSUPDATE && ptr->getCommand()!=CMD_SNAPSHOT)
465  //COUT << "Completely received a packet of type " << ptr->getCommand() << endl;
466  b->buf = NULL;
467  _cpq_mx.lock();
468  _cpq.push( ptr );
469  _cpq_mx.unlock();
470  if (_set) _set->add_pending( _sq_fd );
471  delete b;
472 }
bool VsnetTCPSocket::isActive ( )
virtual

Implements VsnetSocketBase.

Definition at line 318 of file vsnet_sockettcp.cpp.

References _connection_closed, _cpq, _cpq_mx, VsnetSocketBase::_set, _sq_fd, VSMutex::lock(), private_nothread_conditional_write(), SocketSet::rem_pending(), and VSMutex::unlock().

319 {
320  /* True is the correct answer when the connection is closed:
321  * the app must call recvbuf once after this to receive 0
322  * and start close processing.
323  * We could return packets from the queue first, but that may
324  * trigger an answer packet from the application, and give
325  * us trouble because of the closed socket.
326  */
327  if (_connection_closed)
328  return true;
329  bool retval = false;
330 
331  _cpq_mx.lock();
332  if (_cpq.empty() == false)
333  retval = true;
334  else if (_set)
335  _set->rem_pending( _sq_fd );
336  _cpq_mx.unlock();
337 
339 
340  return retval;
341 }
virtual bool VsnetTCPSocket::isTcp ( ) const
inlinevirtual

Implements VsnetSocket.

Definition at line 36 of file vsnet_sockettcp.h.

37  {
38  return true;
39  }
void VsnetTCPSocket::lower_clean_sendbuf ( )
virtual

Called when we noticed that the primary file descriptor is closed but data remains in the send queue.

Reimplemented from VsnetSocketBase.

Definition at line 251 of file vsnet_sockettcp.cpp.

References _sq, _sq_current, _sq_mx, _sq_off, COUT, VsnetTCPSocket::SqQueues::empty(), VSMutex::lock(), VsnetTCPSocket::SqQueues::pop(), and VSMutex::unlock().

252 {
253  _sq_mx.lock();
254  while ( !_sq.empty() ) {
255  _sq.pop();
256 #ifdef VSNET_DEBUG
257  COUT<<"forgetting a packet in _sq"<<endl;
258 #endif
259  }
260  while ( !_sq_current.empty() ) {
261  _sq_current.pop();
262 #ifdef VSNET_DEBUG
263  COUT<<"forgetting a segment in _sq_current"<<endl;
264 #endif
265  _sq_off = 0;
266  }
267  _sq_mx.unlock();
268 }
bool VsnetTCPSocket::lower_selected ( int  datalen = -1)
virtual

Implements VsnetSocketBase.

Definition at line 343 of file vsnet_sockettcp.cpp.

References _connection_closed, _header, _incomplete_header, _incomplete_packet, VsnetSocketBase::_set, _sq_fd, SocketSet::add_pending(), b, VsnetTCPSocket::Blob::base(), VsnetTCPSocket::Blob::buf, VsnetSocketBase::close_fd(), COUT, PacketMem::dump(), VsnetTCPSocket::Blob::expected_len, VsnetSocketBase::get_fd(), VsnetSocketBase::get_nonblock(), VsnetTCPSocket::Header::h_len(), i, inner_complete_a_packet(), VsnetTCPSocket::Blob::missing(), VsnetTCPSocket::Blob::present_len, VsnetOSS::recv(), vsnetEConnAborted(), vsnetEConnReset(), vsnetEWouldBlock(), vsnetGetLastError(), and vsnetLastError().

344 {
345  if (_connection_closed) {
346  COUT<<"Connection already closed"<<endl;
347  return true; /* Pretty sure that recv will return 0. */
348  }
349  bool endless = true;
350  bool successful = false;
351  if (get_nonblock() == false && datalen == -1) endless = false;
352  do {
353  if ( (_incomplete_header > 0)
354  || (_incomplete_header == 0 && _incomplete_packet == 0) ) {
355  assert( _incomplete_packet == 0 ); //we expect a len, can not have data yet
356  assert( (unsigned int) _incomplete_header < sizeof (Header) ); //len is coded in sizeof(Header) bytes
357  unsigned int len = sizeof (Header)-_incomplete_header;
358  char *b = (char*) &_header;
359  int ret = VsnetOSS::recv( get_fd(), &b[_incomplete_header], len, 0 );
360  if (ret <= 0) {
361  if ( ret == 0 || vsnetEConnAborted() || vsnetEConnReset() ) {
362  COUT<<"Connection closed in header"<<endl;
363  _connection_closed = true;
364  close_fd();
365  if (_set) _set->add_pending( _sq_fd );
366  return true;
367  } else if (vsnetEWouldBlock() == false) {
368  COUT<<"recv returned "<<ret
369  <<" errno "<<vsnetGetLastError()
370  <<" = "<<vsnetLastError()
371  <<endl;
372  perror( "receiving TCP packetlength bytes" );
373  _connection_closed = true;
374  close_fd();
375  return true;
376  } else {
377  //COUT << "Received EWOULDBLOCK." << (get_nonblock()?"true":"false") << endl;
378  }
379  return successful;
380  }
381  assert( (unsigned int)ret <= len );
382  if (ret > 0) _incomplete_header += ret;
383  if (datalen != -1) datalen -= ret;
384  if ( _incomplete_header == sizeof (Header) ) {
385  _incomplete_header = 0;
386  len = _header.h_len();
387  _incomplete_packet = new Blob( len );
388  }
389  }
390  if (_incomplete_packet != 0) {
391  int len = _incomplete_packet->missing();
392  if (datalen > 0)
393  len = datalen < len ? datalen : len;
394  int ret = VsnetOSS::recv( get_fd(), _incomplete_packet->base(), len, 0 );
395  assert( ret <= len );
396  if (ret <= 0) {
397  if (ret == 0) {
398  COUT<<"Connection closed in data"<<endl;
399  _connection_closed = true;
400  close_fd();
401  if (_set) _set->add_pending( _sq_fd );
402  return true;
403  } else if ( vsnetEConnAborted() ) {
404  perror( "receiving TCP packet" );
405  if (get_fd() == -1) {
406  perror( "receiving dead TCP packet" );
407  } else {
408  COUT<<"Connection closed in error"<<endl;
409  _connection_closed = true;
410  close_fd();
411  if (_set) _set->add_pending( _sq_fd );
412  }
413  return true;
414  } else if ( vsnetEWouldBlock() ) {
415  static int i = 0;
416  if (i++%128 == 0)
417  COUT<<"Received EWOULDBLOCK in data."<<(get_nonblock() ? "true" : "false")<<endl;
418  }
419  return successful;
420  } else {
421  if (datalen != -1) {
422  datalen -= ret;
423  if (datalen <= 0)
424  endless = false;
425  }
427  if (ret == len) {
430 #ifdef VSNET_DEBUG
431  //
432  //DEBUG block - remove soon
433  //
434  {
435  Blob *b = _incomplete_packet;
436  COUT<<"received buffer with len "<<b->present_len<<": "<<endl;
437  PacketMem m( b->buf, b->present_len, PacketMem::LeaveOwnership );
438 #if 0
439  m.dump( cout, 3 );
440 #endif
441  }
442 #endif
443 
445  _incomplete_packet = 0;
446  successful = true;
447  endless = false; //If we're done, let's stop while we're ahead.
448 
449  //either endless is false, or we exit with EWOULDBLOCK
450  }
451  }
452  }
453  } while (endless); //exit only for EWOULDBLOCK or closed socket
454  return successful;
455 }
int VsnetTCPSocket::lower_sendbuf ( )
virtual

Reimplemented from VsnetSocketBase.

Definition at line 164 of file vsnet_sockettcp.cpp.

References _sq, _sq_current, _sq_fd, _sq_mx, _sq_off, COUT, VsnetTCPSocket::SqQueues::empty(), fprintf, h, PacketMem::len(), VSMutex::lock(), VsnetTCPSocket::SqQueues::pop(), and VSMutex::unlock().

165 {
166  _sq_mx.lock();
167  if ( _sq_current.empty() ) {
168  if ( _sq.empty() ) {
169 #ifdef VSNET_DEBUG
170  COUT<<"both queues are empty"<<endl;
171 #endif
172  _sq_mx.unlock();
173  return 0;
174  } else {
175  PacketPtr m = _sq.pop();
176  int len = m->getSendBufferLength();
177  Header h( len );
178  _sq_current.push( PacketMem( &h, sizeof (Header) ) );
179  _sq_current.push( PacketMem( m->getSendBuffer(), len ) );
180  _sq_off = 0;
181  }
182  }
183  PacketMem packet( _sq_current.front() );
184 
185  int numsent;
186  unsigned int len = packet.len();
187  assert( len > _sq_off );
188  len -= _sq_off;
189  const char *buf = packet.getConstBuf();
190  numsent = ::send( _sq_fd, &buf[_sq_off], len, 0 );
191  if (numsent < 0) {
192  switch (errno)
193  {
194 #if defined (_WIN32) && !defined (__CYGWIN__)
195  case WSAECONNRESET: //other side closed socket
196  case WSAECONNABORTED: //other side closed socket
197  case WSAEWOULDBLOCK:
198 #else
199  case ECONNRESET: //other side closed socket
200  case ECONNABORTED: //other side closed socket
201  case EWOULDBLOCK:
202 #endif
203  case EINTR:
204  _sq_mx.unlock();
205  return 0;
206 
207  case EFAULT:
208  _sq_mx.unlock();
209  COUT<<"EFAULT"<<endl
210  <<" *** An invalid user space address was specified for a parameter."<<endl
211  <<" *** fd : "<<_sq_fd<<endl
212  <<" *** buf : "<<std::hex<<(long) buf<<std::dec<<endl
213  <<" *** sq offset : "<<_sq_off<<endl
214  <<" *** packet len: "<<packet.len()<<endl;
215  return 0;
216 
217  default:
218  fprintf( stderr, "Failed sending TCP data of %d len to socket %d\n", len, _sq_fd );
219  perror( "\tsending TCP data" );
220  _sq_mx.unlock();
221  return -1;
222  }
223  } else if (numsent == 0) {
224  //other side closed socket - what to do now?
225  _sq_mx.unlock();
226  return numsent;
227  } else if ( (unsigned int) numsent == len ) {
228  _sq_off = 0;
229  _sq_current.pop();
230  _sq_mx.unlock();
231 #ifdef VSNET_DEBUG
232  //
233  //DEBUG block - remove soon
234  //
235  {
236  COUT<<"sent buffer with len "<<packet.len()<<": "<<endl;
237 #if 0
238  packet.dump( cout, 0 );
239 #endif
240  }
241 #endif
242  return numsent;
243  } else {
244  assert( (unsigned int) numsent < len ); //should be impossible
245  _sq_off += numsent;
246  _sq_mx.unlock();
247  return numsent;
248  }
249 }
bool VsnetTCPSocket::need_test_writable ( )
virtual

Reimplemented from VsnetSocketBase.

Definition at line 131 of file vsnet_sockettcp.cpp.

References _sq, _sq_current, _sq_mx, COUT, e, VsnetTCPSocket::SqQueues::empty(), VSMutex::lock(), and VSMutex::unlock().

132 {
133  _sq_mx.lock();
134  bool e = ( _sq.empty() && _sq_current.empty() );
135 #ifdef VSNET_DEBUG
136  if (!e)
137  COUT<<"_sq "
138  <<(_sq.empty() ? "empty" : "not empty")
139  <<", _sq_current "
140  <<(_sq_current.empty() ? "empty" : "not empty")<<endl;
141 #endif
142  _sq_mx.unlock();
143  return !e;
144 }
int VsnetTCPSocket::optPayloadSize ( ) const
virtual

Implements VsnetSocket.

Definition at line 151 of file vsnet_sockettcp.cpp.

152 {
153  return _mtu_size_estimation;
154 }
void VsnetTCPSocket::private_nothread_conditional_write ( )
protected

Definition at line 123 of file vsnet_sockettcp.cpp.

References _connection_closed, VsnetSocketBase::_set, and SocketSet::waste_time().

Referenced by isActive().

124 {
125 #ifdef USE_NO_THREAD
126  if (_connection_closed) return;
127  if (_set) _set->waste_time( 0, 0 ); //waste zero time, but check sockets
128 #endif
129 }
int VsnetTCPSocket::queueLen ( int  pri)
virtual

Implements VsnetSocket.

Definition at line 156 of file vsnet_sockettcp.cpp.

References _sq, _sq_mx, VsnetTCPSocket::SqQueues::getLength(), VSMutex::lock(), and VSMutex::unlock().

157 {
158  _sq_mx.lock();
159  int retval = _sq.getLength( pri );
160  _sq_mx.unlock();
161  return retval;
162 }
int VsnetTCPSocket::recvbuf ( Packet p,
AddressIP from 
)
virtual

This function copies or moves data into the given PacketMem variable. It is preferred over the other recvbuf function because it may reduce the number of copy operations by at least one.

Implements VsnetSocket.

Definition at line 270 of file vsnet_sockettcp.cpp.

References _connection_closed, _cpq, _cpq_mx, VsnetSocket::_remote_ip, VsnetSocketBase::_set, _sq_fd, VsnetSocketBase::close_fd(), Packet::copyfrom(), COUT, VSMutex::lock(), SocketSet::rem_pending(), and VSMutex::unlock().

271 {
272  _cpq_mx.lock();
273  if (_cpq.empty() == false) {
274  PacketPtr ptr = _cpq.front();
275  _cpq.pop();
276  _cpq_mx.unlock();
277 
278  AddressIP dummy;
279  if (ipadr) *ipadr = _remote_ip;
280  p->copyfrom( *ptr.get() );
281  return ptr->getDataLength()+ptr->getHeaderLength();
282  } else if (_connection_closed) {
283  if (_set) _set->rem_pending( _sq_fd );
284  _cpq_mx.unlock();
285  close_fd();
286  COUT<<__PRETTY_FUNCTION__<<" connection is closed"<<endl;
287  return 0;
288  } else {
289  if (_set) _set->rem_pending( _sq_fd );
290  _cpq_mx.unlock();
291  return -1;
292  }
293 }
int VsnetTCPSocket::sendbuf ( Packet packet,
const AddressIP to,
int  pcktflags 
)
virtual
  • Use a priority queue instead of a standard queue.

Implements VsnetSocket.

Definition at line 104 of file vsnet_sockettcp.cpp.

References VsnetSocketBase::_set, _sq, _sq_mx, e, VsnetTCPSocket::SqQueues::empty(), Packet::getSendBufferLength(), HIPRI, VSMutex::lock(), LOPRI, VsnetTCPSocket::SqQueues::push(), VSMutex::unlock(), and SocketSet::wakeup().

105 {
106  int idx = 1;
107  if (pcktflags&LOPRI) idx = 0;
108  if (pcktflags&HIPRI) idx = 2;
109  /* Add a timestamp here -- drop packets when they get too old.
110  */
111 
112  PacketPtr enq = PacketPtr( new Packet( *packet ) );
113 
114  _sq_mx.lock();
115  bool e = _sq.empty();
116 
117  _sq.push( idx, enq );
118  _sq_mx.unlock();
119  if (e && _set) _set->wakeup();
120  return packet->getSendBufferLength();
121 }

Member Data Documentation

bool VsnetTCPSocket::_connection_closed
protected

Closed connections are noticed in isActive but evaluated by the application after recvbuf. So, we remember the situation here until the application notices it.

Definition at line 122 of file vsnet_sockettcp.h.

Referenced by isActive(), lower_selected(), private_nothread_conditional_write(), recvbuf(), and ~VsnetTCPSocket().

std::queue< PacketPtr > VsnetTCPSocket::_cpq
protected

cpq = completed packet queue

Definition at line 106 of file vsnet_sockettcp.h.

Referenced by inner_complete_a_packet(), isActive(), and recvbuf().

VSMutex VsnetTCPSocket::_cpq_mx
protected

Definition at line 107 of file vsnet_sockettcp.h.

Referenced by inner_complete_a_packet(), isActive(), and recvbuf().

Header VsnetTCPSocket::_header
protected

Definition at line 116 of file vsnet_sockettcp.h.

Referenced by lower_selected().

int VsnetTCPSocket::_incomplete_header
protected

We send sizeof(Header) bytes as a packet length indicator. Unfortunately, even these sizeof(Header) bytes may be split by TCP. These two variables are needed for collecting the sizeof(Header) bytes. Note: for the obvious reason that this happens rarely, the collection code can not be considered tested.

Definition at line 115 of file vsnet_sockettcp.h.

Referenced by lower_selected().

Blob* VsnetTCPSocket::_incomplete_packet
protected

if we have received part of a TCP packet but not the complete packet, the expected length and received number of bytes are stored in _incomplete_packet. If several packets have been received at once, but the application processes them one at a time, the received, unprocessed packets are stored in the list.

Definition at line 103 of file vsnet_sockettcp.h.

Referenced by lower_selected(), and ~VsnetTCPSocket().

SqQueues VsnetTCPSocket::_sq
protected
SqQueueP VsnetTCPSocket::_sq_current
protected

Definition at line 161 of file vsnet_sockettcp.h.

Referenced by lower_clean_sendbuf(), lower_sendbuf(), and need_test_writable().

int VsnetTCPSocket::_sq_fd
protected
VSMutex VsnetTCPSocket::_sq_mx
protected
size_t VsnetTCPSocket::_sq_off
protected

Definition at line 162 of file vsnet_sockettcp.h.

Referenced by lower_clean_sendbuf(), and lower_sendbuf().


The documentation for this class was generated from the following files: