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
pull/1/head
Tatsuhiro Tsujikawa 2010-03-03 14:29:40 +00:00
parent 48c809d441
commit 5d05ef0e75
3 changed files with 49 additions and 16 deletions

View File

@ -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> 2010-03-03 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Removed unused FileEntry::extracted Removed unused FileEntry::extracted

View File

@ -2,7 +2,7 @@
/* /*
* aria2 - The high speed download utility * 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 * 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 * it under the terms of the GNU General Public License as published by
@ -44,13 +44,13 @@
namespace aria2 { namespace aria2 {
SocketBuffer::SocketBuffer(const SharedHandle<SocketCore>& socket): SocketBuffer::SocketBuffer(const SharedHandle<SocketCore>& socket):
_socket(socket) {} _socket(socket), _offset(0) {}
SocketBuffer::~SocketBuffer() {} SocketBuffer::~SocketBuffer() {}
void SocketBuffer::feedSendBuffer(const std::string& data) void SocketBuffer::feedSendBuffer(const std::string& data)
{ {
_sendbuf += data; _bufq.push_back(data);
} }
ssize_t SocketBuffer::feedAndSend(const std::string& 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() ssize_t SocketBuffer::send()
{ {
if(_sendbuf.empty()) { size_t totalslen = 0;
return 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());
} }
ssize_t len = _socket->writeData(_sendbuf.c_str(), totalslen += slen;
_sendbuf.size()); if(slen < r) {
if(len == 0 && !_socket->wantRead() && !_socket->wantWrite()) { _offset += slen;
throw DL_ABORT_EX(StringFormat(EX_SOCKET_SEND, "Connection closed.").str()); break;
} else {
_offset = 0;
_bufq.pop_front();
} }
_sendbuf.erase(0, len); }
return len; return totalslen;
} }
bool SocketBuffer::sendBufferIsEmpty() const bool SocketBuffer::sendBufferIsEmpty() const
{ {
return _sendbuf.empty(); return _bufq.empty();
} }
} // namespace aria2 } // namespace aria2

View File

@ -2,7 +2,7 @@
/* /*
* aria2 - The high speed download utility * 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 * 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 * it under the terms of the GNU General Public License as published by
@ -36,8 +36,11 @@
#define _D_SOCKET_BUFFER_H_ #define _D_SOCKET_BUFFER_H_
#include "common.h" #include "common.h"
#include "SharedHandle.h"
#include <string> #include <string>
#include <deque>
#include "SharedHandle.h"
namespace aria2 { namespace aria2 {
@ -47,18 +50,29 @@ class SocketBuffer {
private: private:
SharedHandle<SocketCore> _socket; 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: public:
SocketBuffer(const SharedHandle<SocketCore>& socket); SocketBuffer(const SharedHandle<SocketCore>& socket);
~SocketBuffer(); ~SocketBuffer();
// Feeds data into queue. This function doesn't send data.
void feedSendBuffer(const std::string& 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); ssize_t feedAndSend(const std::string& data);
// Sends data in queue. Returns the number of bytes sent.
ssize_t send(); ssize_t send();
// Returns true if queue is empty.
bool sendBufferIsEmpty() const; bool sendBufferIsEmpty() const;
}; };