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
VsnetDownload::Server::Manager Class Reference

#include <vsnet_dloadmgr.h>

Public Member Functions

 Manager (SocketSet &set, const char **local_search_paths)
 
 Manager (SocketSet &set)
 
void addCmdDownload (SOCKETALT sock, NetBuffer &buffer)
 
void cleanDownload (SOCKETALT s)
 
void lower_check_queues ()
 

Detailed Description

The download manager on the server side works in the networking thread as well. It does not catch CMD_DOWNLOAD messages from the client, but it is handed these requests by NetServer::processPacket. It doesn't care about the client, but only about the socket that connects the server to the client. The download manager could run in a separate process, but that would make it very difficult to manage the connection bandwidth.

Definition at line 177 of file vsnet_dloadmgr.h.

Constructor & Destructor Documentation

VsnetDownload::Server::Manager::Manager ( SocketSet set,
const char **  local_search_paths 
)
VsnetDownload::Server::Manager::Manager ( SocketSet set)

Definition at line 491 of file vsnet_dloadmgr.cpp.

References COUT, and VSFileSystem::datadir.

491  :
492  _set( sets )
493 {
494  COUT<<"Enter "<<__PRETTY_FUNCTION__<<endl;
495 
496  _local_search_paths.push_back( VSFileSystem::datadir );
497 }

Member Function Documentation

void VsnetDownload::Server::Manager::addCmdDownload ( SOCKETALT  sock,
NetBuffer buffer 
)

NetServer::processPacket calls this. NetServer doesn't care, but we process the NetBuffer actually already in the main thread before triggering wakeup.

Definition at line 499 of file vsnet_dloadmgr.cpp.

References NetBuffer::addChar(), NetBuffer::addShort(), NetBuffer::addString(), VsnetDownload::RecvCmdDownload::asDownloadRequest(), VsnetDownload::RecvCmdDownload::asResolveRequest(), c, CMD_DOWNLOAD, COMPRESSED, COUT, VsnetDownload::DownloadRequest, f, accountXML::file, VsnetDownload::Adapter::ResolveRequest::files, VsnetDownload::Adapter::DownloadRequest::files, NetBuffer::getData(), NetBuffer::getDataLength(), getZoneInfoBuffer(), VSMutex::lock(), LOPRI, VsnetDownload::Adapter::ResolveRequest::num, VsnetDownload::Adapter::DownloadRequest::num, VsnetDownload::RecvCmdDownload::parse(), PSEUDO__LINE__, VsnetOSS::recv(), VsnetDownload::ResolveResponse, Packet::send(), SENDRELIABLE, VSFileSystem::VSFile::Size(), VsnetDownload::UnexpectedSubcommand, VSMutex::unlock(), SocketSet::wakeup(), and VSFileSystem::ZoneBuffer.

