2014-09-17 11:37 GMT+02:00 Saúl Ibarra Corretgé <
sag...@gmail.com>:
> Then malloc one of these and pass &ctx->req to uv_udp_send. In the
> callback, you can do the following to get a pointer to your context:
>
> udp_send_ctx_t* ctx = container_of(req, udp_send_ctx_t, req);
Don't do that please. The "container_of" is just defined in Linux.
IMHO it is much more elegant to use the void* data field of the
uv_udp_send_t.
What I do in my C++ code (and in fact Saghul suggested it) is:
-------------------------------------
typedef struct UvSendData {
UDPSocket* socket; // My C++ UDPSocket class
uv_udp_send_t req;
uint8_t store[1];
} UvSendData;
void UDPSocket::Send(unint8_t* data, size_t len, const sockaddr* addr)
{
UvSendData* send_data = (UvSendData*)std::malloc(sizeof(UvSendData) + len);
send_data->socket = this;
memcpy(send_data->store, data, len);
// Store the pointer to our UvSendData in the data field
// of the uv_udp_send_t request:
send_data->req.data = (void*)send_data;
uv_buf_t buffer = uv_buf_init((char*)send_data->store, len);
int err = uv_udp_send(&send_data->req, this->uvUdpHandle, &buffer,
1, addr, (uv_udp_send_cb)on_send);
etc etc
}
-------------------------------------------
A single malloc is done. Then in the on_send callback:
------------------------------------------
static inline
void on_send(uv_udp_send_t* req, int status)
{
UDPSocket::UvSendData* send_data =
static_cast<UDPSocket::UvSendData*>(req->data);
UDPSocket* socket = send_data->socket;
// Delete the UvSendData struct (which includes the uv_req_t and the
store char[]).
free(send_data);
// Just notify the UDPSocket when error.
if (status)
socket->onUvSendError(status);
}
---------------------------------------------
Hope it helps.
--
Iñaki Baz Castillo
<
i...@aliax.net>