X-Git-Url: https://git.sesse.net/?p=cubemap;a=blobdiff_plain;f=httpinput.cpp;h=49501831fa7df2805eead2a172b5dab5d77a3320;hp=f92ac13ca9ca010f1b2a8efb2d45cba68c40b12f;hb=71fc5575037bead8b6e927a1fffd199e4fc4514b;hpb=ba03a3ed19cc8b02d4bb198edfd1c8bee9f28e35 diff --git a/httpinput.cpp b/httpinput.cpp index f92ac13..4950183 100644 --- a/httpinput.cpp +++ b/httpinput.cpp @@ -1,4 +1,3 @@ -#include #include #include #include @@ -21,7 +20,6 @@ #include "parse.h" #include "serverpool.h" #include "state.pb.h" -#include "util.h" #include "version.h" using namespace std; @@ -62,7 +60,14 @@ HTTPInput::HTTPInput(const InputProto &serialized) void HTTPInput::close_socket() { - safe_close(sock); + int ret; + do { + ret = close(sock); + } while (ret == -1 && errno == EINTR); + + if (ret == -1) { + log_perror("close()"); + } } InputProto HTTPInput::serialize() const @@ -94,64 +99,31 @@ int HTTPInput::lookup_and_connect(const string &host, const string &port) addrinfo *base_ai = ai; // Connect to everything in turn until we have a socket. - while (ai && !should_stop()) { + while (ai && !should_stop) { int sock = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP); if (sock == -1) { // Could be e.g. EPROTONOSUPPORT. The show must go on. continue; } - // Now do a non-blocking connect. This is important because we want to be able to be - // woken up, even though it's rather cumbersome. - - // Set the socket as nonblocking. - int one = 1; - if (ioctl(sock, FIONBIO, &one) == -1) { - log_perror("ioctl(FIONBIO)"); - safe_close(sock); - return -1; - } - - // Do a non-blocking connect. do { err = connect(sock, ai->ai_addr, ai->ai_addrlen); } while (err == -1 && errno == EINTR); - if (err == -1 && errno != EINPROGRESS) { - log_perror("connect"); - safe_close(sock); - continue; - } - - // Wait for the connect to complete, or an error to happen. - for ( ;; ) { - bool complete = wait_for_activity(sock, POLLIN | POLLOUT, NULL); - if (should_stop()) { - safe_close(sock); - return -1; - } - if (complete) { - break; - } - } - - // Check whether it ended in an error or not. - socklen_t err_size = sizeof(err); - if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &err_size) == -1) { - log_perror("getsockopt"); - safe_close(sock); - continue; + if (err != -1) { + freeaddrinfo(base_ai); + return sock; } - errno = err; + do { + err = close(sock); + } while (err == -1 && errno == EINTR); - if (err == 0) { - // Successful connect. - freeaddrinfo(base_ai); - return sock; + if (err == -1) { + log_perror("close"); + // Can still continue. } - safe_close(sock); ai = ai->ai_next; } @@ -249,13 +221,23 @@ bool HTTPInput::parse_response(const std::string &request) void HTTPInput::do_work() { - while (!should_stop()) { + while (!should_stop) { if (state == SENDING_REQUEST || state == RECEIVING_HEADER || state == RECEIVING_DATA) { - bool activity = wait_for_activity(sock, (state == SENDING_REQUEST) ? POLLOUT : POLLIN, NULL); - if (!activity) { - // Most likely, should_stop was set. + // Since we are non-blocking, we need to wait for the right state first. + // Wait up to 50 ms, then check should_stop. + pollfd pfd; + pfd.fd = sock; + pfd.events = (state == SENDING_REQUEST) ? POLLOUT : POLLIN; + pfd.events |= POLLRDHUP; + + int nfds = poll(&pfd, 1, 50); + if (nfds == 0 || (nfds == -1 && errno == EINTR)) { continue; } + if (nfds == -1) { + log_perror("poll"); + state = CLOSING_SOCKET; + } } switch (state) { @@ -395,7 +377,15 @@ void HTTPInput::do_work() break; } case CLOSING_SOCKET: { - close_socket(); + int err; + do { + err = close(sock); + } while (err == -1 && errno == EINTR); + + if (err == -1) { + log_perror("close"); + } + state = NOT_CONNECTED; break; } @@ -406,12 +396,9 @@ void HTTPInput::do_work() // If we are still in NOT_CONNECTED, either something went wrong, // or the connection just got closed. // The earlier steps have already given the error message, if any. - if (state == NOT_CONNECTED && !should_stop()) { + if (state == NOT_CONNECTED && !should_stop) { log(INFO, "[%s] Waiting 0.2 second and restarting...", url.c_str()); - timespec timeout_ts; - timeout_ts.tv_sec = 0; - timeout_ts.tv_nsec = 200000000; - wait_for_wakeup(&timeout_ts); + usleep(200000); } } }