write() & read() with pipe()

113 views
Skip to first unread message

Emmanuel Schmidbauer

unread,
Dec 28, 2021, 4:29:13 PM12/28/21
to libuv
Hello,
I'm trying to integrate existing code that uses pipe() and write() into libuv
I've been hacking my way through it as I'm not a libuv expert. But i've come up with a solution that works but maybe not "correct". The "publish" is an existing function that writes data to the pipe, it gets called by an external command. I would really appreciate if anyone could help me out with a "better" or "correct" way to implement this, thanks in advance. 

here is a snippet of "working" code:

int *worker_pipes_fds = NULL;
int *worker_pipes = NULL;
uv_loop_t *loop;
uv_pipe_t apipe;
static int publish()
{
char *payload = "Hello World";
write(worker_pipes[0], &payload, sizeof(payload));
}
void alloc_buffer(uv_handle_t *handle, size_t len, uv_buf_t *buf)
{
uv_os_fd_t fd;
char *payload = NULL;
if (uv_fileno(handle, &fd) < 0) {
printf("could not get fd: %d\n", fd);
return;
}
read(fd, &payload, sizeof(payload));
printf("%s \n", payload);
}

void read_pipe(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf)
{
// empty
}
int worker_proc(int fd)
{
loop = uv_default_loop();
uv_pipe_init(loop, &apipe, 0);
uv_pipe_open(&apipe, fd);
uv_read_start((uv_stream_t *)&apipe, alloc_buffer, read_pipe);
uv_run(loop, UV_RUN_DEFAULT);
return 1;
}

int start()
{
worker_pipes_fds = (int *)malloc(sizeof(int) * 2);
worker_pipes = (int *)malloc(sizeof(int) * 1);
worker_pipes_fds[0] = worker_pipes_fds[1] = -1;
if(pipe(&worker_pipes_fds[0]) < 0) {
return -1;
}
worker_pipes[0] = worker_pipes_fds[1];
worker_proc(worker_pipes_fds[0]);
}

Ben Noordhuis

unread,
Dec 29, 2021, 6:13:36 AM12/29/21
to li...@googlegroups.com
Do I understand correctly the idea is to have some a queue-like
mechanism that wakes up the event loop when new items are added?

Idiomatic libuv code would use uv_async_t coupled with a (optionally
uv_mutex_t protected) data structure. The sender adds the item and
calls uv_async_send(), the receiver pops it off in the uv_async_cb
callback.

Emmanuel Schmidbauer

unread,
Dec 29, 2021, 9:45:39 AM12/29/21
to libuv
Yes, your understanding is correct. 
Basically, there is an external function which pushes an object into a job queue. And another separate process running which reads off the queue. 
The code is already setup to use pipe(), write(), read() and libev but I am working on switching it to use libuv. I've had some more success using uv_poll_t and pipe(), write(), read() but it sounds like uv_async_t might be a more elegant solution. I will give it a try, thank you for help!
Reply all
Reply to author
Forward
0 new messages