Browse Source

*** empty log message ***

Mike Goslin 25 years ago
parent
commit
fc8e976192

+ 8 - 7
panda/src/downloader/config_downloader.cxx

@@ -11,21 +11,22 @@
 Configure(config_downloader);
 NotifyCategoryDef(downloader, "");
 
+// How often we write to disk is determined by this ratio which is
+// relative to the downloader-byte-rate (e.g. if disk-write-ratio is 4,
+// we will write every 4 seconds if the frequency is 0.2)
+const int downloader_disk_write_frequency =
+	config_downloader.GetInt("downloader-disk-write-frequency", 4);
+
 // We'd like this to be about 1 second worth of download assuming a
 // 28.8Kb connection (28.8Kb / 8 = 3600 bytes per second).
-const int downloader_buffer_size = 
-	config_downloader.GetInt("downloader-buffer-size", 3600);
+const int downloader_byte_rate = 
+	config_downloader.GetInt("downloader-byte-rate", 3600);
 
 // Frequency of download chunk requests in seconds (or fractions of)
 // (Estimated 200 msec round-trip to server).
 const float downloader_frequency =
 	config_downloader.GetFloat("downloader-frequency", 0.2);
 
-// Estimated available bandwidth (assume a 28.8Kb connection, so again
-// we have 3600 bytes per second).
-const float downloader_bandwidth =
-	config_downloader.GetFloat("downloader-bandwidth", 3600.0);
-
 const int downloader_timeout =
 	config_downloader.GetInt("downloader-timeout", 15);
 

+ 2 - 2
panda/src/downloader/config_downloader.h

@@ -11,9 +11,9 @@
 
 NotifyCategoryDecl(downloader, EXPCL_PANDAEXPRESS, EXPTP_PANDAEXPRESS);
 
-extern const int downloader_buffer_size;
+extern const int downloader_disk_write_frequency;
+extern const int downloader_byte_rate;
 extern const float downloader_frequency;
-extern const float downloader_bandwidth;
 extern const int downloader_timeout;
 extern const int downloader_timeout_retries;
 

+ 33 - 10
panda/src/downloader/downloader.I

@@ -6,27 +6,27 @@
 #include "config_downloader.h"
 
 ////////////////////////////////////////////////////////////////////
-//     Function: Downloader::set_bandwidth
+//     Function: Downloader::set_byte_rate
 //       Access: Public
 //  Description: Note: modem speeds are reported in bits, so you 
 //		 need to convert! 
 ////////////////////////////////////////////////////////////////////
 INLINE void Downloader::
