mirror of https://github.com/aria2/aria2
2010-04-24 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
In SocketCore::isReadable()/isWritable(), use poll() if it is available otherwise use select(). Removed epoll/port from there because poll() does the good enough job for single socket event notification. * src/SocketCore.cc * src/SocketCore.h * src/main.ccpull/1/head
parent
5d636df361
commit
5635190927
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2010-04-24 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
In SocketCore::isReadable()/isWritable(), use poll() if it is
|
||||
available otherwise use select(). Removed epoll/port from there
|
||||
because poll() does the good enough job for single socket event
|
||||
notification.
|
||||
* src/SocketCore.cc
|
||||
* src/SocketCore.h
|
||||
* src/main.cc
|
||||
|
||||
2010-04-24 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Added kqueue support. We use poll() for
|
||||
|
|
|
@ -38,9 +38,6 @@
|
|||
#ifdef HAVE_IFADDRS_H
|
||||
# include <ifaddrs.h>
|
||||
#endif // HAVE_IFADDRS_H
|
||||
#ifdef HAVE_PORT_H
|
||||
# include <port.h>
|
||||
#endif // HAVE_PORT_H
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
|
@ -121,12 +118,6 @@ static const char *errorMsg()
|
|||
return errorMsg(SOCKET_ERRNO);
|
||||
}
|
||||
|
||||
#ifdef HAVE_EPOLL
|
||||
SocketCore::PollMethod SocketCore::_pollMethod = SocketCore::POLL_METHOD_EPOLL;
|
||||
#else // !HAVE_EPOLL
|
||||
SocketCore::PollMethod SocketCore::_pollMethod = SocketCore::POLL_METHOD_SELECT;
|
||||
#endif // !HAVE_EPOLL
|
||||
|
||||
int SocketCore::_protocolFamily = AF_UNSPEC;
|
||||
|
||||
std::vector<std::pair<struct sockaddr_storage, socklen_t> >
|
||||
|
@ -151,13 +142,6 @@ SocketCore::SocketCore(sock_t sockfd, int sockType):_sockType(sockType), sockfd(
|
|||
|
||||
void SocketCore::init()
|
||||
{
|
||||
#ifdef HAVE_EPOLL
|
||||
_epfd = -1;
|
||||
#endif // HAVE_EPOLL
|
||||
#ifdef HAVE_PORT_ASSOCIATE
|
||||
_portfd = -1;
|
||||
#endif // HAVE_PORT_ASSOCIATE
|
||||
|
||||
blocking = true;
|
||||
secure = 0;
|
||||
|
||||
|
@ -178,16 +162,6 @@ void SocketCore::init()
|
|||
|
||||
SocketCore::~SocketCore() {
|
||||
closeConnection();
|
||||
#ifdef HAVE_EPOLL
|
||||
if(_epfd != -1) {
|
||||
CLOSE(_epfd);
|
||||
}
|
||||
#endif // HAVE_EPOLL
|
||||
#ifdef HAVE_PORT_ASSOCIATE
|
||||
if(_portfd != -1) {
|
||||
CLOSE(_portfd);
|
||||
}
|
||||
#endif // HAVE_PORT_ASSOCIATE
|
||||
#ifdef HAVE_LIBGNUTLS
|
||||
delete [] peekBuf;
|
||||
#endif // HAVE_LIBGNUTLS
|
||||
|
@ -572,119 +546,47 @@ void SocketCore::closeConnection()
|
|||
#endif // HAVE_LIBGNUTLS
|
||||
}
|
||||
|
||||
#ifdef HAVE_EPOLL
|
||||
|
||||
void SocketCore::initEPOLL()
|
||||
{
|
||||
if((_epfd = epoll_create(1)) == -1) {
|
||||
throw DL_RETRY_EX(StringFormat("epoll_create failed:%s", errorMsg()).str());
|
||||
}
|
||||
|
||||
memset(&_epEvent, 0, sizeof(struct epoll_event));
|
||||
_epEvent.events = EPOLLIN|EPOLLOUT;
|
||||
_epEvent.data.fd = sockfd;
|
||||
|
||||
if(epoll_ctl(_epfd, EPOLL_CTL_ADD, sockfd, &_epEvent) == -1) {
|
||||
throw DL_RETRY_EX(StringFormat("epoll_ctl failed:%s", errorMsg()).str());
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HAVE_EPOLL
|
||||
|
||||
#ifdef HAVE_PORT_ASSOCIATE
|
||||
void SocketCore::initPort()
|
||||
{
|
||||
if((_portfd = port_create()) == -1) {
|
||||
throw DL_RETRY_EX(StringFormat("port_create failed:%s", errorMsg()).str());
|
||||
}
|
||||
if(port_associate(_portfd, PORT_SOURCE_FD, sockfd, POLLIN|POLLOUT, 0) == -1) {
|
||||
throw DL_RETRY_EX
|
||||
(StringFormat("port_associate failed:%s", errorMsg()).str());
|
||||
}
|
||||
}
|
||||
#endif // HAVE_PORT_ASSOCIATE
|
||||
|
||||
bool SocketCore::isWritable(time_t timeout)
|
||||
{
|
||||
#ifdef HAVE_EPOLL
|
||||
if(_pollMethod == SocketCore::POLL_METHOD_EPOLL) {
|
||||
if(_epfd == -1) {
|
||||
initEPOLL();
|
||||
}
|
||||
struct epoll_event epEvents[1];
|
||||
int r;
|
||||
while((r = epoll_wait(_epfd, epEvents, 1, timeout*1000)) == -1 &&
|
||||
errno == EINTR);
|
||||
if(r > 0) {
|
||||
return epEvents[0].events&(EPOLLOUT|EPOLLHUP|EPOLLERR);
|
||||
} else if(r == 0) {
|
||||
#ifdef HAVE_POLL
|
||||
struct pollfd p;
|
||||
p.fd = sockfd;
|
||||
p.events = POLLOUT;
|
||||
int r;
|
||||
while((r = poll(&p, 1, timeout*1000)) == -1 && errno == EINTR);
|
||||
if(r > 0) {
|
||||
return p.revents&(POLLOUT|POLLHUP|POLLERR);
|
||||
} else if(r == 0) {
|
||||
return false;
|
||||
} else {
|
||||
throw DL_RETRY_EX
|
||||
(StringFormat(EX_SOCKET_CHECK_WRITABLE, errorMsg()).str());
|
||||
}
|
||||
#else // !HAVE_POLL
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(sockfd, &fds);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
int r = select(sockfd+1, NULL, &fds, NULL, &tv);
|
||||
if(r == 1) {
|
||||
return true;
|
||||
} else if(r == 0) {
|
||||
// time out
|
||||
return false;
|
||||
} else {
|
||||
if(SOCKET_ERRNO == A2_EINPROGRESS || SOCKET_ERRNO == A2_EINTR) {
|
||||
return false;
|
||||
} else {
|
||||
throw DL_RETRY_EX(StringFormat(EX_SOCKET_CHECK_WRITABLE, errorMsg()).str());
|
||||
throw DL_RETRY_EX
|
||||
(StringFormat(EX_SOCKET_CHECK_WRITABLE, errorMsg()).str());
|
||||
}
|
||||
} else
|
||||
#endif // HAVE_EPOLL
|
||||
#ifdef HAVE_PORT_ASSOCIATE
|
||||
if(_pollMethod == SocketCore::POLL_METHOD_PORT) {
|
||||
if(_portfd == -1) {
|
||||
initPort();
|
||||
}
|
||||
struct timespec ts = { timeout, 0 };
|
||||
port_event_t portEvent;
|
||||
int r = port_get(_portfd, &portEvent, &ts);
|
||||
if(r == 0) {
|
||||
return portEvent.portev_events&(POLLOUT|POLLHUP|POLLERR);
|
||||
} else if(r == -1 && (errno == ETIME || errno == EINTR)) {
|
||||
return false;
|
||||
} else {
|
||||
throw DL_RETRY_EX
|
||||
(StringFormat(EX_SOCKET_CHECK_WRITABLE, errorMsg()).str());
|
||||
}
|
||||
} else
|
||||
#endif // HAVE_PORT_ASSOCIATE
|
||||
#ifdef HAVE_POLL
|
||||
if(_pollMethod == SocketCore::POLL_METHOD_POLL) {
|
||||
struct pollfd p;
|
||||
p.fd = sockfd;
|
||||
p.events = POLLOUT;
|
||||
int r;
|
||||
while((r = poll(&p, 1, timeout*1000)) == -1 && errno == EINTR);
|
||||
if(r > 0) {
|
||||
return p.revents&(POLLOUT|POLLHUP|POLLERR);
|
||||
} else if(r == 0) {
|
||||
return false;
|
||||
} else {
|
||||
throw DL_RETRY_EX
|
||||
(StringFormat(EX_SOCKET_CHECK_WRITABLE, errorMsg()).str());
|
||||
}
|
||||
} else
|
||||
#endif // HAVE_POLL
|
||||
if(_pollMethod == SocketCore::POLL_METHOD_SELECT) {
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(sockfd, &fds);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
int r = select(sockfd+1, NULL, &fds, NULL, &tv);
|
||||
if(r == 1) {
|
||||
return true;
|
||||
} else if(r == 0) {
|
||||
// time out
|
||||
return false;
|
||||
} else {
|
||||
if(SOCKET_ERRNO == A2_EINPROGRESS || SOCKET_ERRNO == A2_EINTR) {
|
||||
return false;
|
||||
} else {
|
||||
throw DL_RETRY_EX
|
||||
(StringFormat(EX_SOCKET_CHECK_WRITABLE, errorMsg()).str());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif // !HAVE_POLL
|
||||
}
|
||||
|
||||
bool SocketCore::isReadable(time_t timeout)
|
||||
|
@ -694,87 +596,44 @@ bool SocketCore::isReadable(time_t timeout)
|
|||
return true;
|
||||
}
|
||||
#endif // HAVE_LIBGNUTLS
|
||||
#ifdef HAVE_POLL
|
||||
struct pollfd p;
|
||||
p.fd = sockfd;
|
||||
p.events = POLLIN;
|
||||
int r;
|
||||
while((r = poll(&p, 1, timeout*1000)) == -1 && errno == EINTR);
|
||||
if(r > 0) {
|
||||
return p.revents&(POLLIN|POLLHUP|POLLERR);
|
||||
} else if(r == 0) {
|
||||
return false;
|
||||
} else {
|
||||
throw DL_RETRY_EX
|
||||
(StringFormat(EX_SOCKET_CHECK_READABLE, errorMsg()).str());
|
||||
}
|
||||
#else // !HAVE_POLL
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(sockfd, &fds);
|
||||
|
||||
#ifdef HAVE_EPOLL
|
||||
if(_pollMethod == SocketCore::POLL_METHOD_EPOLL) {
|
||||
if(_epfd == -1) {
|
||||
initEPOLL();
|
||||
}
|
||||
struct epoll_event epEvents[1];
|
||||
int r;
|
||||
while((r = epoll_wait(_epfd, epEvents, 1, timeout*1000)) == -1 &&
|
||||
errno == EINTR);
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if(r > 0) {
|
||||
return epEvents[0].events&(EPOLLIN|EPOLLHUP|EPOLLERR);
|
||||
} else if(r == 0) {
|
||||
int r = select(sockfd+1, &fds, NULL, NULL, &tv);
|
||||
if(r == 1) {
|
||||
return true;
|
||||
} else if(r == 0) {
|
||||
// time out
|
||||
return false;
|
||||
} else {
|
||||
if(SOCKET_ERRNO == A2_EINPROGRESS || SOCKET_ERRNO == A2_EINTR) {
|
||||
return false;
|
||||
} else {
|
||||
throw DL_RETRY_EX(StringFormat(EX_SOCKET_CHECK_READABLE, errorMsg()).str());
|
||||
throw DL_RETRY_EX
|
||||
(StringFormat(EX_SOCKET_CHECK_READABLE, errorMsg()).str());
|
||||
}
|
||||
} else
|
||||
#endif // HAVE_EPOLL
|
||||
#ifdef HAVE_PORT_ASSOCIATE
|
||||
if(_pollMethod == SocketCore::POLL_METHOD_PORT) {
|
||||
if(_portfd == -1) {
|
||||
initPort();
|
||||
}
|
||||
struct timespec ts = { timeout, 0 };
|
||||
port_event_t portEvent;
|
||||
int r = port_get(_portfd, &portEvent, &ts);
|
||||
if(r == 0) {
|
||||
return portEvent.portev_events&(POLLIN|POLLHUP|POLLERR);
|
||||
} else if(r == -1 && (errno == ETIME || errno == EINTR)) {
|
||||
return false;
|
||||
} else {
|
||||
throw DL_RETRY_EX
|
||||
(StringFormat(EX_SOCKET_CHECK_READABLE, errorMsg()).str());
|
||||
}
|
||||
} else
|
||||
#endif // HAVE_PORT_ASSOCIATE
|
||||
#ifdef HAVE_POLL
|
||||
if(_pollMethod == SocketCore::POLL_METHOD_POLL) {
|
||||
struct pollfd p;
|
||||
p.fd = sockfd;
|
||||
p.events = POLLIN;
|
||||
int r;
|
||||
while((r = poll(&p, 1, timeout*1000)) == -1 && errno == EINTR);
|
||||
if(r > 0) {
|
||||
return p.revents&(POLLIN|POLLHUP|POLLERR);
|
||||
} else if(r == 0) {
|
||||
return false;
|
||||
} else {
|
||||
throw DL_RETRY_EX
|
||||
(StringFormat(EX_SOCKET_CHECK_READABLE, errorMsg()).str());
|
||||
}
|
||||
} else
|
||||
#endif // HAVE_POLL
|
||||
if(_pollMethod == SocketCore::POLL_METHOD_SELECT) {
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(sockfd, &fds);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
int r = select(sockfd+1, &fds, NULL, NULL, &tv);
|
||||
if(r == 1) {
|
||||
return true;
|
||||
} else if(r == 0) {
|
||||
// time out
|
||||
return false;
|
||||
} else {
|
||||
if(SOCKET_ERRNO == A2_EINPROGRESS || SOCKET_ERRNO == A2_EINTR) {
|
||||
return false;
|
||||
} else {
|
||||
throw DL_RETRY_EX
|
||||
(StringFormat(EX_SOCKET_CHECK_READABLE, errorMsg()).str());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif // !HAVE_POLL
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBSSL
|
||||
|
@ -1320,32 +1179,6 @@ bool SocketCore::wantWrite() const
|
|||
return _wantWrite;
|
||||
}
|
||||
|
||||
#ifdef HAVE_EPOLL
|
||||
void SocketCore::useEpoll()
|
||||
{
|
||||
_pollMethod = SocketCore::POLL_METHOD_EPOLL;
|
||||
}
|
||||
#endif // HAVE_EPOLL
|
||||
|
||||
#ifdef HAVE_PORT_ASSOCIATE
|
||||
void SocketCore::usePort()
|
||||
{
|
||||
_pollMethod = SocketCore::POLL_METHOD_PORT;
|
||||
}
|
||||
#endif // HAVE_PORT_ASSOCIATE
|
||||
|
||||
#ifdef HAVE_POLL
|
||||
void SocketCore::usePoll()
|
||||
{
|
||||
_pollMethod = SocketCore::POLL_METHOD_POLL;
|
||||
}
|
||||
#endif // HAVE_POLL
|
||||
|
||||
void SocketCore::useSelect()
|
||||
{
|
||||
_pollMethod = SocketCore::POLL_METHOD_SELECT;
|
||||
}
|
||||
|
||||
void SocketCore::bindAddress(const std::string& iface)
|
||||
{
|
||||
std::vector<std::pair<struct sockaddr_storage, socklen_t> > bindAddrs;
|
||||
|
|
|
@ -37,10 +37,6 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
#ifdef HAVE_EPOLL
|
||||
# include <sys/epoll.h>
|
||||
#endif // HAVE_EPOLL
|
||||
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <utility>
|
||||
|
@ -78,28 +74,6 @@ private:
|
|||
// socket endpoint descriptor
|
||||
sock_t sockfd;
|
||||
|
||||
#ifdef HAVE_EPOLL
|
||||
|
||||
// file descriptor used for epoll
|
||||
int _epfd;
|
||||
|
||||
struct epoll_event _epEvent;
|
||||
|
||||
#endif // HAVE_EPOLL
|
||||
|
||||
#ifdef HAVE_PORT_ASSOCIATE
|
||||
int _portfd;
|
||||
#endif // HAVE_PORT_ASSOCIATE
|
||||
|
||||
enum PollMethod {
|
||||
POLL_METHOD_EPOLL,
|
||||
POLL_METHOD_PORT,
|
||||
POLL_METHOD_POLL,
|
||||
POLL_METHOD_SELECT
|
||||
};
|
||||
|
||||
static PollMethod _pollMethod;
|
||||
|
||||
static int _protocolFamily;
|
||||
|
||||
static std::vector<std::pair<struct sockaddr_storage, socklen_t> > _bindAddrs;
|
||||
|
@ -138,13 +112,6 @@ private:
|
|||
|
||||
void bind(const struct sockaddr* addr, socklen_t addrlen);
|
||||
|
||||
#ifdef HAVE_EPOLL
|
||||
void initEPOLL();
|
||||
#endif // HAVE_EPOLL
|
||||
#ifdef HAVE_PORT_ASSOCIATE
|
||||
void initPort();
|
||||
#endif // HAVE_PORT_ASSOCIATE
|
||||
|
||||
void setSockOpt(int level, int optname, void* optval, socklen_t optlen);
|
||||
|
||||
SocketCore(sock_t sockfd, int sockType);
|
||||
|
@ -365,17 +332,6 @@ public:
|
|||
*/
|
||||
bool wantWrite() const;
|
||||
|
||||
#ifdef HAVE_EPOLL
|
||||
static void useEpoll();
|
||||
#endif // HAVE_EPOLL
|
||||
#ifdef HAVE_PORT_ASSOCIATE
|
||||
static void usePort();
|
||||
#endif // HAVE_PORT_ASSOCIATE
|
||||
#ifdef HAVE_POLL
|
||||
static void usePoll();
|
||||
#endif // HAVE_POLL
|
||||
static void useSelect();
|
||||
|
||||
#ifdef ENABLE_SSL
|
||||
static void setTLSContext(const SharedHandle<TLSContext>& tlsContext);
|
||||
#endif // ENABLE_SSL
|
||||
|
|
25
src/main.cc
25
src/main.cc
|
@ -186,32 +186,7 @@ downloadresultcode::RESULT main(int argc, char* argv[])
|
|||
if(op->getAsBool(PREF_QUIET)) {
|
||||
LogFactory::setConsoleOutput(false);
|
||||
}
|
||||
const std::string& pollMethod = op->get(PREF_EVENT_POLL);
|
||||
#ifdef HAVE_EPOLL
|
||||
if(pollMethod == V_EPOLL) {
|
||||
SocketCore::useEpoll();
|
||||
} else
|
||||
#endif // HAVE_EPOLL
|
||||
#ifdef HAVE_KQUEUE
|
||||
if(pollMethod == V_KQUEUE) {
|
||||
SocketCore::usePoll();
|
||||
} else
|
||||
#endif // HAVE_KQUEUE
|
||||
#ifdef HAVE_PORT_ASSOCIATE
|
||||
if(pollMethod == V_PORT) {
|
||||
SocketCore::usePort();
|
||||
} else
|
||||
#endif // HAVE_PORT_ASSOCIATE
|
||||
#ifdef HAVE_POLL
|
||||
if(pollMethod == V_POLL) {
|
||||
SocketCore::usePoll();
|
||||
} else
|
||||
#endif // HAVE_POLL
|
||||
if(pollMethod == V_SELECT) {
|
||||
SocketCore::useSelect();
|
||||
}
|
||||
downloadresultcode::RESULT exitStatus = downloadresultcode::FINISHED;
|
||||
|
||||
Logger* logger = LogFactory::getInstance();
|
||||
logger->info("<<--- --- --- ---");
|
||||
logger->info(" --- --- --- ---");
|
||||
|
|
Loading…
Reference in New Issue