Beispiel #1
0
void test_queue_peek_head(void)
{
	Queue *queue;

	/* Check peeking into an empty queue */

	queue = queue_new();

	assert(queue_peek_head(queue) == NULL);

	queue_free(queue);

	/* Pop off all the values from the queue, making sure that peek
	 * has the correct value beforehand */

	queue = generate_queue();

	while (!queue_is_empty(queue)) {
		assert(queue_peek_head(queue) == &variable4);
		assert(queue_pop_head(queue) == &variable4);
		assert(queue_peek_head(queue) == &variable3);
		assert(queue_pop_head(queue) == &variable3);
		assert(queue_peek_head(queue) == &variable2);
		assert(queue_pop_head(queue) == &variable2);
		assert(queue_peek_head(queue) == &variable1);
		assert(queue_pop_head(queue) == &variable1);
	}

	assert(queue_peek_head(queue) == NULL);

	queue_free(queue);
}
Beispiel #2
0
static struct att_send_op *pick_next_send_op(struct bt_att *att)
{
	struct att_send_op *op;

	/* See if any operations are already in the write queue */
	op = queue_pop_head(att->write_queue);
	if (op)
		return op;

	/* If there is no pending request, pick an operation from the
	 * request queue.
	 */
	if (!att->pending_req) {
		op = queue_pop_head(att->req_queue);
		if (op)
			return op;
	}

	/* There is either a request pending or no requests queued. If there is
	 * no pending indication, pick an operation from the indication queue.
	 */
	if (!att->pending_ind) {
		op = queue_pop_head(att->ind_queue);
		if (op)
			return op;
	}