-set_bandwidth(float bytes) {
+set_byte_rate(float bytes) {
 #ifdef HAVE_IPC
   mutex_lock lock(_bandwidth_frequency_lock);
 #endif
-  _bandwidth = bytes;
+  _byte_rate = bytes;
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: Downloader::get_bandwidth
+//     Function: Downloader::get_byte_rate
 //       Access: Public
-//  Description: Returns bandwidth in bytes.
+//  Description: Returns byte rate in bytes.
 ////////////////////////////////////////////////////////////////////
 INLINE float Downloader::
-get_bandwidth(void) const {
-  return _bandwidth;
+get_byte_rate(void) const {
+  return _byte_rate;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -50,14 +50,17 @@ is_download_enabled(void) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: Downloader::change_buffer_size
+//     Function: Downloader::set_disk_write_frequency
 //       Access: Public
 //  Description:
 ////////////////////////////////////////////////////////////////////
 INLINE bool Downloader::
-change_buffer_size(int size) {
+set_disk_write_frequency(int frequency) {
+  nassertr(frequency > 0, false);
+  _disk_write_frequency = frequency;
+  int size = _disk_write_frequency * (_byte_rate * _frequency);
   if (size == _buffer_size)
-    return true;
+    return false;
   nassertr(size > 0, false);
 #ifdef HAVE_IPC
     _buffer_lock.lock();
@@ -68,3 +71,23 @@ change_buffer_size(int size) {
 #endif
   return true;
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: Downloader::get_disk_write_frequency
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE int Downloader::
+get_disk_write_frequency(void) const {
+  return _disk_write_frequency;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Downloader::get_last_attempt_stalled
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE bool Downloader::
+get_last_attempt_stalled(void) const {
+  return _last_attempt_stalled;
+}

+ 64 - 23
panda/src/downloader/downloader.cxx

@@ -57,12 +57,13 @@ public:
   INLINE DownloaderToken(uint id, const string &file_name, 
 	const Filename &file_dest, const string &event_name,
 	int first_byte, int last_byte, int total_bytes,
-	bool partial_content) : _id(id), _first_byte(first_byte), 
+	bool partial_content, bool sync) : _id(id), _first_byte(first_byte), 
 		_last_byte(last_byte), _total_bytes(total_bytes) {
     _file_name = file_name;
     _event_name = event_name;
     _file_dest = file_dest;
     _partial_content = partial_content;
+    _sync = sync;
   }
   uint _id;
   string _file_name; 
@@ -72,6 +73,7 @@ public:
   int _last_byte; 
   int _total_bytes;
   bool _partial_content;
+  bool _sync;
 };
 
 ////////////////////////////////////////////////////////////////////
@@ -81,10 +83,10 @@ public:
 ////////////////////////////////////////////////////////////////////
 Downloader::
 Downloader(void) : AsyncUtility() {
-  PT(Buffer) buffer = new Buffer(downloader_buffer_size);
-  init(buffer);
+  init();
 }
 
+#if 0
 ////////////////////////////////////////////////////////////////////
 //     Function: Downloader::Constructor
 //       Access: Public
@@ -94,6 +96,7 @@ Downloader::
 Downloader(PT(Buffer) buffer) : AsyncUtility() {
   init(buffer);
 }
+#endif
 
 ////////////////////////////////////////////////////////////////////
 //     Function: Downloader::init
@@ -101,18 +104,23 @@ Downloader(PT(Buffer) buffer) : AsyncUtility() {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 void Downloader::
-init(PT(Buffer) buffer) {
-  nassertv(!buffer.is_null());
+init(void) {
+  _disk_write_frequency = downloader_disk_write_frequency;
+  _byte_rate = downloader_byte_rate;
   _frequency = downloader_frequency;
-  _bandwidth = downloader_bandwidth;
+  nassertv(_frequency > 0);
+  if (_frequency == 0)
+    _buffer_size = _disk_write_frequency * _byte_rate;
+  else
+    _buffer_size = _disk_write_frequency * (_byte_rate * _frequency);
+  _buffer = new Buffer(_buffer_size);
+  _new_buffer_size = 0;
   _connected = false;
   _token_board = new DownloaderTokenBoard;
-  _buffer = buffer; 
   _download_enabled = true;
+  _last_attempt_stalled = true;
   // We need to flush after every write in case we're interrupted
   _dest_stream.setf(ios::unitbuf, 0);
-  _buffer_size = _buffer->get_length();
-  _new_buffer_size = 0;
 
 #if defined(WIN32)
   WSAData mydata;
@@ -227,6 +235,30 @@ disconnect_from_server(void) {
   _connected = false;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: Downloader::request_sync_download
+//       Access: Public
+//  Description: Requests the synchronous download of a complete file. 
+////////////////////////////////////////////////////////////////////
+int Downloader::
+request_sync_download(const string &file_name, const Filename &file_dest,
+		const string &event_name) {
+  return request_download(file_name, file_dest, event_name, true);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Downloader::request_sync_download
+//       Access: Public
+//  Description: Requests the synchronous download of a complete file. 
+////////////////////////////////////////////////////////////////////
+int Downloader::
+request_sync_download(const string &file_name, const Filename &file_dest,
+		const string &event_name, int first_byte,
+		int last_byte, int total_bytes, bool partial_content) {
+  return request_download(file_name, file_dest, event_name, first_byte,
+			last_byte, total_bytes, partial_content, true); 
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: Downloader::request_download
 //       Access: Public
@@ -234,9 +266,9 @@ disconnect_from_server(void) {
 ////////////////////////////////////////////////////////////////////
 int Downloader::
 request_download(const string &file_name, const Filename &file_dest,
-		const string &event_name) {
+		const string &event_name, bool sync) {
   return request_download(file_name, file_dest, event_name, 0, 0, 0,
-				false);
+				false, sync);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -258,7 +290,7 @@ int Downloader::
 request_download(const string &file_name, const Filename &file_dest,
 			const string &event_name, int first_byte,
 			int last_byte, int total_bytes,
-			bool partial_content) {
+			bool partial_content, bool sync) {
 
   nassertr(first_byte <= last_byte && last_byte <= total_bytes, 0);
 
@@ -291,7 +323,7 @@ request_download(const string &file_name, const Filename &file_dest,
 
       tok = new DownloaderToken(_next_token++, file_name, file_dest, 
 		event_name, first_byte, last_byte, total_bytes, 
-					partial_content);
+					partial_content, sync);
       _token_board->_waiting.insert(tok);
 
 #ifdef HAVE_IPC
@@ -314,7 +346,7 @@ request_download(const string &file_name, const Filename &file_dest,
 
     tok = new DownloaderToken(_next_token++, file_name, file_dest, 
 		event_name, first_byte, last_byte, total_bytes, 
-					partial_content);
+					partial_content, sync);
     _token_board->_waiting.insert(tok);
     process_request();
   }
@@ -342,7 +374,7 @@ process_request() {
     PT(DownloaderToken) tok = _token_board->_waiting.extract();
     int ret = download(tok->_file_name, tok->_file_dest, tok->_event_name,
 		 tok->_first_byte, tok->_last_byte, tok->_total_bytes,
-		 tok->_partial_content, tok->_id);
+		 tok->_partial_content, tok->_sync, tok->_id);
     if (ret == D_success) {
       _token_board->_done.insert(tok);
 
@@ -420,8 +452,9 @@ safe_send(int socket, const char *data, int length, long timeout) {
 ////////////////////////////////////////////////////////////////////
 int Downloader::
 safe_receive(int socket, DownloadStatus &status, int length, 
-					long timeout, int &bytes) {
+				long timeout, int &bytes, bool &stalled) {
   bytes = 0;
+  stalled = true;
   if (length == 0) {
     downloader_cat.error()
       << "Downloader::safe_receive() - requested 0 length receive!" << endl;
@@ -454,6 +487,8 @@ safe_receive(int socket, DownloadStatus &status, int length,
       bytes += ret;
       status._next_in += ret;
       status._bytes_in_buffer += ret;
+      if (bytes == length)
+        stalled = false;
     } else if (ret == 0) {
       if (downloader_cat.is_debug())
         downloader_cat.debug()
@@ -475,7 +510,8 @@ safe_receive(int socket, DownloadStatus &status, int length,
 //  Description:
 ////////////////////////////////////////////////////////////////////
 int Downloader::
-attempt_read(int length, DownloadStatus &status, int &bytes_read) {
+attempt_read(int length, DownloadStatus &status, int &bytes_read,
+			bool &stalled) {
 
   bytes_read = 0;
   for (int i = 0; i < downloader_timeout_retries; i++) {
@@ -494,7 +530,7 @@ attempt_read(int length, DownloadStatus &status, int &bytes_read) {
     // Make the request for length bytes
     int bytes;
     int ans = safe_receive(_socket, status, length,
-					(long)downloader_timeout, bytes); 
+				(long)downloader_timeout, bytes, stalled); 
     bytes_read += bytes;
 
     switch (ans) {
@@ -528,7 +564,7 @@ attempt_read(int length, DownloadStatus &status, int &bytes_read) {
 int Downloader::
 download(const string &file_name, Filename file_dest, 
 		const string &event_name, int first_byte, int last_byte,
-		int total_bytes, bool partial_content, uint id) {
+		int total_bytes, bool partial_content, bool sync, uint id) {
 
   if (_download_enabled == false) {
     if (downloader_cat.is_debug())
@@ -611,16 +647,21 @@ download(const string &file_name, Filename file_dest,
     _bandwidth_frequency_lock.lock();
 #endif
     // read_size is the length of the buffer requested via safe_receive()
-    int read_size = (int)_bandwidth;
-    if (_frequency > 0)
-      read_size = (int)(_bandwidth * _frequency);	
+    int read_size;
+    nassertr(_frequency > 0, D_error);
+    if (sync == true || _frequency == 0)
+      read_size = (int)_byte_rate;
+    else
+      read_size = (int)(_byte_rate * _frequency);	
 #ifdef HAVE_IPC
     _bandwidth_frequency_lock.unlock();
 #endif
 
     // Attempt to read
     int bytes_read;
-    int ret = attempt_read(read_size, status, bytes_read);
+    bool stalled;
+    int ret = attempt_read(read_size, status, bytes_read, stalled);
+    _last_attempt_stalled = stalled;
     if (bytes_read > 0)
       got_any_data = true;
 

+ 22 - 11
panda/src/downloader/downloader.h

@@ -33,24 +33,32 @@ class DownloaderToken;
 class EXPCL_PANDAEXPRESS Downloader : public AsyncUtility {
 PUBLISHED:
   Downloader(void);
-  Downloader(PT(Buffer) buffer);
+  //Downloader(PT(Buffer) buffer);
   virtual ~Downloader(void);
 
   bool connect_to_server(const string &name, uint port=80);
   void disconnect_from_server(void);
 
-  int request_download(const string &file_name, const Filename &file_dest,
+  int request_sync_download(const string &file_name, const Filename &file_dest,
 			const string &event_name);
+  int request_sync_download(const string &file_name, const Filename &file_dest,
+			const string &event_name, int first_byte,
+			int last_byte, int total_bytes,
+			bool partial_content = true);
+  int request_download(const string &file_name, const Filename &file_dest,
+			const string &event_name, bool sync = false);
   int request_download(const string &file_name, const Filename &file_dest,
 			const string &event_name, int first_byte,
 			int last_byte, int total_bytes, 
-			bool partial_content = true);
+			bool partial_content = true, bool sync = false);
 
-  INLINE void set_bandwidth(float bytes);
-  INLINE float get_bandwidth(void) const;
+  INLINE void set_byte_rate(float bytes);
+  INLINE float get_byte_rate(void) const;
+  INLINE bool set_disk_write_frequency(int frequency);
+  INLINE int get_disk_write_frequency(void) const;
   INLINE void enable_download(bool val);
   INLINE bool is_download_enabled(void) const;
-  INLINE bool change_buffer_size(int size);
+  INLINE bool get_last_attempt_stalled(void) const;
 
 private:
   class DownloadStatus {
@@ -79,20 +87,21 @@ private:
     char *_buffer;
   };
 
-  void init(PT(Buffer) buffer);
+  void init();
   int download(const string &file_name, Filename file_dest, 
 			const string &event_name, int first_byte,
 			int last_byte, int total_bytes, bool partial_content,
-			uint id);
+			bool sync, uint id);
   virtual bool process_request(void);
   bool parse_header(DownloadStatus &status);
   bool write_to_disk(DownloadStatus &status);
   bool connect_to_server(void);
   int safe_send(int socket, const char *data, int length, long timeout);
   int safe_receive(int socket, DownloadStatus &status, int length, 
-					long timeout, int &bytes);
+				long timeout, int &bytes, bool &stalled);
   bool parse_http_response(const string &resp);
-  int attempt_read(int length, DownloadStatus &status, int &bytes_read);
+  int attempt_read(int length, DownloadStatus &status, int &bytes_read,
+				bool &stalled);
 
   typedef TokenBoard<DownloaderToken> DownloaderTokenBoard;
   DownloaderTokenBoard *_token_board;
@@ -106,11 +115,13 @@ private:
 
   int _socket;
   PT(Buffer) _buffer;
-  float _bandwidth;
+  int _disk_write_frequency;
+  float _byte_rate; 
   bool _download_enabled;
   ofstream _dest_stream;
   int _new_buffer_size;
   int _buffer_size;
+  bool _last_attempt_stalled;
 
   string _server_name;
   struct sockaddr_in _sin;