Example #1
0
File: mux.c Project: FuangCao/cavan
ssize_t cavan_mux_link_recv(struct cavan_mux_link *link, void *buff, size_t size)
{
	size_t length;
	const char *data;
	struct cavan_mux_package *package;
	struct cavan_mux_package_raw *package_raw;

	cavan_lock_acquire(&link->lock);

	package_raw = link->package_head;
	if (package_raw == NULL) {
		cavan_lock_release(&link->lock);
		return 0;
	}

	package = &package_raw->package;
	data = package->data + link->hole_size;
	length = package->length - link->hole_size;
	if (size < length) {
		memcpy(buff, data, size);

		link->hole_size += size;
	} else {
		size = length;
		memcpy(buff, data, size);

		cavan_mux_package_free(link->mux, package);
		link->hole_size = 0;
	}

	cavan_lock_release(&link->lock);

	return size;
}
Example #2
0
File: mux.c Project: FuangCao/cavan
ssize_t cavan_mux_append_receive_data(struct cavan_mux *mux, const void *buff, size_t size)
{
	int ret;
	size_t wrlen, rdlen;
	struct cavan_mux_package package;
	struct cavan_mux_package *ppackage;

	cavan_lock_acquire(&mux->lock);

	wrlen = cavan_mem_queue_inqueue(&mux->recv_queue, buff, size);

	while (1) {
		rdlen = cavan_mem_queue_dequeue_peek(&mux->recv_queue, &package, sizeof(package));
		if (rdlen < sizeof(package)) {
			goto out_success;
		}

		if (package.magic == CAVAN_MUX_MAGIC) {
			break;
		}

		cavan_mem_queue_dequeue(&mux->recv_queue, NULL, 1);
	}

	size = cavan_mux_package_get_whole_length(&package);
	if (cavan_mem_queue_get_used_size(&mux->recv_queue) < size) {
		goto out_success;
	}

	ppackage = cavan_mux_package_alloc(mux, package.length);
	if (ppackage == NULL) {
		pr_red_info("cavan_mux_package_alloc");
		ret = -ENOMEM;
		goto out_cavan_lock_release;
	}

	if (cavan_mem_queue_dequeue(&mux->recv_queue, ppackage, size) != size) {
		pr_red_info("cavan_mem_queue_dequeue");
		ret = -EFAULT;
		goto out_cavan_lock_release;
	}

	ret = cavan_mux_append_receive_package(mux, ppackage);
	if (ret < 0) {
		pr_red_info("cavan_mux_write_recv_package: %d", ret);
		cavan_mux_package_free(mux, ppackage);
	}

out_success:
	ret = wrlen;
out_cavan_lock_release:
	cavan_lock_release(&mux->lock);
	return ret;
}
Example #3
0
static int cavan_mux_send_thread_handler(struct cavan_thread *thread, void *data)
{
	struct cavan_mux *mux = data;
	struct cavan_mux_package_raw *package_raw;

	package_raw = mux->package_head;
	if (package_raw == NULL)
	{
		cavan_thread_suspend(thread);
	}
	else
	{
		struct cavan_mux_package *package = &package_raw->package;
		char *data = (char *) package;
		size_t length = cavan_mux_package_get_whole_length(package);

		while (length)
		{
			ssize_t wrlen;

			wrlen = mux->send(mux, data, length);
			if (wrlen < 0)
			{
				pr_red_info("mux->send");
				return wrlen;
			}

			data += wrlen;
			length -= wrlen;
		}

		mux->package_head = package_raw->next;
		if (mux->package_head == NULL)
		{
			mux->package_tail = &mux->package_head;
		}

		cavan_mux_package_free(mux, package);
	}

	return 0;
}
Example #4
0
int main(int argc, char *argv[])
{
    int i;
    int ret;
    int count;
    ssize_t rdlen;
    char buff[1024];
    struct cavan_mux mux;
    struct cavan_mux_link link1, link2;
    struct cavan_mux_package *package, *packages[10];
    int pipefd[2];

    ret = pipe(pipefd);
    if (ret < 0) {
        pr_error_info("pipe");
        return ret;
    }

    mux.send = test_mux_send;
    mux.recv = test_mux_recv;
    ret = cavan_mux_init(&mux, pipefd);
    if (ret < 0) {
        pr_red_info("cavan_mux_init");
        return ret;
    }

    cavan_mux_link_init(&link1, &mux);
    cavan_mux_link_init(&link2, &mux);

    cavan_mux_show_packages(&mux);

    for (i = 0; i < NELEM(packages); i++) {
        packages[i] = cavan_mux_package_alloc(&mux, (i + 1) * 100);
    }

    cavan_mux_show_packages(&mux);

    for (i = NELEM(packages) - 1; i >= 0; i--) {
        cavan_mux_package_free(&mux, packages[i]);
    }

    cavan_mux_show_packages(&mux);

    (void) package;

#if 0
    package = cavan_mux_package_alloc(&mux, 560);
    if (package) {
        println("alloc length = %d", package->length);
    }

    cavan_mux_show_packages(&mux);
#endif

    link1.on_received = link2.on_received = test_mux_on_received;

    link1.private_data = "Link1";
    ret = cavan_mux_bind(&mux, &link1, 2000);
    if (ret < 0) {
        pr_red_info("cavan_mux_bind");
    }

    link2.private_data = "Link2";
    ret = cavan_mux_bind(&mux, &link2, 12345);
    if (ret < 0) {
        pr_red_info("cavan_mux_bind");
    }

    println("port1 = %d, port2 = %d", link1.local_port, link2.local_port);
    link1.remote_port = link2.local_port;
    ret = cavan_mux_link_send(&link1, "1234567890", 10);
    if (ret < 0) {
        pr_red_info("cavan_mux_link_send");
    }

    cavan_mux_show_packages(&mux);

    link2.remote_port = link1.local_port;
    ret = cavan_mux_link_send(&link2, "ABCDEFGHIJKL", 10);
    if (ret < 0) {
        pr_red_info("cavan_mux_link_send");
    }

    cavan_mux_show_packages(&mux);

    (void) count;

#if 0
    count = 0;

    while (1) {
        struct cavan_mux_link *link = malloc(sizeof(struct cavan_mux_link));
        ret = cavan_mux_bind(&mux, link, 0);
        if (ret < 0) {
            pr_red_info("cavan_mux_bind");
            break;
        }

        if (link->local_port == link1.local_port || link->local_port == link2.local_port) {
            pr_red_info("invalid port %d", link->local_port);
        }

        count++;

        println("port = %d, count = %d", link->local_port, count);
    }
#endif

    msleep(5000);

    rdlen = cavan_mux_link_recv(&link1, buff, sizeof(buff));
    buff[rdlen] = 0;
    println("link1: buff[%" PRINT_FORMAT_SIZE "] = %s", rdlen, buff);

    cavan_mux_show_packages(&mux);

    msleep(5000);

    rdlen = cavan_mux_link_recv(&link2, buff, sizeof(buff));
    buff[rdlen] = 0;
    println("link2: buff[%" PRINT_FORMAT_SIZE "] = %s", rdlen, buff);

    cavan_mux_show_packages(&mux);

    cavan_mux_deinit(&mux);

    return 0;
}