	return NULL;
}
Beispiel #3
0
static void process_read_by_type(struct async_read_op *op)
{
	struct bt_gatt_server *server = op->server;
	uint8_t ecode;
	struct gatt_db_attribute *attr;

	attr = queue_pop_head(op->db_data);

	if (op->done || !attr) {
		bt_att_send(server->att, BT_ATT_OP_READ_BY_TYPE_RSP, op->pdu,
								op->pdu_len,
								NULL, NULL,
								NULL);
		async_read_op_destroy(op);
		return;
	}

	ecode = check_permissions(server, attr, BT_ATT_PERM_READ |
						BT_ATT_PERM_READ_AUTHEN |
						BT_ATT_PERM_READ_ENCRYPT);
	if (ecode)
		goto error;

	if (gatt_db_attribute_read(attr, 0, op->opcode, server->att,
					read_by_type_read_complete_cb, op))
		return;

	ecode = BT_ATT_ERROR_UNLIKELY;

error:
	bt_att_send_error_rsp(server->att, BT_ATT_OP_READ_BY_TYPE_REQ,
				gatt_db_attribute_get_handle(attr), ecode);
	async_read_op_destroy(op);
}
Beispiel #4
0
/* Drop a packet from the longest queue in 'rl'. */
static void
drop_packet(struct rate_limiter *rl)
{
    struct ofp_queue *longest;  /* Queue currently selected as longest. */
    int n_longest;              /* # of queues of same length as 'longest'. */
    struct ofp_queue *q;

    longest = &rl->queues[0];
    n_longest = 1;
    for (q = &rl->queues[0]; q < &rl->queues[OFPP_MAX]; q++) {
        if (longest->n < q->n) {
            longest = q;
            n_longest = 1;
        } else if (longest->n == q->n) {
            n_longest++;

            /* Randomly select one of the longest queues, with a uniform
             * distribution (Knuth algorithm 3.4.2R). */
            if (!random_range(n_longest)) {
                longest = q;
            }
        }
    }

    /* FIXME: do we want to pop the tail instead? */
    ofpbuf_delete(queue_pop_head(longest));
    rl->n_queued--;
}
Beispiel #5
0
void *queue_remove(struct queue *queue, void *data)
{
    struct list *entry;

    if ( !queue->head ) return NULL;

    entry = list_find(queue->head, data);
    if ( NULL == entry ) {
        // We didnt find this entry
        return NULL;
    }

    // This entry is there in the list
    if ( queue->head == entry ) {
        // This is the first node
        data = queue_pop_head(queue);
        return data;
    } else if ( queue->tail == entry ) {
        // This is the tail node
        data = queue_pop_tail(queue);
        return data;
    }

    // This is and arbitary location, between head and tail
	queue->length--;
    __list_remove(entry, entry);
    __list_free(entry);

    return data;
}
Beispiel #6
0
void test_queue_is_empty(void)
{
	Queue *queue;

	queue = queue_new();

	assert(queue_is_empty(queue));

	queue_push_head(queue, &variable1);

	assert(!queue_is_empty(queue));

	queue_pop_head(queue);

	assert(queue_is_empty(queue));

	queue_push_tail(queue, &variable1);

	assert(!queue_is_empty(queue));

	queue_pop_tail(queue);

	assert(queue_is_empty(queue));

	queue_free(queue);
}
Beispiel #7
0
static bool encode_read_by_grp_type_rsp(struct gatt_db *db, struct queue *q,
						struct bt_att *att,
						uint16_t mtu, uint8_t *pdu,
						uint16_t *len)
{
	int iter = 0;
	uint16_t start_handle, end_handle;
	struct iovec value;
	uint8_t data_val_len;

	*len = 0;

	while (queue_peek_head(q)) {
		struct gatt_db_attribute *attrib = queue_pop_head(q);

		value.iov_base = NULL;
		value.iov_len = 0;

		/*
		 * This should never be deferred to the read callback for
		 * primary/secondary service declarations.
		 */
		if (!gatt_db_attribute_read(attrib, 0,
						BT_ATT_OP_READ_BY_GRP_TYPE_REQ,
						att, attribute_read_cb,
						&value) || !value.iov_len)
			return false;

		/*
		 * Use the first attribute to determine the length of each
		 * attribute data unit. Stop the list when a different attribute
		 * value is seen.
		 */
		if (iter == 0) {
			data_val_len = MIN(MIN((unsigned)mtu - 6, 251),
								value.iov_len);
			pdu[0] = data_val_len + 4;
			iter++;
		} else if (value.iov_len != data_val_len)
			break;

		/* Stop if this unit would surpass the MTU */
		if (iter + data_val_len + 4 > mtu - 1)
			break;

		gatt_db_attribute_get_service_handles(attrib, &start_handle,
								&end_handle);

		put_le16(start_handle, pdu + iter);
		put_le16(end_handle, pdu + iter + 2);
		memcpy(pdu + iter + 4, value.iov_base, data_val_len);

		iter += data_val_len + 4;
	}

	*len = iter;

	return true;
}
Beispiel #8
0
void test_queue_push_head(void)
{
	Queue *queue;
	int i;

	queue = queue_new();

	/* Add some values */

	for (i=0; i<1000; ++i) {
		queue_push_head(queue, &variable1);
		queue_push_head(queue, &variable2);
		queue_push_head(queue, &variable3);
		queue_push_head(queue, &variable4);
	}

	assert(!queue_is_empty(queue));

	/* Check values come out of the tail properly */

	assert(queue_pop_tail(queue) == &variable1);
	assert(queue_pop_tail(queue) == &variable2);
	assert(queue_pop_tail(queue) == &variable3);
	assert(queue_pop_tail(queue) == &variable4);

	/* Check values come back out of the head properly */

	assert(queue_pop_head(queue) == &variable4);
	assert(queue_pop_head(queue) == &variable3);
	assert(queue_pop_head(queue) == &variable2);
	assert(queue_pop_head(queue) == &variable1);

	queue_free(queue);

	/* Test behavior when running out of memory. */

	queue = queue_new();

	alloc_test_set_limit(0);
	assert(!queue_push_head(queue, &variable1));

	queue_free(queue);
}
Beispiel #9
0
/*get picture from vo_queue,remove*/
AVPicture_t *dtvideo_output_read (void *priv)
{
    dtvideo_context_t *vctx = (dtvideo_context_t *) priv;
    queue_t *picture_queue = vctx->vo_queue;
    if (picture_queue->length == 0)
    {
        return NULL;
    }
    return queue_pop_head (picture_queue);
}
Beispiel #10
0
void queue_free (Queue* queue) {
  /* Empty the queue */

  while (!queue_is_empty (queue)) {
    queue_pop_head (queue);
    }

  /* Free back the queue */

  free (queue);
  }
