1
0
Fork 0

Fix memory leaks around LogicalCollection.

This commit is contained in:
Max Neunhoeffer 2016-10-04 11:56:35 +02:00
parent 21beb09d08
commit 0698065d63
7 changed files with 29 additions and 17 deletions

View File

@ -109,8 +109,11 @@ static void WeakCollectionCallback(const v8::WeakCallbackData<
} }
} }
///////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief wraps a LogicalCollection /// @brief wraps a LogicalCollection
/// Note that if collection is a local collection, then the object will never
/// be freed. If it is not a local collection (coordinator case), then delete
/// will be called when the V8 object is garbage collected.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
v8::Handle<v8::Object> WrapCollection(v8::Isolate* isolate, v8::Handle<v8::Object> WrapCollection(v8::Isolate* isolate,

View File

@ -178,7 +178,8 @@ static int ParseDocumentOrDocumentHandle(v8::Isolate* isolate,
try { try {
std::shared_ptr<LogicalCollection> col = std::shared_ptr<LogicalCollection> col =
ci->getCollection(vocbase->name(), collectionName); ci->getCollection(vocbase->name(), collectionName);
collection = col->clone(); auto colCopy = col->clone();
collection = colCopy.release();
} catch (...) { } catch (...) {
return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND; return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
} }
@ -2533,7 +2534,8 @@ static void JS_CollectionVocbase(
try { try {
std::shared_ptr<LogicalCollection> const ci = std::shared_ptr<LogicalCollection> const ci =
ClusterInfo::instance()->getCollection(vocbase->name(), name); ClusterInfo::instance()->getCollection(vocbase->name(), name);
collection = ci->clone(); auto colCopy = ci->clone();
collection = colCopy.release();
} catch (...) { } catch (...) {
// not found // not found
TRI_V8_RETURN_NULL(); TRI_V8_RETURN_NULL();

View File

@ -46,7 +46,12 @@ bool EqualCollection(arangodb::CollectionNameResolver const* resolver,
std::string const& collectionName, std::string const& collectionName,
arangodb::LogicalCollection const* collection); arangodb::LogicalCollection const* collection);
////////////////////////////////////////////////////////////////////////////////
/// @brief wraps a LogicalCollection /// @brief wraps a LogicalCollection
/// Note that if collection is a local collection, then the object will never
/// be freed. If it is not a local collection (coordinator case), then delete
/// will be called when the V8 object is garbage collected.
////////////////////////////////////////////////////////////////////////////////
v8::Handle<v8::Object> WrapCollection( v8::Handle<v8::Object> WrapCollection(
v8::Isolate* isolate, arangodb::LogicalCollection const* collection); v8::Isolate* isolate, arangodb::LogicalCollection const* collection);

View File

@ -1869,7 +1869,8 @@ static void MapGetVocBase(v8::Local<v8::String> const name,
if (ServerState::instance()->isCoordinator()) { if (ServerState::instance()->isCoordinator()) {
auto ci = ClusterInfo::instance()->getCollection(vocbase->name(), auto ci = ClusterInfo::instance()->getCollection(vocbase->name(),
std::string(key)); std::string(key));
collection = ci->clone(); auto colCopy = ci->clone();
collection = colCopy.release(); // will be delete on garbage collection
} else { } else {
collection = vocbase->lookupCollection(std::string(key)); collection = vocbase->lookupCollection(std::string(key));
} }

View File

@ -633,7 +633,7 @@ static void EnsureIndex(v8::FunctionCallbackInfo<v8::Value> const& args,
/// @brief create a collection on the coordinator /// @brief create a collection on the coordinator
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
LogicalCollection* CreateCollectionCoordinator(LogicalCollection* parameters) { std::unique_ptr<LogicalCollection> CreateCollectionCoordinator(LogicalCollection* parameters) {
std::string distributeShardsLike = parameters->distributeShardsLike(); std::string distributeShardsLike = parameters->distributeShardsLike();
std::vector<std::string> dbServers; std::vector<std::string> dbServers;
@ -664,8 +664,6 @@ LogicalCollection* CreateCollectionCoordinator(LogicalCollection* parameters) {
parameters->distributeShardsLike(otherCidString); parameters->distributeShardsLike(otherCidString);
} }
} }
// If the list dbServers is still empty, it will be filled in // If the list dbServers is still empty, it will be filled in
// distributeShards below. // distributeShards below.
@ -699,8 +697,7 @@ LogicalCollection* CreateCollectionCoordinator(LogicalCollection* parameters) {
// collection does not exist. Also, the create collection should have // collection does not exist. Also, the create collection should have
// failed before. // failed before.
TRI_ASSERT(c != nullptr); TRI_ASSERT(c != nullptr);
std::unique_ptr<LogicalCollection> newCol(c->clone()); return c->clone();
return newCol.release();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -1079,11 +1076,11 @@ static void CreateVocBase(v8::FunctionCallbackInfo<v8::Value> const& args,
#ifndef USE_ENTERPRISE #ifndef USE_ENTERPRISE
auto parameters = std::make_unique<LogicalCollection>(vocbase, infoSlice, false); auto parameters = std::make_unique<LogicalCollection>(vocbase, infoSlice, false);
TRI_V8_RETURN( TRI_V8_RETURN(
WrapCollection(isolate, CreateCollectionCoordinator(parameters.get()))); WrapCollection(isolate, CreateCollectionCoordinator(parameters.get()).release()));
#else #else
TRI_V8_RETURN( TRI_V8_RETURN(
WrapCollection(isolate, CreateCollectionCoordinatorEnterprise( WrapCollection(isolate, CreateCollectionCoordinatorEnterprise(
collectionType, vocbase, infoSlice))); collectionType, vocbase, infoSlice).release()));
#endif #endif
} }

View File

@ -50,11 +50,13 @@ void TRI_InitV8indexCollection(v8::Isolate* isolate,
v8::Handle<v8::ObjectTemplate> rt); v8::Handle<v8::ObjectTemplate> rt);
// This could be static but is used in enterprise version as well // This could be static but is used in enterprise version as well
arangodb::LogicalCollection* CreateCollectionCoordinator( // Note that this returns a newly allocated object and ownership is transferred
// to the caller, which is expressed by the returned unique_ptr.
std::unique_ptr<arangodb::LogicalCollection> CreateCollectionCoordinator(
arangodb::LogicalCollection* parameters); arangodb::LogicalCollection* parameters);
#ifdef USE_ENTERPRISE #ifdef USE_ENTERPRISE
arangodb::LogicalCollection* CreateCollectionCoordinatorEnterprise( std::unique_ptr<arangodb::LogicalCollection> CreateCollectionCoordinatorEnterprise(
TRI_col_type_e collectionType, TRI_vocbase_t* vocbase, TRI_col_type_e collectionType, TRI_vocbase_t* vocbase,
arangodb::velocypack::Slice parameters); arangodb::velocypack::Slice parameters);
#endif #endif

View File

@ -68,17 +68,19 @@ class LogicalCollection {
public: public:
LogicalCollection(TRI_vocbase_t*, arangodb::velocypack::Slice const&, bool isPhysical); LogicalCollection(TRI_vocbase_t*, arangodb::velocypack::Slice const&, bool isPhysical);
explicit LogicalCollection(LogicalCollection const&);
virtual ~LogicalCollection(); virtual ~LogicalCollection();
protected: // If you need a copy outside the class, use clone below.
explicit LogicalCollection(LogicalCollection const&);
private: private:
LogicalCollection& operator=(LogicalCollection const&) = delete; LogicalCollection& operator=(LogicalCollection const&) = delete;
public: public:
LogicalCollection() = delete; LogicalCollection() = delete;
virtual LogicalCollection* clone() { virtual std::unique_ptr<LogicalCollection> clone() {
return new LogicalCollection(*this); auto p = new LogicalCollection(*this);
return std::unique_ptr<LogicalCollection>(p);
} }
/// @brief hard-coded minimum version number for collections /// @brief hard-coded minimum version number for collections