500 {
501  COUT<<"Enter "<<__PRETTY_FUNCTION__<<endl;
502 
503  RecvCmdDownload recv( buffer );
504  Subcommand c = recv.parse();
505 
506  COUT<<" *** "<<" cmd "<<c<<endl;
507  switch (c)
508  {
509  case ResolveRequest:
510  {
511  Adapter::ResolveRequest *r = recv.asResolveRequest();
512 
513  short num = r->num;
514 
515  NetBuffer respbuffer;
516  respbuffer.addChar( ResolveResponse );
517  respbuffer.addShort( num );
518 
520  for (iter = r->files.begin(); iter != r->files.end(); iter++) {
521  bool ok;
522  char ft = iter->ft;
523  string file = iter->file;
524  //If we want to download a memory buffer from server access is considered ok
525  if (ft == VSFileSystem::ZoneBuffer) {
526  //We receive a filename containing a zone id so we test it exists
527  int zoneid = atoi( file.c_str() );
528  ok = true;
529  } else {
530  ok = private_test_access( file, (VSFileSystem::VSFileType) ft );
531  }
532  respbuffer.addString( file );
533  respbuffer.addChar( ok ? 1 : 0 );
534  }
535  Packet packet;
536  packet.send( CMD_DOWNLOAD, 0,
537  respbuffer.getData(), respbuffer.getDataLength(),
539  NULL, sock,
540  __FILE__, PSEUDO__LINE__( 334 ) );
541  break;
542  }
543  case DownloadRequest:
544  {
545  Adapter::DownloadRequest *r = recv.asDownloadRequest();
546  short num = r->num;
547  if (num > 0) {
549  for (iter = r->files.begin(); iter != r->files.end(); iter++) {
550  char ft = iter->ft;
551  string file = iter->file;
552  string path = file;
553  DownloadItemPtr di;
555  //If a request for ZoneBuffer we create a VSFile based on a memory buffer
556  if (ft == VSFileSystem::ZoneBuffer) {
557  NetBuffer netbuf;
558  getZoneInfoBuffer( atoi( file.c_str() ), netbuf );
559  //f = new VSFile( netbuf.getData(), netbuf.getDataLength());
560 
561  DownloadItemBuf *buf;
562  buf = new DownloadItemBuf( sock, file, netbuf.getData(), netbuf.getDataLength() );
563  di.reset( buf );
564  } else {
565  f = private_access( path, (VSFileSystem::VSFileType) ft );
566  if (f) {
567  size_t bytes = f->Size();
568  di.reset( new DownloadItemFile( sock, file, f, bytes ) );
569  } else {
570  //Couldn't open for reading, maybe removed since resolve?
571  di.reset( new DownloadItemFile( sock, file ) );
572  }
573  }
574  _download_mx.lock();
575  _download.push( di );
576  _download_mx.unlock();
577  }
578  _set.wakeup();
579  }
580  break;
581  }
582  default:
583  {
584  NetBuffer respbuffer;
585 
586  respbuffer.addChar( UnexpectedSubcommand );
587  respbuffer.addChar( c );
588  Packet packet;
589  packet.send( CMD_DOWNLOAD, 0,
590  respbuffer.getData(), respbuffer.getDataLength(),
592  NULL, sock,
593  __FILE__, PSEUDO__LINE__( 334 ) );
594  break;
595  }
596  }
597 }
void VsnetDownload::Server::Manager::cleanDownload ( SOCKETALT  s)

The NetServer must tell the download manager that a socket has been closed or is otherwise expired. : function needs cleanup (via mutex or private_lower*) - there is a bad race right now.

Definition at line 599 of file vsnet_dloadmgr.cpp.

References COUT.

600 {
601  COUT<<"Enter "<<__PRETTY_FUNCTION__<<endl;
602 
603  _lower_download.erase( s );
604 }
void VsnetDownload::Server::Manager::lower_check_queues ( )

Called by SocketSet after each round.

Definition at line 606 of file vsnet_dloadmgr.cpp.

References COUT, done, VSMutex::lock(), q, and VSMutex::unlock().

607 {
608  _download_mx.lock();
609  while (_download.empty() == false) {
610  COUT<<"Enter "<<__PRETTY_FUNCTION__<<endl;
611 
612  DownloadItemPtr item = _download.front();
613  _download.pop();
614  ItemMap_I it = _lower_download.find( item->getSock() );
615  if ( it == _lower_download.end() ) {
616  ItemQueuePtr q( new ItemQueue );
617  _lower_download.insert( ItemMapPair( item->getSock(), q ) );
618  it = _lower_download.find( item->getSock() );
619  }
620  it->second->push( item );
621  }
622  _download_mx.unlock();
623 
624  list< SOCKETALT >tbd; //to be deleted
625  list< SOCKETALT >::const_iterator tbdi;
626 
627  ItemMap_I it;
628  for (it = _lower_download.begin(); it != _lower_download.end(); it++) {
629  COUT<<"Enter "<<__PRETTY_FUNCTION__<<endl;
630 
631  bool done = private_lower_try_push_queue( it->first, it->second );
632  if (done)
633  tbd.push_back( it->first );
634  /* This is expensive but I don't dare to call erase() here
635  * because I don't know whether the STL standard allows iterator
636  * invalidation for map<>. And anyway, MSVC doesn't care about
637  * standards, so better safe than sorry.
638  */
639  }
640  for (tbdi = tbd.begin(); tbdi != tbd.end(); tbdi++)
641  _lower_download.erase( *tbdi );
642 }

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