From 0f7b2963ada3198348b04ae564b56ac9774a2c47 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sat, 31 Aug 2013 07:37:51 +0200 Subject: [PATCH] include: uv_udp_recv_cb now takes const uv_buf_t* Passing or returning structs as values makes life hard for people that work with libuv through a foreign function interface. Switch to a pointer-based approach. Fixes #684. --- include/uv.h | 7 +++++-- src/unix/udp.c | 10 +++++----- src/win/udp.c | 20 ++++++++++---------- test/benchmark-udp-pummel.c | 6 +++--- test/echo-server.c | 13 ++++++++++--- test/test-getsockname.c | 6 +++--- test/test-udp-ipv6.c | 8 ++++---- test/test-udp-multicast-join.c | 6 +++--- test/test-udp-open.c | 6 +++--- test/test-udp-send-and-recv.c | 20 ++++++++++---------- 10 files changed, 56 insertions(+), 46 deletions(-) diff --git a/include/uv.h b/include/uv.h index 3ae0da86..4bf4d6fe 100644 --- a/include/uv.h +++ b/include/uv.h @@ -826,8 +826,11 @@ typedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status); * flags One or more OR'ed UV_UDP_* constants. * Right now only UV_UDP_PARTIAL is used. */ -typedef void (*uv_udp_recv_cb)(uv_udp_t* handle, ssize_t nread, uv_buf_t buf, - struct sockaddr* addr, unsigned flags); +typedef void (*uv_udp_recv_cb)(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* buf, + const struct sockaddr* addr, + unsigned flags); /* uv_udp_t is a subclass of uv_handle_t */ struct uv_udp_s { diff --git a/src/unix/udp.c b/src/unix/udp.c index 2356794b..c96afc0c 100644 --- a/src/unix/udp.c +++ b/src/unix/udp.c @@ -207,7 +207,7 @@ static void uv__udp_recvmsg(uv_loop_t* loop, do { handle->alloc_cb((uv_handle_t*) handle, 64 * 1024, &buf); if (buf.len == 0) { - handle->recv_cb(handle, UV_ENOBUFS, buf, NULL, 0); + handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0); return; } assert(buf.base != NULL); @@ -223,9 +223,9 @@ static void uv__udp_recvmsg(uv_loop_t* loop, if (nread == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) - handle->recv_cb(handle, 0, buf, NULL, 0); + handle->recv_cb(handle, 0, &buf, NULL, 0); else - handle->recv_cb(handle, -errno, buf, NULL, 0); + handle->recv_cb(handle, -errno, &buf, NULL, 0); } else { flags = 0; @@ -235,8 +235,8 @@ static void uv__udp_recvmsg(uv_loop_t* loop, handle->recv_cb(handle, nread, - buf, - (struct sockaddr*)&peer, + &buf, + (const struct sockaddr*) &peer, flags); } } diff --git a/src/win/udp.c b/src/win/udp.c index 51b31664..0a5d0600 100644 --- a/src/win/udp.c +++ b/src/win/udp.c @@ -273,7 +273,7 @@ static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) { handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->recv_buffer); if (handle->recv_buffer.len == 0) { - handle->recv_cb(handle, UV_ENOBUFS, handle->recv_buffer, NULL, 0); + handle->recv_cb(handle, UV_ENOBUFS, &handle->recv_buffer, NULL, 0); return; } assert(handle->recv_buffer.base != NULL); @@ -497,7 +497,7 @@ void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, uv_udp_recv_stop(handle); buf = (handle->flags & UV_HANDLE_ZERO_READ) ? uv_buf_init(NULL, 0) : handle->recv_buffer; - handle->recv_cb(handle, uv_translate_sys_error(err), buf, NULL, 0); + handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0); } goto done; } @@ -508,8 +508,8 @@ void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, partial = !REQ_SUCCESS(req); handle->recv_cb(handle, req->overlapped.InternalHigh, - handle->recv_buffer, - (struct sockaddr*) &handle->recv_from, + &handle->recv_buffer, + (const struct sockaddr*) &handle->recv_from, partial ? UV_UDP_PARTIAL : 0); } else if (handle->flags & UV_HANDLE_READING) { DWORD bytes, err, flags; @@ -520,7 +520,7 @@ void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, /* TODO: try to read multiple datagrams at once. FIONREAD maybe? */ handle->alloc_cb((uv_handle_t*) handle, 65536, &buf); if (buf.len == 0) { - handle->recv_cb(handle, UV_ENOBUFS, buf, NULL, 0); + handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0); goto done; } assert(buf.base != NULL); @@ -541,24 +541,24 @@ void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, NULL) != SOCKET_ERROR) { /* Message received */ - handle->recv_cb(handle, bytes, buf, (struct sockaddr*) &from, 0); + handle->recv_cb(handle, bytes, &buf, (const struct sockaddr*) &from, 0); } else { err = WSAGetLastError(); if (err == WSAEMSGSIZE) { /* Message truncated */ handle->recv_cb(handle, bytes, - buf, - (struct sockaddr*) &from, + &buf, + (const struct sockaddr*) &from, UV_UDP_PARTIAL); } if (err == WSAEWOULDBLOCK) { /* Kernel buffer empty */ - handle->recv_cb(handle, 0, buf, NULL, 0); + handle->recv_cb(handle, 0, &buf, NULL, 0); } else if (err != WSAECONNRESET && err != WSAENETRESET) { /* Serious error. WSAECONNRESET/WSANETRESET is ignored because this */ /* just indicates that a previous sendto operation failed. */ uv_udp_recv_stop(handle); - handle->recv_cb(handle, uv_translate_sys_error(err), buf, NULL, 0); + handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0); } } } diff --git a/test/benchmark-udp-pummel.c b/test/benchmark-udp-pummel.c index 9bb7e170..80d2bfc7 100644 --- a/test/benchmark-udp-pummel.c +++ b/test/benchmark-udp-pummel.c @@ -108,8 +108,8 @@ send: static void recv_cb(uv_udp_t* handle, ssize_t nread, - uv_buf_t buf, - struct sockaddr* addr, + const uv_buf_t* buf, + const struct sockaddr* addr, unsigned flags) { if (nread == 0) return; @@ -120,7 +120,7 @@ static void recv_cb(uv_udp_t* handle, } ASSERT(addr->sa_family == AF_INET); - ASSERT(!memcmp(buf.base, EXPECTED, nread)); + ASSERT(!memcmp(buf->base, EXPECTED, nread)); recv_cb_called++; } diff --git a/test/echo-server.c b/test/echo-server.c index 3b281005..160a85cf 100644 --- a/test/echo-server.c +++ b/test/echo-server.c @@ -190,10 +190,11 @@ static void on_send(uv_udp_send_t* req, int status); static void on_recv(uv_udp_t* handle, ssize_t nread, - uv_buf_t buf, - struct sockaddr* addr, + const uv_buf_t* rcvbuf, + const struct sockaddr* addr, unsigned flags) { uv_udp_send_t* req; + uv_buf_t sndbuf; int r; ASSERT(nread > 0); @@ -202,7 +203,13 @@ static void on_recv(uv_udp_t* handle, req = malloc(sizeof(*req)); ASSERT(req != NULL); - r = uv_udp_send(req, handle, &buf, 1, *(struct sockaddr_in*)addr, on_send); + sndbuf = *rcvbuf; + r = uv_udp_send(req, + handle, + &sndbuf, + 1, + *(const struct sockaddr_in*) addr, + on_send); ASSERT(r == 0); } diff --git a/test/test-getsockname.c b/test/test-getsockname.c index d97700e2..c530122c 100644 --- a/test/test-getsockname.c +++ b/test/test-getsockname.c @@ -234,15 +234,15 @@ static void tcp_connector(void) { static void udp_recv(uv_udp_t* handle, ssize_t nread, - uv_buf_t buf, - struct sockaddr* addr, + const uv_buf_t* buf, + const struct sockaddr* addr, unsigned flags) { struct sockaddr sockname; int namelen; int r; ASSERT(nread >= 0); - free(buf.base); + free(buf->base); if (nread == 0) { return; diff --git a/test/test-udp-ipv6.c b/test/test-udp-ipv6.c index 5dee3962..aaf54a8d 100644 --- a/test/test-udp-ipv6.c +++ b/test/test-udp-ipv6.c @@ -70,8 +70,8 @@ static void send_cb(uv_udp_send_t* req, int status) { static void ipv6_recv_fail(uv_udp_t* handle, ssize_t nread, - uv_buf_t buf, - struct sockaddr* addr, + const uv_buf_t* buf, + const struct sockaddr* addr, unsigned flags) { ASSERT(0 && "this function should not have been called"); } @@ -79,8 +79,8 @@ static void ipv6_recv_fail(uv_udp_t* handle, static void ipv6_recv_ok(uv_udp_t* handle, ssize_t nread, - uv_buf_t buf, - struct sockaddr* addr, + const uv_buf_t* buf, + const struct sockaddr* addr, unsigned flags) { CHECK_HANDLE(handle); ASSERT(nread >= 0); diff --git a/test/test-udp-multicast-join.c b/test/test-udp-multicast-join.c index 6f492d1c..5545c3f4 100644 --- a/test/test-udp-multicast-join.c +++ b/test/test-udp-multicast-join.c @@ -68,8 +68,8 @@ static void sv_send_cb(uv_udp_send_t* req, int status) { static void cl_recv_cb(uv_udp_t* handle, ssize_t nread, - uv_buf_t buf, - struct sockaddr* addr, + const uv_buf_t* buf, + const struct sockaddr* addr, unsigned flags) { CHECK_HANDLE(handle); ASSERT(flags == 0); @@ -89,7 +89,7 @@ static void cl_recv_cb(uv_udp_t* handle, ASSERT(addr != NULL); ASSERT(nread == 4); - ASSERT(!memcmp("PING", buf.base, nread)); + ASSERT(!memcmp("PING", buf->base, nread)); /* we are done with the client handle, we can close it */ uv_close((uv_handle_t*) &client, close_cb); diff --git a/test/test-udp-open.c b/test/test-udp-open.c index 1a6edda5..c23d53c4 100644 --- a/test/test-udp-open.c +++ b/test/test-udp-open.c @@ -85,8 +85,8 @@ static void close_cb(uv_handle_t* handle) { static void recv_cb(uv_udp_t* handle, ssize_t nread, - uv_buf_t buf, - struct sockaddr* addr, + const uv_buf_t* buf, + const struct sockaddr* addr, unsigned flags) { int r; @@ -105,7 +105,7 @@ static void recv_cb(uv_udp_t* handle, ASSERT(addr != NULL); ASSERT(nread == 4); - ASSERT(memcmp("PING", buf.base, nread) == 0); + ASSERT(memcmp("PING", buf->base, nread) == 0); r = uv_udp_recv_stop(handle); ASSERT(r == 0); diff --git a/test/test-udp-send-and-recv.c b/test/test-udp-send-and-recv.c index fc3a4fab..f90a182f 100644 --- a/test/test-udp-send-and-recv.c +++ b/test/test-udp-send-and-recv.c @@ -61,8 +61,8 @@ static void close_cb(uv_handle_t* handle) { static void cl_recv_cb(uv_udp_t* handle, ssize_t nread, - uv_buf_t buf, - struct sockaddr* addr, + const uv_buf_t* buf, + const struct sockaddr* addr, unsigned flags) { CHECK_HANDLE(handle); ASSERT(flags == 0); @@ -80,7 +80,7 @@ static void cl_recv_cb(uv_udp_t* handle, ASSERT(addr != NULL); ASSERT(nread == 4); - ASSERT(!memcmp("PONG", buf.base, nread)); + ASSERT(!memcmp("PONG", buf->base, nread)); cl_recv_cb_called++; @@ -116,10 +116,11 @@ static void sv_send_cb(uv_udp_send_t* req, int status) { static void sv_recv_cb(uv_udp_t* handle, ssize_t nread, - uv_buf_t buf, - struct sockaddr* addr, + const uv_buf_t* rcvbuf, + const struct sockaddr* addr, unsigned flags) { uv_udp_send_t* req; + uv_buf_t sndbuf; int r; if (nread < 0) { @@ -138,7 +139,7 @@ static void sv_recv_cb(uv_udp_t* handle, ASSERT(addr != NULL); ASSERT(nread == 4); - ASSERT(!memcmp("PING", buf.base, nread)); + ASSERT(!memcmp("PING", rcvbuf->base, nread)); /* FIXME? `uv_udp_recv_stop` does what it says: recv_cb is not called * anymore. That's problematic because the read buffer won't be returned @@ -150,13 +151,12 @@ static void sv_recv_cb(uv_udp_t* handle, req = malloc(sizeof *req); ASSERT(req != NULL); - buf = uv_buf_init("PONG", 4); - + sndbuf = uv_buf_init("PONG", 4); r = uv_udp_send(req, handle, - &buf, + &sndbuf, 1, - *(struct sockaddr_in*)addr, + *(const struct sockaddr_in*) addr, sv_send_cb); ASSERT(r == 0);