[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: kdenonbeta/icecream/icecream/services
From: Stephan Kulow <coolo () kde ! org>
Date: 2004-08-29 20:19:14
Message-ID: 20040829201914.ABBDA1DD4 () office ! kde ! org
[Download RAW message or body]
CVS commit by coolo:
trying to support shorter time outs in connect
M +85 -3 comm.cpp 1.105
M +4 -0 logging.h 1.6
--- kdenonbeta/icecream/icecream/services/comm.cpp #1.104:1.105
@@ -475,5 +475,5 @@ Service::Service (const string &hostname
if (!host)
{
- log_error() << "Unknown host " << strerror(errno) << endl;
+ log_perror("Unknown host");
close (remote_fd);
return;
@@ -485,12 +485,94 @@ Service::Service (const string &hostname
return;
}
+ fcntl(remote_fd, F_SETFL, O_NONBLOCK);
+
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons (p);
memcpy (&remote_addr.sin_addr.s_addr, host->h_addr_list[0], host->h_length);
- if (connect (remote_fd, (struct sockaddr *) &remote_addr, sizeof (remote_addr)) < 0)
+ int status = connect (remote_fd, (struct sockaddr *) &remote_addr, sizeof (remote_addr) );
+
+ if ( ( status < 0 ) && ( errno == EINPROGRESS || errno == EAGAIN ) )
{
- close (remote_fd);
+ struct timeval select_timeout;
+ int ret;
+ int tries=0;
+
+ ret = 0;
+ while (ret <= 0) {
+ fd_set writefds;
+
+ trace() << "trying to connect\n";
+ /*
+ ** Protect against an infinite loop.
+ */
+ if (tries++ >= 100) {
+ return;
+ }
+
+ select_timeout.tv_sec = 0;
+ select_timeout.tv_usec = 100000;
+ FD_ZERO(&writefds);
+ FD_SET(remote_fd, &writefds);
+ ret = select(remote_fd + 1, NULL, &writefds, NULL, &select_timeout);
+
+ /*
+ ** If we suspend, then it is possible that select will be
+ ** interrupted. Allow for this possibility. - JED
+ */
+ if ((ret == -1) && (errno == EINTR))
+ continue;
+
+ if ((ret < 0) && (errno != EALREADY)) {
+ status = ret;
+ break;
+ } else if (ret > 0) {
+ /*
+ ** Extra check here for connection success, if we try to
+ ** connect again, and get EISCONN, it means we have a
+ ** successful connection. But don't check with SOCKS.
+ */
+ status = connect(remote_fd, (struct sockaddr*)&remote_addr,
+ sizeof(remote_addr));
+ if ((status < 0) && (errno == EISCONN))
+ {
+ status = 0;
+ }
+
+ if (status && (errno == EALREADY)) /* new stuff LJM */
+ ret = 0; /* keep going */
+ else {
+ break;
+ }
+ }
+ else
+ {
+ status = connect(remote_fd, (struct sockaddr*)&remote_addr,
+ sizeof(remote_addr));
+ if ((status < 0) &&
+ (errno != EALREADY
+ && errno != EAGAIN )
+ && (errno != EISCONN)) {
+ break;
+ }
+ }
+ }
+ }
+ if (status < 0)
+ {
+ /*
+ ** The connect attempt failed or was interrupted,
+ ** so close up the socket.
+ */
+ trace() << "failed\n";
+ close(remote_fd);
return;
}
+ else {
+ /*
+ ** Make the socket blocking again on good connect.
+ */
+ fcntl(remote_fd, F_SETFL, 0);
+ }
+ trace() << "connected " << remote_fd << endl;
len = sizeof (remote_addr);
addr = (struct sockaddr *)malloc (len);
--- kdenonbeta/icecream/icecream/services/logging.h #1.5:1.6
@@ -55,4 +55,8 @@ static inline std::ostream& trace() {
std::string get_backtrace();
+static inline void log_perror(const char *prefix) {
+ int tmp_errno = errno;
+ log_error() << prefix << " " << strerror( tmp_errno ) << std::endl;
+}
#endif
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic