static bool proxy_client_worker_next_reply(struct proxy_client_dsync_worker *worker, const char *line) { const struct proxy_client_request *requests; struct proxy_client_request request; bool ret = TRUE; i_assert(worker->msg_get_data.input == NULL); if (aqueue_count(worker->request_queue) == 0) { i_error("Unexpected reply from server: %s", line); proxy_client_fail(worker); return FALSE; } requests = array_idx(&worker->request_array, 0); request = requests[aqueue_idx(worker->request_queue, 0)]; aqueue_delete_tail(worker->request_queue); switch (request.type) { case PROXY_CLIENT_REQUEST_TYPE_COPY: ret = proxy_client_worker_next_copy(worker, &request, line); break; case PROXY_CLIENT_REQUEST_TYPE_GET: ret = proxy_client_worker_next_msg_get(worker, &request, line); break; case PROXY_CLIENT_REQUEST_TYPE_FINISH: proxy_client_worker_next_finish(worker, &request, line); break; } return ret; }
static void worker_connection_disconnect(struct worker_connection *conn) { unsigned int i, count = aqueue_count(conn->request_queue); if (conn->fd != -1) { io_remove(&conn->io); i_stream_destroy(&conn->input); o_stream_destroy(&conn->output); if (close(conn->fd) < 0) i_error("close(%s) failed: %m", conn->socket_path); conn->fd = -1; } /* cancel any pending requests */ if (count > 0) { i_error("Indexer worker disconnected, " "discarding %u requests for %s", count, conn->request_username); } /* conn->callback() can try to destroy us */ conn->refcount++; for (i = 0; i < count; i++) { void *const *contextp = array_idx(&conn->request_contexts, aqueue_idx(conn->request_queue, 0)); void *context = *contextp; aqueue_delete_tail(conn->request_queue); conn->callback(-1, context); } i_free_and_null(conn->request_username); worker_connection_unref(conn); }
void auth_request_handler_flush_failures(bool flush_all) { struct auth_request **auth_requests, *auth_request; unsigned int i, count; time_t diff; count = aqueue_count(auth_failures); if (count == 0) { if (to_auth_failures != NULL) timeout_remove(&to_auth_failures); return; } auth_requests = array_idx_modifiable(&auth_failures_arr, 0); for (i = 0; i < count; i++) { auth_request = auth_requests[aqueue_idx(auth_failures, 0)]; /* FIXME: assumess that failure_delay is always the same. */ diff = ioloop_time - auth_request->last_access; if (diff < (time_t)auth_request->set->failure_delay && !flush_all) break; aqueue_delete_tail(auth_failures); i_assert(auth_request->state == AUTH_REQUEST_STATE_FINISHED); auth_request_handler_reply(auth_request, AUTH_CLIENT_RESULT_FAILURE, &uchar_nul, 0); auth_request_unref(&auth_request); } }
static int worker_connection_input_line(struct worker_connection *conn, const char *line) { void *const *contextp, *context; int percentage; if (aqueue_count(conn->request_queue) == 0) { i_error("Input from worker without pending requests: %s", line); return -1; } if (str_to_int(line, &percentage) < 0 || percentage < -1 || percentage > 100) { i_error("Invalid input from worker: %s", line); return -1; } contextp = array_idx(&conn->request_contexts, aqueue_idx(conn->request_queue, 0)); context = *contextp; if (percentage < 0 || percentage == 100) { /* the request is finished */ aqueue_delete_tail(conn->request_queue); if (aqueue_count(conn->request_queue) == 0) i_free_and_null(conn->request_username); } conn->callback(percentage, context); return 0; }
static bool dsync_mailbox_tree_bfs_iter_next(struct dsync_mailbox_tree_bfs_iter *iter, struct dsync_mailbox_node **node_r) { struct dsync_mailbox_node *const *nodep; if (iter->cur == NULL) { if (aqueue_count(iter->queue) == 0) return FALSE; nodep = array_idx(&iter->queue_arr, aqueue_idx(iter->queue, 0)); iter->cur = *nodep; aqueue_delete_tail(iter->queue); } *node_r = iter->cur; if (iter->cur->first_child != NULL) aqueue_append(iter->queue, &iter->cur->first_child); iter->cur = iter->cur->next; return TRUE; }