From 473e5532221e031f8723fc2c5b2267fc72c5d7cc Mon Sep 17 00:00:00 2001 From: florian <f.spreckelsen@inidscale.com> Date: Thu, 12 Aug 2021 11:16:55 +0200 Subject: [PATCH] DRAFT: Include a `_deletable` flag --- include/ccaosdb.h | 10 ++++++ src/ccaosdb.cpp | 83 ++++++++++++++++++++++++++++++++----------- test/test_ccaosdb.cpp | 16 ++++----- 3 files changed, 80 insertions(+), 29 deletions(-) diff --git a/include/ccaosdb.h b/include/ccaosdb.h index a0643a5..027a102 100644 --- a/include/ccaosdb.h +++ b/include/ccaosdb.h @@ -61,6 +61,7 @@ const char *caosdb_constants_COMPATIBLE_SERVER_VERSION_PRE_RELEASE(); */ typedef struct { void *wrapped_connection; + bool _deletable = false; } caosdb_connection_connection; /** @@ -72,6 +73,7 @@ typedef struct { */ typedef struct { void *wrapped_connection_configuration; + bool _deletable = false; } caosdb_connection_connection_configuration; /** @@ -91,10 +93,12 @@ typedef struct { typedef struct { void *wrapped_certificate_provider; + bool _deletable = false; } caosdb_connection_certificate_provider; typedef struct { void *wrapped_authenticator; + bool _deletable = false; } caosdb_authentication_authenticator; /** @@ -263,6 +267,7 @@ int caosdb_connection_connection_manager_get_connection( // not sufficient yet. typedef struct { void *wrapped_transaction; + bool _deletable = false; } caosdb_transaction_transaction; /** @@ -289,6 +294,7 @@ int caosdb_transaction_transaction_execute( typedef struct { void *wrapped_result_set; + bool _deletable = false; } caosdb_transaction_result_set; int caosdb_transaction_transaction_get_result_set( @@ -300,6 +306,7 @@ int caosdb_transaction_transaction_get_count_result( typedef struct { void *wrapped_entity; + bool _deletable = false; } caosdb_entity_entity; int caosdb_transaction_result_set_at(caosdb_transaction_result_set *result_set, @@ -309,12 +316,15 @@ int caosdb_transaction_result_set_size( typedef struct { void *wrapped_property; + bool _deletable = false; } caosdb_entity_property; typedef struct { void *wrapped_parent; + bool _deletable = false; } caosdb_entity_parent; typedef struct { void *wrapped_message; + bool _deletable = false; } caosdb_entity_message; // GETTERS FOR EVERYTHING diff --git a/src/ccaosdb.cpp b/src/ccaosdb.cpp index 4c9a4f0..23a4dc2 100644 --- a/src/ccaosdb.cpp +++ b/src/ccaosdb.cpp @@ -180,6 +180,7 @@ ERROR_RETURN_CODE(GENERIC_ERROR, out->wrapped_certificate_provider = new caosdb::configuration::PemFileCertificateProvider( std::string(path)); + out->_deletable = true; return 0; }) @@ -188,8 +189,11 @@ ERROR_RETURN_CODE( int caosdb_connection_delete_certificate_provider( caosdb_connection_certificate_provider *provider), { - delete static_cast<caosdb::configuration::CertificateProvider *>( - provider->wrapped_certificate_provider); + if (provider->_deletable) { + delete static_cast<caosdb::configuration::CertificateProvider *>( + provider->wrapped_certificate_provider); + } + provider->_deletable = false; return 0; }) @@ -201,17 +205,22 @@ ERROR_RETURN_CODE(GENERIC_ERROR, out->wrapped_authenticator = new caosdb::authentication::PlainPasswordAuthenticator( std::string(username), std::string(password)); + out->_deletable = true; return 0; }) -ERROR_RETURN_CODE(GENERIC_ERROR, - int caosdb_authentication_delete_authenticator( - caosdb_authentication_authenticator *authenticator), - { - delete static_cast<caosdb::authentication::Authenticator *>( - authenticator->wrapped_authenticator); - return 0; - }) +ERROR_RETURN_CODE( + GENERIC_ERROR, + int caosdb_authentication_delete_authenticator( + caosdb_authentication_authenticator *authenticator), + { + if (authenticator->_deletable) { + delete static_cast<caosdb::authentication::Authenticator *>( + authenticator->wrapped_authenticator); + } + authenticator->_deletable = false; + return 0; + }) ERROR_RETURN_CODE( GENERIC_ERROR, @@ -249,6 +258,7 @@ ERROR_RETURN_CODE( out->wrapped_connection_configuration = new caosdb::configuration::TlsConnectionConfiguration(host_str, port); } + out->_deletable = true; return 0; }) @@ -260,6 +270,7 @@ ERROR_RETURN_CODE( { out->wrapped_connection_configuration = new caosdb::configuration::InsecureConnectionConfiguration(host, port); + out->_deletable = true; return 0; }) @@ -268,8 +279,11 @@ ERROR_RETURN_CODE( int caosdb_connection_delete_connection_configuration( caosdb_connection_connection_configuration *configuration), { - delete static_cast<caosdb::configuration::ConnectionConfiguration *>( - configuration->wrapped_connection_configuration); + if (configuration->_deletable) { + delete static_cast<caosdb::configuration::ConnectionConfiguration *>( + configuration->wrapped_connection_configuration); + } + configuration->_deletable = false; return 0; }) @@ -283,6 +297,7 @@ ERROR_RETURN_CODE( static_cast<caosdb::configuration::ConnectionConfiguration *>( configuration->wrapped_connection_configuration); out->wrapped_connection = new caosdb::connection::Connection(*config); + out->_deletable = true; return 0; }) @@ -290,8 +305,11 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_connection_delete_connection( caosdb_connection_connection *connection), { - delete static_cast<caosdb::connection::Connection *>( - connection->wrapped_connection); + if (connection->_deletable) { + delete static_cast<caosdb::connection::Connection *>( + connection->wrapped_connection); + } + connection->_deletable = false; return 0; }) @@ -347,6 +365,9 @@ ERROR_RETURN_CODE(GENERIC_ERROR, caosdb::connection::ConnectionManager::GetConnection( std::string(name)) .get(); + // managed by the connection manager now, so not + // to be deleted manually + out->_deletable = false; return 0; }) @@ -363,6 +384,7 @@ ERROR_RETURN_CODE(GENERIC_ERROR, connection->wrapped_connection); out->wrapped_transaction = wrapped_connection->CreateTransaction().release(); + out->_deletable = true; return 0; }) @@ -370,8 +392,10 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_transaction_delete_transaction( caosdb_transaction_transaction *transaction), { - delete static_cast<caosdb::transaction::Transaction *>( - transaction->wrapped_transaction); + if (transaction->_deletable) { + delete static_cast<caosdb::transaction::Transaction *>( + transaction->wrapped_transaction); + } return 0; }) @@ -476,13 +500,17 @@ ERROR_RETURN_CODE(GENERIC_ERROR, ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_create_entity(caosdb_entity_entity *out), { out->wrapped_entity = new caosdb::entity::Entity(); + out->_deletable = true; return 0; }) ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_delete_entity(caosdb_entity_entity *out), { - delete static_cast<caosdb::entity::Entity *>( - out->wrapped_entity); + if (out->_deletable) { + delete static_cast<caosdb::entity::Entity *>( + out->wrapped_entity); + } + out->_deletable = false; return 0; }) @@ -490,26 +518,34 @@ ERROR_RETURN_CODE( GENERIC_ERROR, int caosdb_entity_create_property(caosdb_entity_property *out), { out->wrapped_property = new caosdb::entity::Property(); + out->_deletable = true; return 0; }) ERROR_RETURN_CODE( GENERIC_ERROR, int caosdb_entity_delete_property(caosdb_entity_property *out), { - delete static_cast<caosdb::entity::Property *>(out->wrapped_property); + if (out->_deletable) { + delete static_cast<caosdb::entity::Property *>(out->wrapped_property); + } + out->_deletable = false; return 0; }) ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_create_parent(caosdb_entity_parent *out), { out->wrapped_parent = new caosdb::entity::Parent(); + out->_deletable = true; return 0; }) ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_delete_parent(caosdb_entity_parent *out), { - delete static_cast<caosdb::entity::Parent *>( - out->wrapped_parent); + if (out->_deletable) { + delete static_cast<caosdb::entity::Parent *>( + out->wrapped_parent); + } + out->_deletable = false; return 0; }) @@ -543,6 +579,7 @@ ERROR_RETURN_CODE( auto *wrapped_entity = static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); out->wrapped_message = wrapped_entity->GetErrors().mutable_at(index); + out->_deletable = false; return 0; }) @@ -565,6 +602,7 @@ ERROR_RETURN_CODE( auto *wrapped_entity = static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); out->wrapped_message = wrapped_entity->GetWarnings().mutable_at(index); + out->_deletable = false; return 0; }) @@ -587,6 +625,7 @@ ERROR_RETURN_CODE( auto *wrapped_entity = static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); out->wrapped_message = wrapped_entity->GetInfos().mutable_at(index); + out->_deletable = false; return 0; }) @@ -609,6 +648,7 @@ ERROR_RETURN_CODE( auto *wrapped_entity = static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); out->wrapped_property = wrapped_entity->GetProperties().mutable_at(index); + out->_deletable = false; return 0; }) @@ -631,6 +671,7 @@ ERROR_RETURN_CODE( auto *wrapped_entity = static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); out->wrapped_parent = wrapped_entity->GetParents().mutable_at(index); + out->_deletable = false; return 0; }) diff --git a/test/test_ccaosdb.cpp b/test/test_ccaosdb.cpp index c957b3c..62ce930 100644 --- a/test/test_ccaosdb.cpp +++ b/test/test_ccaosdb.cpp @@ -324,13 +324,13 @@ TEST_F(test_ccaosdb, test_entity_with_parent_and_property) { return_code = caosdb_entity_delete_entity(&entity); EXPECT_EQ(return_code, 0); - // TODO(fspreck) This fails, because the output_p{arent,roperty} is owned - // by the entity (which is already deleted). Also, this shows that it is - // dangerous to call the deletion of output_p{arent,roperty} before the - // entity is being deleted, because it screws up the RepeatedPtrFieldWrapper. + // This tests the `_deletable` flag. The wrapped cpp objects of + // `output_parent` and `output_property` are owned by the entity, so + // they have been deleted together with the entity. With a wrong + // `_deletable` flag, the following would cause segfaults. // - // return_code = caosdb_entity_delete_parent(&output_parent); - // EXPECT_EQ(return_code, 0); - // return_code = caosdb_entity_delete_property(&output_property); - // EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_delete_parent(&output_parent); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_delete_property(&output_property); + EXPECT_EQ(return_code, 0); } -- GitLab