Beispiel #11
0
static bool encode_find_info_rsp(struct gatt_db *db, struct queue *q,
						uint16_t mtu,
						uint8_t *pdu, uint16_t *len)
{
	uint16_t handle;
	struct gatt_db_attribute *attr;
	const bt_uuid_t *type;
	int uuid_len, cur_uuid_len;
	int iter = 0;

	*len = 0;

	while (queue_peek_head(q)) {
		attr = queue_pop_head(q);
		handle = gatt_db_attribute_get_handle(attr);
		type = gatt_db_attribute_get_type(attr);
		if (!handle || !type)
			return false;

		cur_uuid_len = bt_uuid_len(type);

		if (iter == 0) {
			switch (cur_uuid_len) {
			case 2:
				uuid_len = 2;
				pdu[0] = 0x01;
				break;
			case 4:
			case 16:
				uuid_len = 16;
				pdu[0] = 0x02;
				break;
			default:
				return false;
			}

			iter++;
		} else if (cur_uuid_len != uuid_len)
			break;

		if (iter + uuid_len + 2 > mtu - 1)
			break;

		put_le16(handle, pdu + iter);
		bt_uuid_to_le(type, pdu + iter + 2);

		iter += uuid_len + 2;
	}

	*len = iter;

	return true;
}
Beispiel #12
0
void test_queue_pop_head(void)
{
	Queue *queue;

	/* Check popping off an empty queue */

	queue = queue_new();

	assert(queue_pop_head(queue) == NULL);

	queue_free(queue);

	/* Pop off all the values from the queue */

	queue = generate_queue();

	while (!queue_is_empty(queue)) {
		assert(queue_pop_head(queue) == &variable4);
		assert(queue_pop_head(queue) == &variable3);
		assert(queue_pop_head(queue) == &variable2);
		assert(queue_pop_head(queue) == &variable1);
	}

	assert(queue_pop_head(queue) == NULL);

	queue_free(queue);
}
static bool can_write_data(struct io *io, void *user_data)
{
	struct mgmt *mgmt = user_data;
	struct mgmt_request *request;
	ssize_t bytes_written;

	request = queue_pop_head(mgmt->reply_queue);
	if (!request) {
		/* only reply commands can jump the queue */
		if (!queue_isempty(mgmt->pending_list))
			return false;

		request = queue_pop_head(mgmt->request_queue);
		if (!request)
			return false;
	}

	bytes_written = write(mgmt->fd, request->buf, request->len);
	if (bytes_written < 0) {
		util_debug(mgmt->debug_callback, mgmt->debug_data,
				"write failed: %s", strerror(errno));
		if (request->callback)
			request->callback(MGMT_STATUS_FAILED, 0, NULL,
							request->user_data);
		destroy_request(request);
		return true;
	}

	util_debug(mgmt->debug_callback, mgmt->debug_data,
				"[0x%04x] command 0x%04x",
				request->index, request->opcode);

	util_hexdump('<', request->buf, bytes_written,
				mgmt->debug_callback, mgmt->debug_data);

	queue_push_tail(mgmt->pending_list, request);

	return false;
}
static bool io_write_callback(struct io *io, void *user_data)
{
	struct bt_hci *hci = user_data;
	struct cmd *cmd;

	cmd = queue_pop_head(hci->cmd_queue);
	if (cmd) {
		send_command(hci, cmd->opcode, cmd->data, cmd->size);
		queue_push_tail(hci->rsp_queue, cmd);
	}

	hci->writer_active = false;

	return false;
}
Beispiel #15
0
/* Remove and return the next packet to transmit (in round-robin order). */
static struct ofpbuf *
dequeue_packet(struct rate_limiter *rl)
{
    unsigned int i;

    for (i = 0; i < OFPP_MAX; i++) {
        unsigned int port = (rl->next_tx_port + i) % OFPP_MAX;
        struct ofp_queue *q = &rl->queues[port];
        if (q->n) {
            rl->next_tx_port = (port + 1) % OFPP_MAX;
            rl->n_queued--;
            return queue_pop_head(q);
        }
    }
    NOT_REACHED();
}
Beispiel #16
0
static void exec_next_prep_write(struct bt_gatt_server *server,
						uint16_t ehandle, int err)
{
	struct prep_write_data *next = NULL;
	struct gatt_db_attribute *attr;
	bool status;

	if (err)
		goto error;

	next = queue_pop_head(server->prep_queue);
	if (!next) {
		bt_att_send(server->att, BT_ATT_OP_EXEC_WRITE_RSP, NULL, 0,
							NULL, NULL, NULL);
		return;
	}

	attr = gatt_db_get_attribute(server->db, next->handle);
	if (!attr) {
		err = BT_ATT_ERROR_UNLIKELY;
		goto error;
	}

	status = gatt_db_attribute_write(attr, next->offset,
						next->value, next->length,
						BT_ATT_OP_EXEC_WRITE_REQ,
						server->att,
						exec_write_complete_cb, server);

	prep_write_data_destroy(next);

	if (status)
		return;

	err = BT_ATT_ERROR_UNLIKELY;

error:
	queue_remove_all(server->prep_queue, NULL, NULL,
						prep_write_data_destroy);

	bt_att_send_error_rsp(server->att, BT_ATT_OP_EXEC_WRITE_REQ,
								ehandle, err);
}
Beispiel #17
0
static void process_read_by_type(struct async_read_op *op)
{
	struct bt_gatt_server *server = op->server;
	uint8_t ecode;
	struct gatt_db_attribute *attr;
	uint32_t perm;

	attr = queue_pop_head(op->db_data);

	if (op->done || !attr) {
		bt_att_send(server->att, BT_ATT_OP_READ_BY_TYPE_RSP, op->pdu,
								op->pdu_len,
								NULL, NULL,
								NULL);
		async_read_op_destroy(op);
		return;
	}

	perm = gatt_db_attribute_get_permissions(attr);

	/*
	 * Check for the READ access permission. Encryption,
	 * authentication, and authorization permissions need to be
	 * checked by the read handler, since bt_att is agnostic to
	 * connection type and doesn't have security information on it.
	 */
	if (perm && !(perm & BT_ATT_PERM_READ)) {
		ecode = BT_ATT_ERROR_READ_NOT_PERMITTED;
		goto error;
	}

	if (gatt_db_attribute_read(attr, 0, op->opcode, server->att,
					read_by_type_read_complete_cb, op))
		return;

	ecode = BT_ATT_ERROR_UNLIKELY;

error:
	bt_att_send_error_rsp(server->att, BT_ATT_OP_READ_BY_TYPE_REQ,
				gatt_db_attribute_get_handle(attr), ecode);
	async_read_op_destroy(op);
}
Beispiel #18
0
static void
end_element(
    void *ud,
    const xmlChar *xname)
{
    char *name = (char*)xname;
    parse_data_t *pd = (parse_data_t*)ud;
    int id;
    union
    {
        int id;
        void * pid;
    } start_id;
    int ii;

    // Check to see if the first element found has been closed
    // If so, ignore any junk following it.
    if (pd->closed_top)
        return;

    for (ii = 0; ii < TAG_MAP_SZ; ii++)
    {
        if (strcmp(name, tag_map[ii].tag) == 0)
        {
            id = tag_map[ii].id;
            break;
        }
    }
    if (ii == TAG_MAP_SZ)
    {
        hb_error("Unrecognized start tag (%s)", name);
        return;
    }
    start_id.pid = queue_pop_head(pd->tag_stack);
    if (start_id.id != id)
        hb_error("start tag != end tag: (%s %d) %d", name, id, id);

    hb_value_t *gval = NULL;
    hb_value_t *current = queue_peek_head(pd->stack);
    hb_value_type_t gtype = 0;
    const char *value;
    if (pd->value != NULL)
        value = pd->value;
    else
        value = "";
    switch (id)
    {
        case P_PLIST:
        { // Ignore
        } break;
        case P_KEY:
        {
            if (pd->key) free(pd->key);
            pd->key = strdup(value);
            return;
        } break;
        case P_DICT:
        {
            queue_pop_head(pd->stack);
        } break;
        case P_ARRAY:
        {
            queue_pop_head(pd->stack);
        } break;
        case P_INTEGER:
        {
            uint64_t val = strtoll(value, NULL, 0);
            gval = hb_value_int(val);
        } break;
        case P_REAL:
        {
            double val = strtod(value, NULL);
            gval = hb_value_double(val);
        } break;
        case P_STRING:
        {
            gval = hb_value_string(value);
        } break;
        case P_TRUE:
        {
            gval = hb_value_bool(1);
        } break;
        case P_FALSE:
        {
            gval = hb_value_bool(0);
        } break;
        default:
        {
            hb_error("Unhandled plist type %d", id);
        } break;
    }
    if (gval)
    {
        // Get the top of the data structure stack and if it's an array
        // or dict, add the current element
        if (current == NULL)
        {
            pd->plist = gval;
            pd->closed_top = 1;
            return;
        }
        gtype = hb_value_type(current);
        if (gtype == HB_VALUE_TYPE_ARRAY)
        {
            hb_value_array_append(current, gval);
        }
        else if (gtype == HB_VALUE_TYPE_DICT)
        {
            if (pd->key == NULL)
            {
                hb_error("No key for dictionary item");
                hb_value_free(&gval);
            }
            else
            {
                hb_dict_set(current, pd->key, gval);
            }
        }
        else
        {
            hb_error("Invalid container type. This shouldn't happen");
        }
    }
    if (queue_is_empty(pd->stack))
        pd->closed_top = 1;
}