Exemplo n.º 1
0
/**
 * Set up tracing to the given stdio stream
 *
 * We assume the stream is not ours, so we do not close it.
 */
static void
trace_to_stdio(FILE *stream)
{
    maybe_close();
    trace_stream = stream;
    trace_close = 0;
}
Exemplo n.º 2
0
/**
 * Set up tracing to the given file
 */
static void
trace_to_file(const char *fn)
{
    maybe_close();
    trace_stream = fopen(fn, "a");
    trace_close = 1;
}
Exemplo n.º 3
0
void Pool::close(bool cancel_reconnect) {
    if (state_ != POOL_STATE_CLOSING && state_ != POOL_STATE_CLOSED) {
        LOG_DEBUG("Closing pool(%p)", static_cast<void*>(this));

        connect_timer.stop();

        // We're closing before we've connected (likely because of an error), we need
        // to notify we're "ready"
        if (state_ == POOL_STATE_CONNECTING) {
            state_ = POOL_STATE_CLOSING;
            io_worker_->notify_pool_ready(this);
        } else {
            state_ = POOL_STATE_CLOSING;
        }

        set_is_available(false);
        cancel_reconnect_ = cancel_reconnect;

        for (ConnectionVec::iterator it = connections_.begin(),
                end = connections_.end();
                it != end; ++it) {
            (*it)->close();
        }
        for (ConnectionSet::iterator it = connections_pending_.begin(),
                end = connections_pending_.end();
                it != end; ++it) {
            (*it)->close();
        }
    }

    maybe_close();
}
Exemplo n.º 4
0
void Pool::on_close(Connection* connection) {
    connections_pending_.erase(connection);

    ConnectionVec::iterator it =
        std::find(connections_.begin(), connections_.end(), connection);
    if (it != connections_.end()) {
        connections_.erase(it);
        metrics_->total_connections.dec();
    }

    // For timeouts, if there are any valid connections left then don't close the
    // entire pool, but attempt to reconnect the timed out connections.
    if (connection->is_timeout_error() && !connections_.empty()) {
        if (!connect_timer.is_running()) {
            connect_timer.start(loop_,
                                config_.reconnect_wait_time_ms(),
                                this, on_partial_reconnect);
        }
        maybe_notify_ready();
    } else if (connection->is_defunct()) {
        // If at least one connection has a critical failure then don't try to
        // reconnect automatically.
        if (connection->is_critical_failure()) {
            is_critical_failure_ = true;
        }
        close();
    } else {
        maybe_notify_ready();
        maybe_close();
    }
}
cops_return_code_t
cops_tapp_invoke(struct cops_state *state, cops_tapp_io_t **tapp_io,
                 cops_taf_id_t taf_id)
{
    cops_return_code_t ret_code = COPS_RC_OK;
    int       readfd = -1;
    int       writefd = -1;
    pid_t     pid = -1;
    uint32_t  hdr[2];
    size_t    l;
    uint8_t  *p;
    ssize_t   res;

    (void) state;

    COPS_CHK_RC(cops_tapp_fork_and_exec_service(taf_id, &readfd, &writefd,
                &pid));
    (*tapp_io)->args.data = NULL;
    (*tapp_io)->data.data = NULL;
    (*tapp_io)->rvs.data = NULL;
    (*tapp_io)->perm_auth_state_data.data = NULL;

    p = (uint8_t *)*tapp_io;
    l = sizeof(cops_tapp_io_t) + (*tapp_io)->args.max_length +
        (*tapp_io)->data.max_length + (*tapp_io)->rvs.max_length +
        (*tapp_io)->perm_auth_state_data.max_length;

    hdr[0] = taf_id;
    hdr[1] = l;

wagain1:
    res = write(writefd, hdr, sizeof(hdr));

    if (res != sizeof(hdr)) {
        if (res == -1) {
            if (errno == EINTR) {
                goto wagain1;
            }

            COPS_SET_RC(COPS_RC_SERVICE_ERROR, "write(%d, x, %zu): %s",
                        writefd, sizeof(hdr), strerror(errno));
        } else {
            COPS_SET_RC(COPS_RC_SERVICE_ERROR, "write(%d, x, %zu): Short write",
                        writefd, sizeof(hdr));
        }
    }

    while (l > 0) {
        res = write(writefd, p, l);

        if (res == -1) {
            if (errno == EINTR) {
                continue;
            }

            COPS_SET_RC(COPS_RC_SERVICE_ERROR, "write(%d, x, %d): %s",
                        writefd, (int)l, strerror(errno));
        }

        l -= res;
        p += res;
    }

    p = (uint8_t *)*tapp_io;
    l = sizeof(cops_tapp_io_t) + (*tapp_io)->args.max_length +
        (*tapp_io)->data.max_length + (*tapp_io)->rvs.max_length +
        (*tapp_io)->perm_auth_state_data.max_length;

ragain1:
    res = read(readfd, hdr, sizeof(hdr));

    if (res == -1) {
        if (errno == EINTR) {
            goto ragain1;
        }

        COPS_SET_RC(COPS_RC_SERVICE_ERROR, "read(%d, x, %zu): %s",
                    readfd, sizeof(hdr), strerror(errno));
    }

    if (res == 0) {
        COPS_SET_RC(COPS_RC_SERVICE_ERROR,
                    "read(%d, x, %zu): Got end of file.\n",
                    readfd, sizeof(hdr));
    }

    if (taf_id != hdr[0]) {
        COPS_SET_RC(COPS_RC_SERVICE_ERROR,
                    "Got response from wrong service %d (expected %d)",
                    hdr[0], taf_id);
    }

    if (l != hdr[1]) {
        COPS_SET_RC(COPS_RC_SERVICE_ERROR,
                    "Got wrong size of respone %d (expected %zu)", hdr[1], l);
    }

    while (l > 0) {
        res = read(readfd, p, l);

        if (res == -1) {
            if (errno == EINTR) {
                continue;
            }

            COPS_SET_RC(COPS_RC_SERVICE_ERROR,
                        "read(%d, x, %zu): %s", readfd, l, strerror(errno));
        }

        if (res == 0) {
            COPS_SET_RC(COPS_RC_SERVICE_ERROR,
                        "read(%d, x, %zu): Got end of file ",
                        readfd, sizeof(hdr));
        }

        l -= res;
        p += res;
    }

    /* Restore pointers in tapp_io */
    p = (uint8_t *)*tapp_io;
    p += sizeof(cops_tapp_io_t);

    (*tapp_io)->args.data = p;
    p += (*tapp_io)->args.max_length;

    (*tapp_io)->data.data = p;
    p += (*tapp_io)->data.max_length;

    (*tapp_io)->rvs.data = p;
    p += (*tapp_io)->rvs.max_length;

    (*tapp_io)->perm_auth_state_data.data = p;

    cops_debug_print_error_stack(&(*tapp_io)->rvs);

function_exit:

    /*
     * Restore pointers in tapp_io (we need to do it again in case we
     * goto:ed to function_exit:
     */
    p = (uint8_t *)*tapp_io;
    p += sizeof(cops_tapp_io_t);

    (*tapp_io)->args.data = p;
    p += (*tapp_io)->args.max_length;

    (*tapp_io)->data.data = p;
    p += (*tapp_io)->data.max_length;

    (*tapp_io)->rvs.data = p;
    p += (*tapp_io)->rvs.max_length;

    (*tapp_io)->perm_auth_state_data.data = p;

    if (pid != -1 && pid != 0) {
        if (kill(pid, SIGKILL) == -1)
            COPS_LOG(LOG_ERROR, "kill(%d /*child service*/, SIGKILL): %s\n",
                     pid, strerror(errno));
        else {
            wait(NULL);
        }
    }

    maybe_close(&readfd);
    maybe_close(&writefd);
    return ret_code;
}
static cops_return_code_t
cops_tapp_fork_and_exec_service(cops_taf_id_t taf_id,
                                int *readfd, int *writefd, pid_t *pid)
{
    cops_return_code_t ret_code = COPS_RC_OK;
    int       stdin_fds[2] = { -1, -1 };
    int       stdout_fds[2] = { -1, -1 };

    if (pipe(stdin_fds) == -1 || pipe(stdout_fds) == -1) {
        COPS_SET_RC(COPS_RC_SERVICE_NOT_AVAILABLE_ERROR,
                    "pipe: %s", strerror(errno));
    }

    *pid = fork();

    if (*pid == -1) {
        COPS_SET_RC(COPS_RC_SERVICE_NOT_AVAILABLE_ERROR,
                    "fork: %s", strerror(errno));
    }

    if (*pid == 0) {            /* Child */
        char      taf_str[4];
        int       stdinfd = stdin_fds[0];
        int       stdoutfd = stdout_fds[1];

        maybe_close(&stdin_fds[1]);
        maybe_close(&stdout_fds[0]);

        if (dup2(stdinfd, STDIN_FILENO) == -1 ||
                dup2(stdoutfd, STDOUT_FILENO) == -1) {

            COPS_LOG(LOG_ERROR, "dup2: %s\n", strerror(errno));
            exit(1);
        }

        if (stdinfd != STDIN_FILENO) {
            close(stdinfd);
        }

        if (stdoutfd != STDOUT_FILENO) {
            close(stdoutfd);
        }

        snprintf(taf_str, sizeof(taf_str), "%d", taf_id);

        /* only returns on error */
        execlp(COPS_TAPP_TEST_PATH "tapp_test", "tapp_test", taf_str, NULL);

        COPS_LOG(LOG_ERROR, "execlp(\"%s\"): %s\n",
                 COPS_TAPP_TEST_PATH "tapp_test", strerror(errno));
        exit(1);
    }

    *readfd = stdout_fds[0];
    stdout_fds[0] = -1;
    *writefd = stdin_fds[1];
    stdin_fds[1] = -1;

function_exit:
    /* Parent */
    maybe_close(&stdout_fds[0]);
    maybe_close(&stdout_fds[1]);
    maybe_close(&stdin_fds[0]);
    maybe_close(&stdin_fds[1]);
    return ret_code;
}
Exemplo n.º 7
0
void IOWorker::request_finished(RequestHandler* request_handler) {
  pending_request_count_--;
  maybe_close();
  request_queue_.send();
}