Browse Source

udp_wrap: use new slab allocator

v0.9.1-release
Ben Noordhuis 13 years ago
parent
commit
1ab95a536a
  1. 13
      lib/dgram.js
  2. 56
      src/udp_wrap.cc

13
lib/dgram.js

@ -343,16 +343,11 @@ Socket.prototype._stopReceiving = function() {
}; };
function onMessage(handle, nread, buf, rinfo) { function onMessage(handle, slab, start, len, rinfo) {
var self = handle.socket; var self = handle.socket;
if (!slab) return self.emit('error', errnoException(errno, 'recvmsg'));
if (nread == -1) { rinfo.size = len; // compatibility
self.emit('error', errnoException(errno, 'recvmsg')); self.emit('message', slab.slice(start, start + len), rinfo);
}
else {
rinfo.size = buf.length; // compatibility
self.emit('message', buf, rinfo);
}
} }

56
src/udp_wrap.cc

@ -21,12 +21,14 @@
#include "node.h" #include "node.h"
#include "node_buffer.h" #include "node_buffer.h"
#include "slab_allocator.h"
#include "req_wrap.h" #include "req_wrap.h"
#include "handle_wrap.h" #include "handle_wrap.h"
#include <stdlib.h> #include <stdlib.h>
#define SLAB_SIZE (1024 * 1024)
// Temporary hack: libuv should provide uv_inet_pton and uv_inet_ntop. // Temporary hack: libuv should provide uv_inet_pton and uv_inet_ntop.
// Clean this up in tcp_wrap.cc too. // Clean this up in tcp_wrap.cc too.
#if defined(__MINGW32__) || defined(_MSC_VER) #if defined(__MINGW32__) || defined(_MSC_VER)
@ -59,16 +61,17 @@ namespace node {
return scope.Close(Integer::New(-1)); \ return scope.Close(Integer::New(-1)); \
} }
// TODO share with tcp_wrap.cc typedef ReqWrap<uv_udp_send_t> SendWrap;
Persistent<String> address_symbol;
Persistent<String> port_symbol;
Persistent<String> buffer_sym;
void AddressToJS(Handle<Object> info, void AddressToJS(Handle<Object> info,
const sockaddr* addr, const sockaddr* addr,
int addrlen); int addrlen);
typedef ReqWrap<uv_udp_send_t> SendWrap;
static Persistent<String> address_symbol;
static Persistent<String> port_symbol;
static Persistent<String> buffer_sym;
static SlabAllocator slab_allocator(SLAB_SIZE);
class UDPWrap: public HandleWrap { class UDPWrap: public HandleWrap {
@ -402,7 +405,9 @@ void UDPWrap::OnSend(uv_udp_send_t* req, int status) {
uv_buf_t UDPWrap::OnAlloc(uv_handle_t* handle, size_t suggested_size) { uv_buf_t UDPWrap::OnAlloc(uv_handle_t* handle, size_t suggested_size) {
return uv_buf_init(new char[suggested_size], suggested_size); UDPWrap* wrap = static_cast<UDPWrap*>(handle->data);
char* buf = slab_allocator.Allocate(wrap->object_, suggested_size);
return uv_buf_init(buf, suggested_size);
} }
@ -413,32 +418,29 @@ void UDPWrap::OnRecv(uv_udp_t* handle,
unsigned flags) { unsigned flags) {
HandleScope scope; HandleScope scope;
if (nread == 0) { UDPWrap* wrap = reinterpret_cast<UDPWrap*>(handle->data);
free(buf.base); Local<Object> slab = slab_allocator.Shrink(wrap->object_,
buf.base,
nread < 0 ? 0 : nread);
if (nread == 0) return;
if (nread < 0) {
Local<Value> argv[] = { Local<Object>::New(wrap->object_) };
SetErrno(uv_last_error(uv_default_loop()));
MakeCallback(wrap->object_, "onmessage", ARRAY_SIZE(argv), argv);
return; return;
} }
UDPWrap* wrap = reinterpret_cast<UDPWrap*>(handle->data); Local<Object> rinfo = Object::New();
AddressToJS(rinfo, addr, sizeof(*addr));
Local<Value> argv[4] = { Local<Value> argv[] = {
Local<Object>::New(wrap->object_), Local<Object>::New(wrap->object_),
Integer::New(nread), slab,
Local<Value>::New(Null()), Integer::NewFromUnsigned(buf.base - Buffer::Data(slab)),
Local<Value>::New(Null()) Integer::NewFromUnsigned(nread),
rinfo
}; };
if (nread == -1) {
SetErrno(uv_last_error(uv_default_loop()));
}
else {
Local<Object> rinfo = Object::New();
AddressToJS(rinfo, addr, sizeof *addr);
argv[2] = Local<Object>::New(
Buffer::New(buf.base, nread, NULL, NULL)->handle_);
argv[3] = rinfo;
}
free(buf.base);
MakeCallback(wrap->object_, "onmessage", ARRAY_SIZE(argv), argv); MakeCallback(wrap->object_, "onmessage", ARRAY_SIZE(argv), argv);
} }

Loading…
Cancel
Save