Exemplo n.º 1
0
int main(int argc, char** argv) {
  cbuf *cb1 = cbuf_alloc();

  // make sure the cbuf grows and shrinks appropriately
  int capacity = cbuf_capacity(cb1);
  check(capacity > 0, "Initial capacity > 0");
  check(cbuf_size(cb1) == 0, "Initial size == 0");

  for(int i = 0; i < capacity; i++) {
    cbuf_update(cb1, 60, 1.291);
  }

  check(cbuf_size(cb1) == cbuf_capacity(cb1), "Size is allowed to grow to capacity");

  cbuf_update(cb1, 60, 1.291);

  // inserting one more than what the original structure could contain
  int new_capacity = cbuf_capacity(cb1);
  check(new_capacity > capacity, "Capacity grows when necessary");

  // inserting an update that's > 5 minutes older than all of the data
  // in the structure
  cbuf_update(cb1, 60 + 6 * 60, 1.291);
  check(cbuf_capacity(cb1) < new_capacity, "Capacity shrinks when able");
  check(cbuf_size(cb1) == 1, "Aged out records are removed correctly");

  cbuf_free(cb1);

  return 0;
}
Exemplo n.º 2
0
Arquivo: util.c Projeto: TUM-LIS/glip
/**
 * Blocking read from a cbuf
 *
 * This function is compatible to the glip_read_b() function and can be used in
 * backend implementations using a cbuf for storing incoming data.
 *
 * @param[in]  buf the buffer to read from
 * @param[in]  size how much data is supposed to be read
 * @param[out] data the read data
 * @param[out] size_read how much data has been read
 * @param[in]  timeout the maximum duration the read operation can take
 *
 * @return 0 if reading was successful
 * @return -ETIMEDOUT if the read timeout was hit
 * @return -ECANCELED if the blocking operation was cancelled
 * @return any other value indicates failure
 *
 * @see glip_read_b()
 */
int gb_util_cbuf_read_b(struct cbuf *buf, size_t size, uint8_t *data,
                        size_t *size_read, unsigned int timeout)
{
    int rv;
    int retval = 0;
    struct timespec ts;

    *size_read = 0;

    if (size > cbuf_size(buf)) {
        /*
         * This is not a problem for non-blocking reads, but blocking reads will
         * block forever in this case as the maximum amount of data ever
         * available is limited by the buffer size.
         * @todo: This can be solved by loop-reading until timeout
         */
        return -1;
    }

    /*
     * Wait until sufficient data is available to be read.
     */
    if (timeout != 0) {
        clock_gettime(CLOCK_REALTIME, &ts);
        timespec_add_ns(&ts, timeout * 1000 * 1000);
    }

    size_t level = cbuf_fill_level(buf);

    while (level < size) {
        if (timeout == 0) {
            rv = cbuf_wait_for_level_change(buf, level);
        } else {
            rv = cbuf_timedwait_for_level_change(buf, level, &ts);
        }

        retval = rv;
        if (rv == -ETIMEDOUT) {
            goto read_ret;
        } else if (rv != 0) {
            goto ret;
        }

        level = cbuf_fill_level(buf);
    }

    /*
     * We read whatever data is available, and assume a timeout if the available
     * amount of data does not match the requested amount.
     */
read_ret:
    rv = gb_util_cbuf_read(buf, size, data, size_read);
    if (rv == 0 && size != *size_read) {
        retval = -ETIMEDOUT;
    }

ret:
    return retval;
}
Exemplo n.º 3
0
/**
 * Send a status message back to the user who issued the !history command.
 */
static int command_status(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd, struct cbuffer* buf)
{
	struct cbuffer* msg = cbuf_create(cbuf_size(buf) + strlen(cmd->prefix) + 8);
	cbuf_append_format(msg, "*** %s: %s", cmd->prefix, cbuf_get(buf));
	plugin->hub.send_message(plugin, user, cbuf_get(msg));
	cbuf_destroy(msg);
	cbuf_destroy(buf);
	return 0;
}
Exemplo n.º 4
0
Arquivo: eyed.c Projeto: texane/eyed
static cio_err_t on_client_write(cio_handle_t* h, cio_dispatcher_t* d, void* p)
{
  int count;

  DEBUG_ENTER();

  count = send(h->fd, h->buf_out.data, cbuf_size(&h->buf_out), 0);
  if (count <= 0)
    return CIO_ERR_CLOSE;

  cbuf_pop_front(&h->buf_out, count);

  return CIO_ERR_SUCCESS;
}
Exemplo n.º 5
0
Arquivo: devices.c Projeto: wwjnc/zeos
int sys_read_console(char* buffer, int size)
{
	if (!list_empty(&keyboardqueue) || keyboard_serving_read)
		block_current_task(&keyboardqueue, BLOCK_AT_END);
	
	keyboard_serving_read = 1;

	// 1) If we can satisfy the read(), copy the needed bytes and return
	// 2) If we can't and the buffer is full, copy the entire input buffer and block
	// 3) Otherwise, block
	int* remaining_bytes = &keyboard_req_bytes[task_struct_to_task_index(current())];
	*remaining_bytes = size;

	for (;;)
	{
		// Copy bytes from the keyboard buffer to the user buffer
		int read_bytes = 0;

		if (cbuf_size(&keyboard_input) >= *remaining_bytes)
			read_bytes = cbuf_read(&keyboard_input, buffer, *remaining_bytes, copy_to_user);
		else if (cbuf_full(&keyboard_input))
			read_bytes = cbuf_read(&keyboard_input, buffer, cbuf_size(&keyboard_input), copy_to_user);

		buffer += read_bytes;
		*remaining_bytes -= read_bytes;

		if (*remaining_bytes == 0)
			break;

		// Block process back at the beginning of the keyboard queue
		keyboard_serving_read = 0;
		block_current_task(&keyboardqueue, BLOCK_AT_BEGINNING);
	}

	keyboard_serving_read = 0;
	return size - *remaining_bytes;
}
Exemplo n.º 6
0
Arquivo: devices.c Projeto: wwjnc/zeos
void keyboard_key_pressed(char c)
{
	// If the buffer is full and there are no tasks waiting to read from it, discard it
	if (list_empty(&keyboardqueue) && cbuf_full(&keyboard_input))
		return;

	cbuf_insert(&keyboard_input, c);

	// Unblock first task in the keyboard queue if needed
	if (list_empty(&keyboardqueue)) // TODO Should we discard keypresses if there are no blocked tasks?
		return;

	if (keyboard_serving_read) // Avoid unblocking two or more tasks from the keyboard queue
		return;
	
	if (cbuf_full(&keyboard_input) || cbuf_size(&keyboard_input) >= get_pending_keyboard_bytes())
	{
		keyboard_serving_read = 1;
		unblock_task(&keyboardqueue);
	}
}