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>
Removed unused FileEntry::extracted

View File

@ -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

View File

@ -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;
};