Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
include: uv_udp_recv_cb now takes const uv_buf_t*
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bnoordhuis committed Sep 1, 2013
1 parent 255671d commit 0f7b296
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 46 deletions.
7 changes: 5 additions & 2 deletions include/uv.h
Expand Up @@ -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 {
Expand Down
10 changes: 5 additions & 5 deletions src/unix/udp.c
Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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);
}
}
Expand Down
20 changes: 10 additions & 10 deletions src/win/udp.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -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);
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions test/benchmark-udp-pummel.c
Expand Up @@ -108,8 +108,8 @@ static void send_cb(uv_udp_send_t* req, int status) {

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;
Expand All @@ -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++;
}
Expand Down
13 changes: 10 additions & 3 deletions test/echo-server.c
Expand Up @@ -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);
Expand All @@ -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);
}

Expand Down
6 changes: 3 additions & 3 deletions test/test-getsockname.c
Expand Up @@ -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;
Expand Down
8 changes: 4 additions & 4 deletions test/test-udp-ipv6.c
Expand Up @@ -70,17 +70,17 @@ 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");
}


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);
Expand Down
6 changes: 3 additions & 3 deletions test/test-udp-multicast-join.c
Expand Up @@ -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);
Expand All @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions test/test-udp-open.c
Expand Up @@ -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;

Expand All @@ -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);
Expand Down
20 changes: 10 additions & 10 deletions test/test-udp-send-and-recv.c
Expand Up @@ -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);
Expand All @@ -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++;

Expand Down Expand Up @@ -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) {
Expand All @@ -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
Expand All @@ -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);

Expand Down

0 comments on commit 0f7b296

Please sign in to comment.