Replies: 4 comments
|
You can control how much data to read by allocating that space in uv_alloc_cb. Once you read that you can uv_read_stop so it no longer continues reading. Rinse and repeat. |
Nice, looks like this is what I need. What happens if the client keeps sending data while there is no read? If I called I assume something like this is the way to do a "sized read": typedef struct {
char* data;
uint32_t off;
uint32_t max;
uv_read_cb cb;
} readall_t;
void readall__alloc(uv_handle_t* handle, size_t unused, uv_buf_t* buf) {
readall_t* r = (readall_t*) uv_handle_get_data(handle);
buf->base = r->data + r->off;
buf->len = r->max - r->off;
}
void readall__read(uv_stream_t* client, ssize_t nread, const uv_buf_t* unused) {
readall_t* r = (readall_t*) uv_handle_get_data((uv_handle_t*) client);
if (nread > 0) {
r->off += nread;
if (r->off == r->max) {
uv_read_stop(client);
uv_buf_t buf = uv_buf_init(r->data, r->max);
r->cb(client, r->max, &buf);
}
}
else if (nread < 0) {
uv_read_stop(client);
uv_buf_t buf = uv_buf_init(NULL, 0);
r->cb(client, nread, &buf);
}
}
void readall__begin(uv_stream_t* stream, readall_t* r) {
uv_handle_set_data((uv_handle_t*) stream, r);
uv_read_start(stream, readall__alloc, readall__read);
} |
|
You don't need to call the callback yourself, libuv will. You also need to account for the case in which you read less data than the expected. As for what happens when not reading, the kernel will buffer the data up to a point, after which it will start discarding it. |
|
This kind of question seems to come up all the time. Indeed, @saghul, you yourself started a project ten years ago to change the API to something like Here, I want to express a big +1 on this proposal. For me there are two distinct advantages:
Indeed, with the current API, under straight-forward usage we reallocate and copy upon each read request, which for my use case is hard to avoid. I understand that the disadvantage of this proposed How hard would it be to offer |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
It looks like the only way to read from a stream is to use
uv_read_startthat will run the callback whenever any amount of data comes through.However most of the time you actually want to read a specific amount of data from the underlying protocol.
Right now the only way to achieve it is to buffer the chunks then try reading the amount of data you need.
If you receive more than needed and you run out of buffer space in the allocation callback you'd get UV_ENOBUFS.
I think an asynchronous version of a blocking
recvwill be very useful, similar to the dispatch_io_read function in libdispatch on macOS that takes the handle, size and callback. The callback is then called with the current data, error and whether the read is finished.Maybe something like
uv_read2(uv_stream* stream, size_t size, void* data, uv_read2_cb cb)where you provide a sized buffer and you get a callback when the data is read into it?All reactions