فهرست منبع

2010-03-03 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Rewritten SocketBuffer. Old implementation uses single std::string
	to store data and erase sent data, which is costly. New
	implementation uses deque to hold each data to avoid to mutate
	string.
	* src/SocketBuffer.cc
	* src/SocketBuffer.h
Tatsuhiro Tsujikawa 15 سال پیش
والد
کامیت
5d05ef0e75
3فایلهای تغییر یافته به همراه49 افزوده شده و 16 حذف شده
  1. 9 0
      ChangeLog
  2. 23 13
      src/SocketBuffer.cc
  3. 17 3
      src/SocketBuffer.h

+ 9 - 0
ChangeLog

@@ -1,3 +1,12 @@
+2010-03-03  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Rewritten SocketBuffer. Old implementation uses single std::string
+	to store data and erase sent data, which is costly. New
+	implementation uses deque to hold each data to avoid to mutate
+	string.
+	* src/SocketBuffer.cc
+	* src/SocketBuffer.h
+
 2010-03-03  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Removed unused FileEntry::extracted

+ 23 - 13
src/SocketBuffer.cc

@@ -2,7 +2,7 @@
 /*
  * aria2 - The high speed download utility
  *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ * Copyright (C) 2010 Tatsuhiro Tsujikawa
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -44,13 +44,13 @@
 namespace aria2 {
 
 SocketBuffer::SocketBuffer(const SharedHandle<SocketCore>& socket):
-  _socket(socket) {}
+  _socket(socket), _offset(0) {}
 
 SocketBuffer::~SocketBuffer() {}
 
 void SocketBuffer::feedSendBuffer(const std::string& data)
 {
-  _sendbuf += data;
+  _bufq.push_back(data);
 }
 
 ssize_t SocketBuffer::feedAndSend(const std::string& data)
@@ -61,21 +61,31 @@ ssize_t SocketBuffer::feedAndSend(const std::string& data)
 
 ssize_t SocketBuffer::send()
 {
-  if(_sendbuf.empty()) {
-    return 0;
+  size_t totalslen = 0;
+  while(!_bufq.empty()) {
+    const std::string& data = _bufq[0];
+    const size_t size = data.size();
+    ssize_t r = size-_offset;
+    ssize_t slen = _socket->writeData(data.data()+_offset, r);
+    if(slen == 0 && !_socket->wantRead() && !_socket->wantWrite()) {
+      throw DL_ABORT_EX(StringFormat(EX_SOCKET_SEND,
+                                     "Connection closed.").str());
+    }
+    totalslen += slen;
+    if(slen < r) {
+      _offset += slen;
+      break;
+    } else {
+      _offset = 0;
+      _bufq.pop_front();
+    }
   }
-  ssize_t len = _socket->writeData(_sendbuf.c_str(),
-                                   _sendbuf.size());
-  if(len == 0 && !_socket->wantRead() && !_socket->wantWrite()) {
-    throw DL_ABORT_EX(StringFormat(EX_SOCKET_SEND, "Connection closed.").str());
-  }
-  _sendbuf.erase(0, len);
-  return len;
+  return totalslen;
 }
 
 bool SocketBuffer::sendBufferIsEmpty() const
 {
-  return _sendbuf.empty();
+  return _bufq.empty();
 }
 
 } // namespace aria2

+ 17 - 3
src/SocketBuffer.h

@@ -2,7 +2,7 @@
 /*
  * aria2 - The high speed download utility
  *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ * Copyright (C) 2010 Tatsuhiro Tsujikawa
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,8 +36,11 @@
 #define _D_SOCKET_BUFFER_H_
 
 #include "common.h"
-#include "SharedHandle.h"
+
 #include <string>
+#include <deque>
+
+#include "SharedHandle.h"
 
 namespace aria2 {
 
@@ -47,18 +50,29 @@ class SocketBuffer {
 private:
   SharedHandle<SocketCore> _socket;
 
-  std::string _sendbuf;
+  std::deque<std::string> _bufq;
+
+  // Offset of data in _bufq[0]. SocketBuffer tries to send _bufq[0],
+  // but it cannot always send whole data. In this case, offset points
+  // to the data to be sent in the next send() call.
+  size_t _offset;
 public:
   SocketBuffer(const SharedHandle<SocketCore>& socket);
 
   ~SocketBuffer();
 
+  // Feeds data into queue. This function doesn't send data.
   void feedSendBuffer(const std::string& data);
 
+  // Feeds data into queue and sends data in queue. This function is
+  // equivalent to call feedSendBuffer() and send() sequentially.
+  // Returns the number of bytes sent.
   ssize_t feedAndSend(const std::string& data);
 
+  // Sends data in queue.  Returns the number of bytes sent.
   ssize_t send();
 
+  // Returns true if queue is empty.
   bool sendBufferIsEmpty() const;
 
 };