Permalink
Browse files

Zero-copy mapcache output when creating response `Buffer`

This fixes issue #3 with benchmarks showing a slight performance
boost.  A side effect is that the memory pool allocated for the
mapcache response is now cleaned up during the V8 garbage collection
cycle instead of at the end of each request as was previously the
case.
  • Loading branch information...
homme committed Mar 21, 2013
1 parent 5669485 commit 7077bd825097129876be6dd455d913e2dffd2b5c
Showing with 11 additions and 4 deletions.
  1. +5 −4 src/mapcache.cpp
  2. +6 −0 src/mapcache.hpp
View
@@ -231,7 +231,7 @@ Handle<Value> MapCache::GetAsync(const Arguments& args) {
RequestBaton *baton = new RequestBaton();
// create the pool for this request
- if (apr_pool_create(&(baton->pool), cache->config->pool) != APR_SUCCESS) {
+ if (apr_pool_create(&(baton->pool), global_pool) != APR_SUCCESS) {
delete baton;
THROW_CSTR_ERROR(Error, "Could not create the mapcache request memory pool");
}
@@ -394,9 +394,11 @@ void MapCache::GetRequestAfter(uv_work_t *req) {
result->Set(mtime_symbol, Date::New(apr_time_as_msec(response->mtime)));
}
- // set the response data as a Node Buffer object
+ // set the response data as a Node Buffer object. This is zero-copied from
+ // mapcache and free'd when the buffer is garbage collected.
if (response->data) {
- result->Set(data_symbol, Buffer::New((char *)response->data->buf, response->data->size)->handle_);
+ result->Set(data_symbol,
+ Buffer::New((char *)response->data->buf, response->data->size, FreeBuffer, (void *)baton->pool)->handle_);
}
// Set the response headers as a javascript object with header
@@ -440,7 +442,6 @@ void MapCache::GetRequestAfter(uv_work_t *req) {
// clean up
baton->callback.Dispose();
cache->Unref(); // decrement the cache reference so it can be garbage collected
- apr_pool_destroy(baton->pool); // free all memory for this request
delete baton;
return;
}
View
@@ -259,6 +259,12 @@ class MapCache: ObjectWrap {
static void NullLogRequestContext(mapcache_context *c, mapcache_log_level level, char *message, ...) {
return;
}
+
+ /// Free data zero-copied to a `Buffer`
+ static void FreeBuffer(char *data, void *hint) {
+ apr_pool_destroy((apr_pool_t *)hint); // free all memory for this request
+ data = NULL;
+ }
};
/**

0 comments on commit 7077bd8

Please sign in to comment.