コード例 #1
0
ファイル: worker-connection.c プロジェクト: bdraco/core
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;
}
コード例 #2
0
ファイル: test_arrayqueue.c プロジェクト: willemt/arrayqueue
void TestarrayQueue_offerensure_ensures_capacity(
    CuTest * tc
    )
{
    char *item = "testitem";
    arrayqueue_t *qu = aqueue_new(1, 8);

    CuAssertTrue(tc, 0 == aqueue_offerensure(&qu, item));
    CuAssertTrue(tc, 1 == aqueue_count(qu));
    CuAssertTrue(tc, 1 == aqueue_size(qu));
    CuAssertTrue(tc, 0 == aqueue_offerensure(&qu, item));
    CuAssertTrue(tc, 2 == aqueue_count(qu));
    CuAssertTrue(tc, 2 == aqueue_size(qu));
    aqueue_free(qu);
}
コード例 #3
0
void ldap_connection_kill(struct ldap_connection *conn)
{
	if (conn->io != NULL)
		io_remove_closed(&(conn->io));
	if (conn->to_disconnect != NULL)
		timeout_remove(&(conn->to_disconnect));
	if (conn->to_reconnect != NULL)
		timeout_remove(&(conn->to_reconnect));
	if (conn->request_queue != NULL) {
		unsigned int n = aqueue_count(conn->request_queue);

		for (unsigned int i = 0; i < n; i++) {
			struct ldap_op_queue_entry *const *reqp =
				array_idx(&(conn->request_array),
					  aqueue_idx(conn->request_queue, i));
			if ((*reqp)->msgid > -1)
				ldap_abandon_ext(conn->conn, (*reqp)->msgid, NULL, NULL);
			(*reqp)->msgid = -1;
		}
	}
	if (conn->conn != NULL) {
		ldap_unbind_ext(conn->conn, NULL, NULL);
		ldap_memfree(conn->scred);
	}
	conn->conn = NULL;
	conn->state = LDAP_STATE_DISCONNECT;
}
コード例 #4
0
static
void ldap_connection_abort_request(struct ldap_op_queue_entry *req)
{
	struct ldap_result res;

	/* too bad */
	if (req->to_abort != NULL)
		timeout_remove(&req->to_abort);
	if (req->msgid > -1)
		ldap_abandon_ext(req->conn->conn, req->msgid, NULL, NULL);

	memset(&res, 0, sizeof(res));
	res.openldap_ret = LDAP_TIMEOUT;
	res.error_string = "Aborting LDAP request after timeout";
	if (req->result_callback != NULL)
		req->result_callback(&res, req->result_callback_ctx);

	unsigned int n = aqueue_count(req->conn->request_queue);
	for (unsigned int i = 0; i < n; i++) {
		struct ldap_op_queue_entry *const *reqp =
			array_idx(&(req->conn->request_array),
				  aqueue_idx(req->conn->request_queue, i));
		if (req == *reqp) {
			aqueue_delete(req->conn->request_queue, i);
			ldap_connection_request_destroy(&req);
			return;
		}
	}
	i_unreached();
}
コード例 #5
0
ファイル: worker-connection.c プロジェクト: bdraco/core
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);
}
コード例 #6
0
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);
	}
}
コード例 #7
0
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;
}
コード例 #8
0
static
void ldap_connection_send_next(struct ldap_connection *conn)
{
	unsigned int i = 0, n;
	struct ldap_op_queue_entry *req;

	if (conn->to_reconnect != NULL)
		timeout_remove(&(conn->to_reconnect));

	if (conn->state == LDAP_STATE_DISCONNECT) {
		if (ldap_connection_connect(conn) == -1)
			conn->to_reconnect = timeout_add(1000, ldap_connection_send_next, conn);
		return;
	}

	if (conn->state != LDAP_STATE_CONNECT) {
		return;
	}

	if (conn->pending > 10) return; /* try again later */

	req = NULL;
	/* get next request */
	n = aqueue_count(conn->request_queue);

	for(i=0; i < n; i++) {
		struct ldap_op_queue_entry *const *reqp =
			array_idx(&(conn->request_array),
				  aqueue_idx(conn->request_queue, i));
		if ((*reqp)->msgid > -1)
			break;
		req = *reqp;
	}

	i--;

	/* nothing to actually send */
	if (req == NULL) return;

	i_assert(req->msgid == -1);

	const char *error;
	int ret;
	if ((ret = req->send_request_cb(conn, req, &error)) != LDAP_SUCCESS) {
		/* did not succeed */
		struct ldap_result res;

		memset(&res, 0, sizeof(res));
		res.openldap_ret = ret;
		if (req->result_callback != NULL)
			req->result_callback(&res, req->result_callback_ctx);

		ldap_connection_request_destroy(&req);
		aqueue_delete(conn->request_queue, i);
	} else conn->pending++;
}
コード例 #9
0
ファイル: test_arrayqueue.c プロジェクト: willemt/arrayqueue
void TestarrayQueue_offer_adds_new_item(
    CuTest * tc
    )
{
    char *item = "testitem";
    void *qu = aqueue_new(10, 8);

    aqueue_offer(qu, item);
    CuAssertTrue(tc, 1 == aqueue_count(qu));
    aqueue_free(qu);
}
コード例 #10
0
ファイル: test_arrayqueue.c プロジェクト: willemt/arrayqueue
void TestarrayQueue_cannot_offer_over_capacity(
    CuTest * tc
    )
{
    char *item = "testitem";
    void *qu = aqueue_new(1, 8);

    aqueue_offer(qu, item);
    CuAssertTrue(tc, -1 == aqueue_offer(qu, item));
    CuAssertTrue(tc, 1 == aqueue_count(qu));
    aqueue_free(qu);
}
コード例 #11
0
ファイル: test_arrayqueue.c プロジェクト: willemt/arrayqueue
void TestarrayQueue_cant_poll_with_no_contents(
    CuTest * tc
    )
{
    char *item = "testitem";
    void *qu = aqueue_new(10, 8);
    aqueue_offer(qu, item);
    CuAssertTrue(tc, 0 == strncmp(item, aqueue_peek(qu), 8));
    CuAssertTrue(tc, 0 == aqueue_poll(qu));
    CuAssertTrue(tc, 0 == aqueue_count(qu));
    aqueue_free(qu);
}
コード例 #12
0
ファイル: test_arrayqueue.c プロジェクト: willemt/arrayqueue
void TestarrayQueue_empty_empties_queue(
    CuTest * tc
    )
{
    char *item = "testitem";
    void *qu = aqueue_new(10, 8);

    aqueue_offer(qu, item);
    aqueue_empty(qu);
    CuAssertTrue(tc, 0 == aqueue_count(qu));
    CuAssertTrue(tc, aqueue_is_empty(qu));
    aqueue_free(qu);
}
コード例 #13
0
ファイル: test-aqueue.c プロジェクト: bdraco/core
static const char *test_aqueue2(unsigned int initial_size)
{
	ARRAY(unsigned int) aqueue_array;
	unsigned int i, j, k;

	for (i = 0; i < N_ELEMENTS(aqueue_input); i++) {
		for (k = 0; k < N_ELEMENTS(aqueue_input); k++) {
			struct aqueue *aqueue;

			t_array_init(&aqueue_array, initial_size);
			aqueue = aqueue_init(&aqueue_array.arr);
			aqueue->head = aqueue->tail = initial_size - 1;
			for (j = 0; j < k; j++) {
				aqueue_append(aqueue, &aqueue_input[j]);
				if (aqueue_count(aqueue) != j + 1) {
					return t_strdup_printf("Wrong count after append %u vs %u)",
							       aqueue_count(aqueue), j + 1);
				}
				if (!aqueue_is_ok(aqueue, UINT_MAX))
					return "Invalid data after append";
			}

			if (k != 0 && i < k) {
				aqueue_delete(aqueue, i);
				if (aqueue_count(aqueue) != k - 1)
					return "Wrong count after delete";
				if (!aqueue_is_ok(aqueue, i))
					return "Invalid data after delete";
			}
			aqueue_clear(aqueue);
			if (aqueue_count(aqueue) != 0)
				return "aqueue_clear() broken";
			aqueue_deinit(&aqueue);
		}
	}
	return NULL;
}
コード例 #14
0
ファイル: test-aqueue.c プロジェクト: bdraco/core
static bool aqueue_is_ok(struct aqueue *aqueue, unsigned int deleted_n)
{
	const unsigned int *p;
	unsigned int n, i, count;

	count = aqueue_count(aqueue);
	for (i = 0, n = 1; i < count; i++, n++) {
		p = array_idx_i(aqueue->arr, aqueue_idx(aqueue, i));
		if (i == deleted_n)
			n++;
		if (*p != n)
			return FALSE;
	}
	return TRUE;
}
コード例 #15
0
static struct ldap_op_queue_entry *
ldap_connection_find_req_by_msgid(struct ldap_connection *conn, int msgid,
				  unsigned int *idx_r)
{
	unsigned int i, n = aqueue_count(conn->request_queue);
	for (i = 0; i < n; i++) {
		struct ldap_op_queue_entry *const *reqp =
			array_idx(&(conn->request_array),
				  aqueue_idx(conn->request_queue, i));
		if ((*reqp)->msgid == msgid) {
			*idx_r = i;
			return *reqp;
		}
	}
	return NULL;
}
コード例 #16
0
void ldap_connection_switch_ioloop(struct ldap_connection *conn)
{
	if (conn->io != NULL)
		conn->io = io_loop_move_io(&conn->io);
	if (conn->to_disconnect != NULL)
		conn->to_disconnect = io_loop_move_timeout(&conn->to_disconnect);
	if (conn->to_reconnect != NULL)
		conn->to_reconnect = io_loop_move_timeout(&conn->to_reconnect);
	unsigned int n = aqueue_count(conn->request_queue);

	for (unsigned int i = 0; i < n; i++) {
		struct ldap_op_queue_entry *const *reqp =
			array_idx(&(conn->request_array),
				  aqueue_idx(conn->request_queue, i));
		if ((*reqp)->to_abort != NULL)
			(*reqp)->to_abort = io_loop_move_timeout(&((*reqp)->to_abort));
	}
}
コード例 #17
0
void ldap_connection_deinit(struct ldap_connection **_conn)
{
	struct ldap_connection *conn = *_conn;

	*_conn = NULL;

	ldap_connection_kill(conn);

	unsigned int n = aqueue_count(conn->request_queue);
	for (unsigned int i = 0; i < n; i++) {
		struct ldap_op_queue_entry *const *reqp =
			array_idx(&(conn->request_array),
				  aqueue_idx(conn->request_queue, i));
		if ((*reqp)->to_abort != NULL)
			timeout_remove(&(*reqp)->to_abort);
	}
	pool_unref(&conn->pool);
}
コード例 #18
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;
}
コード例 #19
0
ファイル: aqueue.c プロジェクト: Distrotech/dovecot
void aqueue_delete(struct aqueue *aqueue, unsigned int n)
{
	unsigned int idx, count = aqueue_count(aqueue);

	i_assert(n < count);

	aqueue->full = FALSE;
	if (n == 0) {
		/* optimized deletion from tail */
		aqueue->tail = (aqueue->tail + 1) % aqueue->area_size;
		return;
	}
	if (n == count-1) {
		/* optimized deletion from head */
		aqueue->head = (aqueue->head + aqueue->area_size - 1) %
			aqueue->area_size;
		return;
	}

	idx = aqueue_idx(aqueue, n);
	if ((n < count/2 || idx > aqueue->head) && idx > aqueue->tail) {
		/* move tail forward.
		   ..tail##idx##head.. or ##head..tail##idx## */
		array_copy(aqueue->arr, aqueue->tail + 1,
			   aqueue->arr, aqueue->tail,
			   idx - aqueue->tail);
		aqueue->tail++;
		i_assert(aqueue->tail < aqueue->area_size);
	} else {
		/* move head backward.
		   ..tail##idx##head.. or ##idx##head..tail## */
		i_assert(idx < aqueue->head);
		array_copy(aqueue->arr, idx,
			   aqueue->arr, idx + 1,
			   aqueue->head - idx);
		aqueue->head = (aqueue->head + aqueue->area_size - 1) %
			aqueue->area_size;
	}
	i_assert(aqueue->head < aqueue->area_size &&
		 aqueue->head != aqueue->tail);
}
コード例 #20
0
static
void ldap_connection_abort_all_requests(struct ldap_connection *conn)
{
	struct ldap_result res;
	memset(&res, 0, sizeof(res));
	res.openldap_ret = LDAP_TIMEOUT;
	res.error_string = "Aborting LDAP requests due to failure";

	unsigned int n = aqueue_count(conn->request_queue);
	for (unsigned int i = 0; i < n; i++) {
		struct ldap_op_queue_entry **reqp =
			array_idx_modifiable(&(conn->request_array),
		aqueue_idx(conn->request_queue, i));
		if ((*reqp)->to_abort != NULL)
			timeout_remove(&(*reqp)->to_abort);
		if ((*reqp)->result_callback != NULL)
			(*reqp)->result_callback(&res, (*reqp)->result_callback_ctx);
		ldap_connection_request_destroy(reqp);
	}
	aqueue_clear(conn->request_queue);
}
コード例 #21
0
ファイル: duraqueue.c プロジェクト: ifzz/duraqueue
static int __load(dqueue_t* me)
{
    unsigned int pos = 0;

    while (pos < me->size)
    {
        int e, start_pos;
        header_t h;

        start_pos = pos;

        /* 1. read first header */
        e = read(me->fd, &h, sizeof(header_t));
        if (e < (int)sizeof(header_t))
            return -1;
        pos += sizeof(header_t);

        /* check header is ok */
        if (h.type != HEADER || 0 != memcmp(h.stamp, STAMP, strlen(STAMP)))
            continue;

        unsigned int check_id = h.id;

        /* 2. read 2nd header */
        /* put on sizeof(header_t) offset */
        size_t offset = sizeof(header_t) - ntohl(h.len) % sizeof(header_t);
        e = lseek(me->fd, ntohl(h.len) + offset, SEEK_CUR);
        pos += ntohl(h.len);

        e = read(me->fd, &h, sizeof(header_t));
        if (e < (int)sizeof(header_t))
        {
            perror("couldn't read file\n");
            return -1;
        }

        pos += __padding_required(ntohl(h.len));
        pos += sizeof(header_t);

        if (h.id != check_id || ntohl(h.type) != FOOTER || 0 !=
            memcmp(h.stamp, STAMP, strlen(STAMP)))
            continue;

        /* found a valid queue item */

        item_t item;
        item.pos = start_pos;
        item.len = ntohl(h.len);
        item.space_used = ntohl(h.len) + ITEM_METADATA_SIZE +
                           __padding_required(ntohl(h.len));
        item.id = h.id;
        aqueue_offerensure((void*)&me->items, &item);

        h.id = ntohl(h.id);
    }

    if (0 == aqueue_count(me->items))
        return 0;

    /* get lowest */
    unsigned int lowest_id = UINT_MAX;
    unsigned int highest_id = 0;
    arrayqueue_iter_t iter;
    for (aqueue_iter(me->items, &iter);
         aqueue_iter_has_next(me->items, &iter); )
    {
        item_t* item = aqueue_iter_next(me->items, &iter);
        if (item->id < lowest_id)
        {
            lowest_id = item->id;
            me->head = item->pos;
        }

        /* set tail */
        if (highest_id < item->id)
        {
            highest_id = item->id;
            me->tail = item->pos + item->len + ITEM_METADATA_SIZE +
                       __padding_required(item->len);
            me->item_id = item->id + 1;
        }
    }

    arrayqueue_t* stowaway = aqueue_new(16, sizeof(item_t));

    /* put lowest at front of queue */
    while (!aqueue_is_empty(me->items))
    {
        item_t* item = aqueue_peek(me->items);
        if (item->id == lowest_id)
            break;
        aqueue_offerensure(&stowaway, aqueue_peek(me->items));
        aqueue_poll(me->items);
    }

    /* empty out stowaway */
    while (!aqueue_is_empty(stowaway))
    {
        aqueue_offerensure((void*)&me->items, aqueue_peek(stowaway));
        aqueue_poll(stowaway);
    }

    aqueue_free(stowaway);

    return 0;
}
コード例 #22
0
ファイル: duraqueue.c プロジェクト: ifzz/duraqueue
int dqueue_is_empty(dqueue_t * me)
{
    return aqueue_count(me->items) == 0;
}
コード例 #23
0
ファイル: duraqueue.c プロジェクト: ifzz/duraqueue
unsigned int dqueue_count(dqueue_t* me)
{
    return aqueue_count(me->items);
}
コード例 #24
0
ファイル: worker-connection.c プロジェクト: bdraco/core
bool worker_connection_is_busy(struct worker_connection *conn)
{
	return aqueue_count(conn->request_queue) > 0;
}