Skip to content

Commit fb7b980

Browse files
committed
Added hints to v8 about memory allocations
1 parent 3d9d61d commit fb7b980

File tree

14 files changed

+186
-80
lines changed

14 files changed

+186
-80
lines changed

.bithoundrc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"critics": {
3+
"lint": { "engine": "eslint" },
4+
"wc": { "limit": 1500 }
5+
},
6+
"dependencies": {
7+
"unused-ignores": [
8+
"node-gyp",
9+
"node-pre-gyp",
10+
"nan",
11+
"debug",
12+
"npmlog"
13+
]
14+
}
15+
}

binding.gyp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
'src/Multi.cc',
1010
'src/Curl.cc',
1111
'src/CurlHttpPost.cc',
12-
'src/string_format.cc',
13-
'src/strndup.cc'
12+
'src/string_format.cc'
1413
],
1514
'include_dirs' : [
1615
"<!(node -e \"require('nan')\")"

scripts/module-packaging.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ function createRelease( tagName, cb ) {
9191
log.info( '', 'creating release for tag "%s"', tagName );
9292

9393
repo.release({
94-
"tag_name" : tagName
94+
tag_name : tagName
9595
}, cb );
9696
}
9797

src/Curl.cc

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
//@TODO CHANGE LIBCURL_VERSION_NUM TO NODE_LIBCURL_VER_GE
3434
namespace NodeLibcurl {
3535

36+
ssize_t addonAllocatedMemory = 0;
37+
bool isLibcurlBuiltWithThreadedResolver = true;
38+
3639
const std::vector<CurlConstant> curlConstAuth = {
3740
{ "ANY", CURLAUTH_ANY },
3841
{ "ANYSAFE", CURLAUTH_ANYSAFE },
@@ -917,7 +920,7 @@ namespace NodeLibcurl {
917920
}
918921

919922
// Add Curl constructor to the module exports
920-
CURL_MODULE_INIT( Initialize )
923+
NODE_LIBCURL_MODULE_INIT( Initialize )
921924
{
922925
Nan::HandleScope scope;
923926

@@ -1046,6 +1049,27 @@ namespace NodeLibcurl {
10461049
return 0;
10471050
}
10481051

1052+
void AdjustMemory( ssize_t diff )
1053+
{
1054+
addonAllocatedMemory += diff;
1055+
1056+
// if v8 is no longer running, don't try to adjust memory
1057+
// this happens when the v8 vm is shutdown and the program is exiting
1058+
// our cleanup routines for libxml will be called (freeing memory)
1059+
// but v8 is already offline and does not need to be informed
1060+
// trying to adjust after shutdown will result in a fatal error
1061+
#if (NODE_MODULE_VERSION > 0x000B)
1062+
if ( !v8::Isolate::GetCurrent() ) {
1063+
return;
1064+
}
1065+
#endif
1066+
if ( v8::V8::IsDead() ) {
1067+
return;
1068+
}
1069+
1070+
Nan::AdjustExternalMemory( static_cast<int>( diff ) );
1071+
}
1072+
10491073
// Create an Exception with the given message and reason
10501074
void ThrowError( const char *message, const char *reason )
10511075
{

src/Curl.h

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -48,48 +48,53 @@ namespace NodeLibcurl {
4848
typedef v8::Local<v8::Value> ADDON_REGISTER_FUNCTION_ARGS2_TYPE;
4949
#endif
5050

51-
#define CURL_MODULE_INIT( name ) \
51+
#define NODE_LIBCURL_MODULE_INIT( name ) \
5252
void name( Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE exports, ADDON_REGISTER_FUNCTION_ARGS2_TYPE module )
5353

54+
#define NODE_LIBCURL_ADJUST_MEM( size ) if ( !isLibcurlBuiltWithThreadedResolver ) AdjustMemory( size )
55+
5456
// store mapping from the CURL[*] constants that can be used in js
5557
struct CurlConstant
5658
{
5759
const char *name;
5860
int64_t value;
5961
};
6062

63+
extern ssize_t addonAllocatedMemory;
64+
extern bool isLibcurlBuiltWithThreadedResolver;
65+
6166
template<typename T>
6267
using deleted_unique_ptr = std::unique_ptr<T, std::function<void( T* )>>;
6368

64-
const extern std::vector<CurlConstant> curlConstAuth;
65-
const extern std::vector<CurlConstant> curlConstProtocol;
66-
const extern std::vector<CurlConstant> curlConstPause;
67-
const extern std::vector<CurlConstant> curlConstHttp;
68-
const extern std::vector<CurlConstant> curlConstHeader;
69-
70-
const extern std::vector<CurlConstant> curlOptionNotImplemented;
71-
const extern std::vector<CurlConstant> curlOptionInteger;
72-
const extern std::vector<CurlConstant> curlOptionString;
73-
const extern std::vector<CurlConstant> curlOptionFunction;
74-
const extern std::vector<CurlConstant> curlOptionLinkedList;
75-
const extern std::vector<CurlConstant> curlOptionHttpPost;
76-
const extern std::vector<CurlConstant> curlOptionSpecific;
77-
78-
const extern std::vector<CurlConstant> curlInfoNotImplemented;
79-
const extern std::vector<CurlConstant> curlInfoString;
80-
const extern std::vector<CurlConstant> curlInfoDouble;
81-
const extern std::vector<CurlConstant> curlInfoInteger;
82-
const extern std::vector<CurlConstant> curlInfoSocket;
83-
const extern std::vector<CurlConstant> curlInfoLinkedList;
84-
85-
const extern std::vector<CurlConstant> curlMultiOptionNotImplemented;
86-
const extern std::vector<CurlConstant> curlMultiOptionInteger;
87-
const extern std::vector<CurlConstant> curlMultiOptionStringArray;
88-
89-
const extern std::vector<CurlConstant> curlCode;
69+
extern const std::vector<CurlConstant> curlConstAuth;
70+
extern const std::vector<CurlConstant> curlConstProtocol;
71+
extern const std::vector<CurlConstant> curlConstPause;
72+
extern const std::vector<CurlConstant> curlConstHttp;
73+
extern const std::vector<CurlConstant> curlConstHeader;
74+
75+
extern const std::vector<CurlConstant> curlOptionNotImplemented;
76+
extern const std::vector<CurlConstant> curlOptionInteger;
77+
extern const std::vector<CurlConstant> curlOptionString;
78+
extern const std::vector<CurlConstant> curlOptionFunction;
79+
extern const std::vector<CurlConstant> curlOptionLinkedList;
80+
extern const std::vector<CurlConstant> curlOptionHttpPost;
81+
extern const std::vector<CurlConstant> curlOptionSpecific;
82+
83+
extern const std::vector<CurlConstant> curlInfoNotImplemented;
84+
extern const std::vector<CurlConstant> curlInfoString;
85+
extern const std::vector<CurlConstant> curlInfoDouble;
86+
extern const std::vector<CurlConstant> curlInfoInteger;
87+
extern const std::vector<CurlConstant> curlInfoSocket;
88+
extern const std::vector<CurlConstant> curlInfoLinkedList;
89+
90+
extern const std::vector<CurlConstant> curlMultiOptionNotImplemented;
91+
extern const std::vector<CurlConstant> curlMultiOptionInteger;
92+
extern const std::vector<CurlConstant> curlMultiOptionStringArray;
93+
94+
extern const std::vector<CurlConstant> curlCode;
9095

9196
// export Curl to js
92-
CURL_MODULE_INIT( Initialize );
97+
NODE_LIBCURL_MODULE_INIT( Initialize );
9398

9499
// js exported Methods
95100
NAN_METHOD( GetVersion );
@@ -99,6 +104,7 @@ namespace NodeLibcurl {
99104
// helper methods
100105
int32_t IsInsideCurlConstantStruct( const std::vector<CurlConstant> &curlConstants, const v8::Local<v8::Value> &searchFor );
101106
void ThrowError( const char *message, const char *reason = nullptr );
107+
void AdjustMemory( ssize_t size );
102108

103109
}
104110
#endif

src/Easy.cc

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
#include "make_unique.h"
3131
#include "string_format.h"
3232

33+
// 36055 was allocated on Win64
34+
#define MEMORY_PER_HANDLE 30000
35+
3336
namespace NodeLibcurl {
3437

3538
class Easy::ToFree {
@@ -48,8 +51,6 @@ namespace NodeLibcurl {
4851
Nan::Persistent<v8::FunctionTemplate> Easy::constructor;
4952
Nan::Persistent<v8::String> Easy::onDataCbSymbol;
5053
Nan::Persistent<v8::String> Easy::onHeaderCbSymbol;
51-
Nan::Persistent<v8::String> Easy::onErrorCbSymbol;
52-
Nan::Persistent<v8::String> Easy::onEndCbSymbol;
5354

5455
uint32_t Easy::counter = 0;
5556
int32_t Easy::currentOpenedHandles = 0;
@@ -65,6 +66,8 @@ namespace NodeLibcurl {
6566
this->ch = curl_easy_init();
6667
assert( this->ch );
6768

69+
NODE_LIBCURL_ADJUST_MEM( MEMORY_PER_HANDLE );
70+
6871
this->toFree = std::make_shared<Easy::ToFree>();
6972

7073
this->ResetRequiredHandleOptions();
@@ -86,6 +89,8 @@ namespace NodeLibcurl {
8689
this->ch = curl_easy_duphandle( orig->ch );
8790
assert( this->ch );
8891

92+
NODE_LIBCURL_ADJUST_MEM( MEMORY_PER_HANDLE );
93+
8994
Nan::HandleScope scope;
9095

9196
// make sure to reset the *DATA options when duplicating a handle.
@@ -185,6 +190,8 @@ namespace NodeLibcurl {
185190

186191
curl_easy_cleanup( this->ch );
187192

193+
NODE_LIBCURL_ADJUST_MEM( -MEMORY_PER_HANDLE );
194+
188195
//dispose persistent callbacks
189196
this->DisposeCallbacks();
190197

@@ -730,7 +737,7 @@ namespace NodeLibcurl {
730737
return retvalInt32;
731738
}
732739

733-
CURL_MODULE_INIT( Easy::Initialize )
740+
NODE_LIBCURL_MODULE_INIT( Easy::Initialize )
734741
{
735742
Nan::HandleScope scope;
736743

@@ -764,8 +771,6 @@ namespace NodeLibcurl {
764771

765772
Easy::onDataCbSymbol.Reset( Nan::New( "onData" ).ToLocalChecked() );
766773
Easy::onHeaderCbSymbol.Reset( Nan::New( "onHeader" ).ToLocalChecked() );
767-
Easy::onEndCbSymbol.Reset( Nan::New( "onEnd" ).ToLocalChecked() );
768-
Easy::onErrorCbSymbol.Reset( Nan::New( "onError" ).ToLocalChecked() );
769774

770775
Nan::Set( exports, Nan::New( "Easy" ).ToLocalChecked(), tmpl->GetFunction() );
771776
}

src/Easy.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,6 @@ namespace NodeLibcurl {
9999
// persistent objects
100100
static Nan::Persistent<v8::String> onDataCbSymbol;
101101
static Nan::Persistent<v8::String> onHeaderCbSymbol;
102-
static Nan::Persistent<v8::String> onErrorCbSymbol;
103-
static Nan::Persistent<v8::String> onEndCbSymbol;
104102

105103
public:
106104
// operators
@@ -119,7 +117,7 @@ namespace NodeLibcurl {
119117
static int32_t currentOpenedHandles;
120118

121119
// export Easy to js
122-
static CURL_MODULE_INIT( Initialize );
120+
static NODE_LIBCURL_MODULE_INIT( Initialize );
123121

124122
// js available methods
125123
static NAN_METHOD( New );

src/Multi.cc

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,33 @@
2020
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2121
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2222
*/
23+
#include <iostream>
2324
#include "Multi.h"
2425

26+
//85233 was allocated on Win64
27+
#define MEMORY_PER_HANDLE 60000
28+
2529
namespace NodeLibcurl {
2630

2731
Nan::Persistent<v8::FunctionTemplate> Multi::constructor;
2832

2933
Multi::Multi() : isOpen( true ), amountOfHandles( 0 ), runningHandles( 0 ), cbOnMessage( nullptr )
3034
{
3135
// init uv timer to be used with HandleTimeout
32-
this->timeout = deleted_unique_ptr<uv_timer_t>( new uv_timer_t, [&]( uv_timer_t *timerhandl ) { uv_close( reinterpret_cast<uv_handle_t *>( timerhandl ), Multi::OnTimerClose ); } );
36+
this->timeout = deleted_unique_ptr<uv_timer_t>( new uv_timer_t, [&]( uv_timer_t *timerhandl ) {
37+
uv_close( reinterpret_cast<uv_handle_t *>( timerhandl ), Multi::OnTimerClose );
38+
});
3339

3440
int timerStatus = uv_timer_init( uv_default_loop(), this->timeout.get() );
3541
assert( timerStatus == 0 );
3642

3743
this->timeout->data = this;
3844

3945
this->mh = curl_multi_init();
40-
4146
assert( this->mh );
4247

48+
NODE_LIBCURL_ADJUST_MEM( MEMORY_PER_HANDLE );
49+
4350
// set curl_multi cb to use libuv
4451
curl_multi_setopt( this->mh, CURLMOPT_SOCKETFUNCTION, Multi::HandleSocket );
4552
curl_multi_setopt( this->mh, CURLMOPT_SOCKETDATA, this );
@@ -64,8 +71,9 @@ namespace NodeLibcurl {
6471
if ( this->mh ) {
6572

6673
CURLMcode code = curl_multi_cleanup( this->mh );
67-
6874
assert( code == CURLM_OK );
75+
76+
NODE_LIBCURL_ADJUST_MEM( -MEMORY_PER_HANDLE );
6977
}
7078

7179
this->RemoveOnMessageCallback();
@@ -227,6 +235,7 @@ namespace NodeLibcurl {
227235
Multi::CurlSocketContext *ctx = NULL;
228236

229237
ctx = static_cast<Multi::CurlSocketContext*>( malloc( sizeof( *ctx ) ) );
238+
assert( ctx && "Not enought memory to allocate a new Multi::CurlSocketContext." );
230239

231240
ctx->sockfd = sockfd;
232241
ctx->multi = multi;
@@ -296,7 +305,7 @@ namespace NodeLibcurl {
296305
}
297306

298307
// Add Curl constructor to the module exports
299-
CURL_MODULE_INIT( Multi::Initialize )
308+
NODE_LIBCURL_MODULE_INIT( Multi::Initialize )
300309
{
301310
Nan::HandleScope scope;
302311

src/Multi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ namespace NodeLibcurl {
8282
static Nan::Persistent<v8::FunctionTemplate> constructor;
8383

8484
// export Multi to js
85-
static CURL_MODULE_INIT( Initialize );
85+
static NODE_LIBCURL_MODULE_INIT( Initialize );
8686

8787
// js available Methods
8888
static NAN_METHOD( New );

src/Share.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
#include "Share.h"
2828
#include "Curl.h"
2929

30+
// 464 was allocated on Win64
31+
// Value too small to bother letting v8 know about it
32+
#define MEMORY_PER_HANDLE 464
33+
3034
namespace NodeLibcurl {
3135

3236
Nan::Persistent<v8::FunctionTemplate> Share::constructor;
@@ -57,7 +61,7 @@ namespace NodeLibcurl {
5761
this->isOpen = false;
5862
}
5963

60-
CURL_MODULE_INIT( Share::Initialize )
64+
NODE_LIBCURL_MODULE_INIT( Share::Initialize )
6165
{
6266
Nan::HandleScope scope;
6367

0 commit comments

Comments
 (0)