Skip to content

Commit 210c4ba

Browse files
committed
fixed cursor memory leaks - free rows data and don't wait for gc to release occi cursor
1 parent 6944bb2 commit 210c4ba

File tree

4 files changed

+32
-13
lines changed

4 files changed

+32
-13
lines changed

src/executeBaton.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,7 @@ ExecuteBaton::~ExecuteBaton() {
3333
delete val;
3434
}
3535

36-
if(rows) {
37-
for (std::vector<row_t*>::iterator iterator = rows->begin(), end = rows->end(); iterator != end; ++iterator) {
38-
row_t* currentRow = *iterator;
39-
delete currentRow;
40-
}
41-
42-
delete rows;
43-
}
36+
ResetRows();
4437

4538
if(outputs) {
4639
for (std::vector<output_t*>::iterator iterator = outputs->begin(), end = outputs->end(); iterator != end; ++iterator) {
@@ -53,6 +46,18 @@ ExecuteBaton::~ExecuteBaton() {
5346
if(error) delete error;
5447
}
5548

49+
void ExecuteBaton::ResetRows() {
50+
if(rows) {
51+
for (std::vector<row_t*>::iterator iterator = rows->begin(), end = rows->end(); iterator != end; ++iterator) {
52+
row_t* currentRow = *iterator;
53+
delete currentRow;
54+
}
55+
56+
delete rows;
57+
rows = NULL;
58+
}
59+
}
60+
5661
double CallDateMethod(v8::Local<v8::Date> date, const char* methodName) {
5762
Handle<Value> args[1]; // should be zero but on windows the compiler will not allow a zero length array
5863
Local<Value> result = Local<Function>::Cast(date->Get(String::New(methodName)))->Call(date, 0, args);

src/executeBaton.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class ExecuteBaton {
6161
public:
6262
ExecuteBaton(Connection* connection, const char* sql, v8::Local<v8::Array>* values, v8::Handle<v8::Function>* callback);
6363
~ExecuteBaton();
64+
void ResetRows();
6465

6566
Connection *connection;
6667
v8::Persistent<v8::Function> callback;

src/reader.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ uni::CallbackType Reader::NextRows(const uni::FunctionCallbackInfo& args) {
7272
void Reader::EIO_NextRows(uv_work_t* req) {
7373
ReaderBaton* baton = static_cast<ReaderBaton*>(req->data);
7474

75-
baton->rows = NULL;
76-
baton->error = NULL;
75+
baton->rows = new vector<row_t*>();
76+
if (baton->done) return;
7777

7878
try {
7979
if(! baton->connection->getConnection()) {
@@ -96,13 +96,13 @@ void Reader::EIO_NextRows(uv_work_t* req) {
9696
Connection::CreateColumnsFromResultSet(baton->rs, baton, baton->columns);
9797
if (baton->error) goto cleanup;
9898
}
99-
baton->rows = new vector<row_t*>();
10099

101100
for (int i = 0; i < baton->count && baton->rs->next(); i++) {
102101
row_t* row = Connection::CreateRowFromCurrentResultSetRow(baton->rs, baton, baton->columns);
103102
if (baton->error) goto cleanup;
104103
baton->rows->push_back(row);
105104
}
105+
if (baton->rows->size() < (size_t)baton->count) baton->done = true;
106106
} catch(oracle::occi::SQLException &ex) {
107107
baton->error = new string(ex.getMessage());
108108
} catch (const exception& ex) {
@@ -135,5 +135,12 @@ void Reader::EIO_AfterNextRows(uv_work_t* req, int status) {
135135
argv[1] = Undefined();
136136
node::MakeCallback(Context::GetCurrent()->Global(), cb, 2, argv);
137137
}
138+
139+
baton->ResetRows();
140+
if (baton->done || baton->error) {
141+
// free occi resources so that we don't run out of cursors if gc is not fast enough
142+
// reader destructor will delete the baton and everything else.
143+
baton->ResetStatement();
144+
}
138145
}
139146

src/readerBaton.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@ class ReaderBaton : public ExecuteBaton {
1010
ReaderBaton(Connection* connection, const char* sql, v8::Local<v8::Array>* values) : ExecuteBaton(connection, sql, values, NULL) {
1111
stmt = NULL;
1212
rs = NULL;
13+
done = false;
1314
}
1415
~ReaderBaton() {
15-
if(stmt && rs) {
16-
stmt->closeResultSet(rs);
16+
ResetStatement();
17+
}
18+
19+
void ResetStatement() {
20+
if(stmt && rs) {
21+
stmt->closeResultSet(rs);
1722
rs = NULL;
1823
}
1924
if(stmt) {
@@ -27,6 +32,7 @@ class ReaderBaton : public ExecuteBaton {
2732
oracle::occi::Statement* stmt;
2833
oracle::occi::ResultSet* rs;
2934
int count;
35+
bool done;
3036
};
3137

3238
#endif

0 commit comments

Comments
 (0)