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; }
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; }