This is an automated email from the ASF dual-hosted git repository. pnoltes pushed a commit to branch feature/cap_req_model_lib in repository https://gitbox.apache.org/repos/asf/celix.git
commit 5df30b1e6d66567650d6df6270cb4c311ab39d8e Author: Pepijn Noltes <[email protected]> AuthorDate: Sat Apr 8 20:42:32 2023 +0200 Add celix array list ei and improve er test for librcm --- libs/CMakeLists.txt | 14 ++- libs/error_injector/CMakeLists.txt | 1 + .../error_injector/celix_array_list/CMakeLists.txt | 35 +++++++ .../celix_array_list/include/celix_array_list_ei.h | 54 +++++++++++ .../celix_array_list/src/celix_array_list_ei.cc | 102 +++++++++++++++++++++ libs/rcm/gtest/CMakeLists.txt | 17 ++-- .../src/RequirementCapabilityModelTestSuite.cc | 4 + ...ntCapabilityModelWithErrorInjectionTestSuite.cc | 54 ++++++++++- libs/rcm/src/celix_rcm_err.c | 13 +-- libs/rcm/src/celix_rcm_err_private.h | 1 - libs/rcm/src/celix_resource.c | 39 ++++++-- libs/utils/include/celix_array_list.h | 27 ++++-- libs/utils/include_deprecated/array_list.h | 2 +- libs/utils/src/array_list.c | 63 ++++++++----- 14 files changed, 355 insertions(+), 71 deletions(-) diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt index 20b51203..d4be91e5 100644 --- a/libs/CMakeLists.txt +++ b/libs/CMakeLists.txt @@ -18,15 +18,18 @@ #utils, dfi and etcdlib are standalone #(e.g. no dependency on celix framework add_subdirectory(utils) + +# Error Injectors +if (ENABLE_TESTING AND LINKER_WRAP_SUPPORTED) + add_subdirectory(error_injector) +endif () + add_subdirectory(dfi) add_subdirectory(etcdlib) add_subdirectory(promises) add_subdirectory(pushstreams) add_subdirectory(rcm) - add_subdirectory(framework) - -#launcher add_subdirectory(launcher) #add_subdirectory(event_admin)# event_admin is unstable @@ -35,8 +38,3 @@ if (CELIX_CXX14) add_subdirectory(dependency_manager_cxx) endif () -# Error Injectors -if (ENABLE_TESTING AND LINKER_WRAP_SUPPORTED) - add_subdirectory(error_injector) -endif () - diff --git a/libs/error_injector/CMakeLists.txt b/libs/error_injector/CMakeLists.txt index 37f78c57..3092c26a 100644 --- a/libs/error_injector/CMakeLists.txt +++ b/libs/error_injector/CMakeLists.txt @@ -26,6 +26,7 @@ add_library(Celix::error_injector ALIAS error_injector) add_subdirectory(malloc) add_subdirectory(asprintf) add_subdirectory(celix_properties) +add_subdirectory(celix_array_list) add_subdirectory(celix_utils) add_subdirectory(zip) add_subdirectory(stdio) diff --git a/libs/error_injector/celix_array_list/CMakeLists.txt b/libs/error_injector/celix_array_list/CMakeLists.txt new file mode 100644 index 00000000..9954bf00 --- /dev/null +++ b/libs/error_injector/celix_array_list/CMakeLists.txt @@ -0,0 +1,35 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +add_library(array_list_ei STATIC src/celix_array_list_ei.cc) + +target_include_directories(array_list_ei PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) +target_link_libraries(array_list_ei PUBLIC Celix::error_injector Celix::utils) +target_link_options(array_list_ei INTERFACE + LINKER:--wrap,celix_arrayList_create + LINKER:--wrap,celix_arrayList_createWithOptions + LINKER:--wrap,celix_arrayList_add + LINKER:--wrap,celix_arrayList_addInt + LINKER:--wrap,celix_arrayList_addLong + LINKER:--wrap,celix_arrayList_addUInt + LINKER:--wrap,celix_arrayList_addULong + LINKER:--wrap,celix_arrayList_addFloat + LINKER:--wrap,celix_arrayList_addDouble + LINKER:--wrap,celix_arrayList_addBool + LINKER:--wrap,celix_arrayList_addSize +) +add_library(Celix::array_list_ei ALIAS array_list_ei) diff --git a/libs/error_injector/celix_array_list/include/celix_array_list_ei.h b/libs/error_injector/celix_array_list/include/celix_array_list_ei.h new file mode 100644 index 00000000..0184c128 --- /dev/null +++ b/libs/error_injector/celix_array_list/include/celix_array_list_ei.h @@ -0,0 +1,54 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +#ifndef CELIX_CELIX_ARRAY_LIST_EI_H +#define CELIX_CELIX_ARRAY_LIST_EI_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "celix_array_list.h" +#include "celix_error_injector.h" + +CELIX_EI_DECLARE(celix_arrayList_create, celix_array_list_t*); + +CELIX_EI_DECLARE(celix_arrayList_createWithOptions, celix_array_list_t*); + +CELIX_EI_DECLARE(celix_arrayList_add, celix_status_t); + +CELIX_EI_DECLARE(celix_arrayList_addInt, celix_status_t); + +CELIX_EI_DECLARE(celix_arrayList_addLong, celix_status_t); + +CELIX_EI_DECLARE(celix_arrayList_addUInt, celix_status_t); + +CELIX_EI_DECLARE(celix_arrayList_addULong, celix_status_t); + +CELIX_EI_DECLARE(celix_arrayList_addFloat, celix_status_t); + +CELIX_EI_DECLARE(celix_arrayList_addDouble, celix_status_t); + +//CELIX_EI_DECLARE(celix_arrayList_addBool, celix_status_t); + +CELIX_EI_DECLARE(celix_arrayList_addSize, celix_status_t); + +#ifdef __cplusplus +} +#endif +#endif //CELIX_CELIX_ARRAY_LIST_EI_H diff --git a/libs/error_injector/celix_array_list/src/celix_array_list_ei.cc b/libs/error_injector/celix_array_list/src/celix_array_list_ei.cc new file mode 100644 index 00000000..6916b5f8 --- /dev/null +++ b/libs/error_injector/celix_array_list/src/celix_array_list_ei.cc @@ -0,0 +1,102 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +#include "celix_array_list_ei.h" + +extern "C" { + +void *__real_celix_arrayList_create(void); +CELIX_EI_DEFINE(celix_arrayList_create, celix_array_list_t*) +void *__wrap_celix_arrayList_create(void) { + CELIX_EI_IMPL(celix_arrayList_create); + return __real_celix_arrayList_create(); +} + +void *__real_celix_arrayList_createWithOptions(const celix_array_list_create_options_t* opts); +CELIX_EI_DEFINE(celix_arrayList_createWithOptions, celix_array_list_t*) +void *__wrap_celix_arrayList_createWithOptions(const celix_array_list_create_options_t* opts) { + CELIX_EI_IMPL(celix_arrayList_createWithOptions); + return __real_celix_arrayList_createWithOptions(opts); +} + +celix_status_t __real_celix_arrayList_add(celix_array_list_t* list, void* value); +CELIX_EI_DEFINE(celix_arrayList_add, celix_status_t) +celix_status_t __wrap_celix_arrayList_add(celix_array_list_t* list, void* value) { + CELIX_EI_IMPL_POSITIVE(celix_arrayList_add); + return __real_celix_arrayList_add(list, value); +} + +celix_status_t __real_celix_arrayList_addInt(celix_array_list_t* list, int value); +CELIX_EI_DEFINE(celix_arrayList_addInt, celix_status_t) +celix_status_t __wrap_celix_arrayList_addInt(celix_array_list_t* list, int value) { + CELIX_EI_IMPL_POSITIVE(celix_arrayList_addInt); + return __real_celix_arrayList_addInt(list, value); +} + +celix_status_t __real_celix_arrayList_addLong(celix_array_list_t* list, long value); +CELIX_EI_DEFINE(celix_arrayList_addLong, celix_status_t) +celix_status_t __wrap_celix_arrayList_addLong(celix_array_list_t* list, long value) { + CELIX_EI_IMPL_POSITIVE(celix_arrayList_addLong); + return __real_celix_arrayList_addLong(list, value); +} + +celix_status_t __real_celix_arrayList_addUInt(celix_array_list_t* list, unsigned int value); +CELIX_EI_DEFINE(celix_arrayList_addUInt, celix_status_t) +celix_status_t __wrap_celix_arrayList_addUInt(celix_array_list_t* list, unsigned int value) { + CELIX_EI_IMPL_POSITIVE(celix_arrayList_addUInt); + return __real_celix_arrayList_addUInt(list, value); +} + +celix_status_t __real_celix_arrayList_addULong(celix_array_list_t* list, unsigned long value); +CELIX_EI_DEFINE(celix_arrayList_addULong, celix_status_t) +celix_status_t __wrap_celix_arrayList_addULong(celix_array_list_t* list, unsigned long value) { + CELIX_EI_IMPL_POSITIVE(celix_arrayList_addULong); + return __real_celix_arrayList_addULong(list, value); +} + +celix_status_t __real_celix_arrayList_addFloat(celix_array_list_t* list, float value); +CELIX_EI_DEFINE(celix_arrayList_addFloat, celix_status_t) +celix_status_t __wrap_celix_arrayList_addFloat(celix_array_list_t* list, float value) { + CELIX_EI_IMPL_POSITIVE(celix_arrayList_addFloat); + return __real_celix_arrayList_addFloat(list, value); +} + +celix_status_t __real_celix_arrayList_addDouble(celix_array_list_t* list, double value); +CELIX_EI_DEFINE(celix_arrayList_addDouble, celix_status_t) +celix_status_t __wrap_celix_arrayList_addDouble(celix_array_list_t* list, double value) { + CELIX_EI_IMPL_POSITIVE(celix_arrayList_addDouble); + return __real_celix_arrayList_addDouble(list, value); +} + +//TODO +//celix_status_t __real_celix_arrayList_addBool(celix_array_list_t* list, bool value); +//CELIX_EI_DEFINE(celix_arrayList_addBool, celix_status_t) +//celix_status_t __wrap_celix_arrayList_addBool(celix_array_list_t* list, bool value) +// CELIX_EI_IMPL_POSITIVE(celix_arrayList_addBool); +// return __real_celix_arrayList_addBool(list, value); +//} + +celix_status_t __real_celix_arrayList_addSize(celix_array_list_t* list, size_t value); +CELIX_EI_DEFINE(celix_arrayList_addSize, celix_status_t) +celix_status_t __wrap_celix_arrayList_addSize(celix_array_list_t* list, size_t value) { + CELIX_EI_IMPL_POSITIVE(celix_arrayList_addSize); + return __real_celix_arrayList_addSize(list, value); +} + +} diff --git a/libs/rcm/gtest/CMakeLists.txt b/libs/rcm/gtest/CMakeLists.txt index baa924f3..52d3b485 100644 --- a/libs/rcm/gtest/CMakeLists.txt +++ b/libs/rcm/gtest/CMakeLists.txt @@ -25,10 +25,13 @@ target_link_libraries(test_rcm PRIVATE Celix::rcm GTest::gtest GTest::gtest_main add_test(NAME test_rcm COMMAND test_rcm) setup_target_for_coverage(test_rcm SCAN_DIR ..) -add_executable(test_rcm_with_error_injection - src/RequirementCapabilityModelWithErrorInjectionTestSuite.cc -) -target_link_libraries(test_rcm_with_error_injection PRIVATE Celix::rcm GTest::gtest GTest::gtest_main) -target_link_libraries(test_rcm_with_error_injection PRIVATE Celix::malloc_ei Celix::utils_ei) -add_test(NAME test_rcm_with_error_injection COMMAND test_rcm_with_error_injection) -setup_target_for_coverage(test_rcm_with_error_injection SCAN_DIR ..) +if (LINKER_WRAP_SUPPORTED) + add_executable(test_rcm_with_error_injection + src/RequirementCapabilityModelWithErrorInjectionTestSuite.cc + ) + target_link_libraries(test_rcm_with_error_injection PRIVATE Celix::rcm GTest::gtest GTest::gtest_main) + target_link_libraries(test_rcm_with_error_injection PRIVATE Celix::malloc_ei Celix::utils_ei Celix::array_list_ei) + add_test(NAME test_rcm_with_error_injection COMMAND test_rcm_with_error_injection) + setup_target_for_coverage(test_rcm_with_error_injection SCAN_DIR ..) +endif () + diff --git a/libs/rcm/gtest/src/RequirementCapabilityModelTestSuite.cc b/libs/rcm/gtest/src/RequirementCapabilityModelTestSuite.cc index b9c7d555..50db0e5e 100644 --- a/libs/rcm/gtest/src/RequirementCapabilityModelTestSuite.cc +++ b/libs/rcm/gtest/src/RequirementCapabilityModelTestSuite.cc @@ -25,11 +25,14 @@ #include "celix_resource.h" #include "celix_rcm_err.h" +extern void celix_rcm_deinitThreadSpecificStorageKey(); //private function, used to ensure coverage + class RequirementCapabilityModelTestSuite : public ::testing::Test {}; TEST_F(RequirementCapabilityModelTestSuite, TestRequirement) { celix_requirement_t* req = celix_requirement_create(nullptr, "test-namespace", "(&(capability.attribute1=foo)(capability.attribute2=bar))"); ASSERT_TRUE(req != nullptr); + EXPECT_TRUE(celix_requirement_equals(req, req)); EXPECT_STREQ("test-namespace", celix_requirement_getNamespace(req)); EXPECT_STREQ("(&(capability.attribute1=foo)(capability.attribute2=bar))", celix_requirement_getFilter(req)); @@ -77,6 +80,7 @@ TEST_F(RequirementCapabilityModelTestSuite, TestRequirement) { TEST_F(RequirementCapabilityModelTestSuite, TestCapability) { celix_capability_t* cap = celix_capability_create(nullptr, "test-namespace"); ASSERT_TRUE(cap != nullptr); + EXPECT_TRUE(celix_capability_equals(cap, cap)); EXPECT_STREQ("test-namespace", celix_capability_getNamespace(cap)); celix_capability_t* cap2 = celix_capability_create(nullptr, "test-namespace"); diff --git a/libs/rcm/gtest/src/RequirementCapabilityModelWithErrorInjectionTestSuite.cc b/libs/rcm/gtest/src/RequirementCapabilityModelWithErrorInjectionTestSuite.cc index 40c08741..33bec6e9 100644 --- a/libs/rcm/gtest/src/RequirementCapabilityModelWithErrorInjectionTestSuite.cc +++ b/libs/rcm/gtest/src/RequirementCapabilityModelWithErrorInjectionTestSuite.cc @@ -19,8 +19,11 @@ #include <gtest/gtest.h> +#include <memory> + #include "malloc_ei.h" #include "celix_utils_ei.h" +#include "celix_array_list_ei.h" #include "celix/Properties.h" #include "celix_capability.h" @@ -35,7 +38,9 @@ public: ~RequirementCapabilityModelWithErrorInjectionTestSuite() override { celix_ei_expect_malloc(nullptr, 0, nullptr); celix_ei_expect_celix_utils_strdup(nullptr, 0, nullptr); - //TODO add celix_ei_expect_celix_arrayList_create(nullptr, 0, nullptr); + celix_ei_expect_celix_arrayList_createWithOptions(nullptr, 0, nullptr); + celix_ei_expect_celix_arrayList_create(nullptr, 0, nullptr); + celix_ei_expect_celix_arrayList_add(nullptr, 0, CELIX_SUCCESS); celix_rcmErr_resetErrors(); } }; @@ -77,9 +82,50 @@ TEST_F(RequirementCapabilityModelWithErrorInjectionTestSuite, TestResourceErrorH EXPECT_EQ(nullptr, res); EXPECT_EQ(1, celix_rcmErr_getErrorCount()); - //TODO inject error on first celix_arrayList_create call from celix_resource_create + //inject error on first celix_arrayList_createWithOptions call from celix_resource_create + celix_ei_expect_celix_arrayList_createWithOptions((void*)celix_resource_create, 0, nullptr); + res = celix_resource_create(); + EXPECT_EQ(nullptr, res); + EXPECT_EQ(2, celix_rcmErr_getErrorCount()); + + res = celix_resource_create(); + EXPECT_NE(nullptr, res); + celix_capability_t* cap = celix_capability_create(res, "test"); + EXPECT_NE(nullptr, cap); + celix_requirement_t* req = celix_requirement_create(res, "test", nullptr); + EXPECT_NE(nullptr, req); + + //inject error on first celix_arrayList_create call from celix_resource_addCapability + celix_ei_expect_celix_arrayList_create((void*)celix_resource_addCapability, 0, nullptr); + EXPECT_FALSE(celix_resource_addCapability(res, cap)); + EXPECT_EQ(3, celix_rcmErr_getErrorCount()); + + //inject error on first celix_arrayList_add call from celix_resource_addCapability + celix_ei_expect_celix_arrayList_add((void*)celix_resource_addCapability, 0, CELIX_ENOMEM); + EXPECT_FALSE(celix_resource_addCapability(res, cap)); + EXPECT_EQ(4, celix_rcmErr_getErrorCount()); + + //inject error on second celix_arrayList_add call from celix_resource_addCapability + celix_ei_expect_celix_arrayList_add((void*)celix_resource_addCapability, 0, CELIX_ENOMEM, 2); + EXPECT_FALSE(celix_resource_addCapability(res, cap)); + EXPECT_EQ(5, celix_rcmErr_getErrorCount()); + + //inject error on first celix_arrayList_create call from celix_resource_addRequirement + celix_ei_expect_celix_arrayList_create((void*)celix_resource_addRequirement, 0, nullptr); + EXPECT_FALSE(celix_resource_addRequirement(res, req)); + EXPECT_EQ(6, celix_rcmErr_getErrorCount()); + + //inject error on first celix_arrayList_add call from celix_resource_addRequirement + celix_ei_expect_celix_arrayList_add((void*)celix_resource_addRequirement, 0, CELIX_ENOMEM); + EXPECT_FALSE(celix_resource_addRequirement(res, req)); + EXPECT_EQ(7, celix_rcmErr_getErrorCount()); - //TODO inject error on first celix_arrayList_create call from celix_resource_addCapability + //inject error on second celix_arrayList_add call from celix_resource_addRequirement + celix_ei_expect_celix_arrayList_add((void*)celix_resource_addRequirement, 0, CELIX_ENOMEM, 2); + EXPECT_FALSE(celix_resource_addRequirement(res, req)); + EXPECT_EQ(8, celix_rcmErr_getErrorCount()); - //TODO inject error on first celix_arrayList_create call from celix_resource_addRequirement + celix_capability_destroy(cap); + celix_requirement_destroy(req); + celix_resource_destroy(res); } \ No newline at end of file diff --git a/libs/rcm/src/celix_rcm_err.c b/libs/rcm/src/celix_rcm_err.c index 8938726e..f3a32ab5 100644 --- a/libs/rcm/src/celix_rcm_err.c +++ b/libs/rcm/src/celix_rcm_err.c @@ -42,12 +42,12 @@ static void celix_rcm_destroyTssErrors(void* data) { celix_arrayList_destroy(errors); } -__attribute__((constructor)) static void celix_rcm_initThreadSpecificStorageKey() { +__attribute__((constructor)) void celix_rcm_initThreadSpecificStorageKey() { //tss_create(&celix_rcm_tssErrorsKey, celix_rcm_destroyTssErrors); pthread_key_create(&celix_rcm_tssErrorsKey, celix_rcm_destroyTssErrors); } -__attribute__((destructor)) static void celix_rcm_deinitThreadSpecificStorageKey() { +__attribute__((destructor)) void celix_rcm_deinitThreadSpecificStorageKey() { //tss_delete(celix_rcm_tssErrorsKey); pthread_key_delete(celix_rcm_tssErrorsKey); } @@ -76,13 +76,8 @@ int celix_rcmErr_getErrorCount() { void celix_rcmErr_resetErrors() { //celix_array_list_t* errors = tss_get(celix_rcm_tssErrorsKey); celix_array_list_t* errors = pthread_getspecific(celix_rcm_tssErrorsKey); - if (errors != NULL) { - for (int i = 0; i < celix_arrayList_size(errors); ++i) { - char* msg = celix_arrayList_get(errors, i); - free(msg); - } - celix_arrayList_clear(errors); - } + celix_rcm_destroyTssErrors(errors); + pthread_setspecific(celix_rcm_tssErrorsKey, NULL); } static void celix_rcm_pushMsg(char* msg) { diff --git a/libs/rcm/src/celix_rcm_err_private.h b/libs/rcm/src/celix_rcm_err_private.h index 83b353be..b6bce443 100644 --- a/libs/rcm/src/celix_rcm_err_private.h +++ b/libs/rcm/src/celix_rcm_err_private.h @@ -34,7 +34,6 @@ void celix_rcmErr_pushf(char* format, ...) __attribute__((format(printf, 1, 2))) */ void celix_rcmErr_push(const char* msg); - #ifdef __cplusplus } #endif diff --git a/libs/rcm/src/celix_resource.c b/libs/rcm/src/celix_resource.c index fbe51083..3dd25782 100644 --- a/libs/rcm/src/celix_resource.c +++ b/libs/rcm/src/celix_resource.c @@ -168,19 +168,30 @@ bool celix_resource_addCapability(celix_resource_t* res, celix_capability_t* cap return false; } - celix_arrayList_add(res->allCapabilities, cap); const char* ns = celix_capability_getNamespace(cap); celix_array_list_t* caps = celix_stringHashMap_get(res->capabilitiesByNamespace, ns); if (caps == NULL) { caps = celix_arrayList_create(); if (caps == NULL) { - celix_rcmErr_push("Failed to allocate capabilities list. Out of memory."); - return false; + goto err_handling; } celix_stringHashMap_put(res->capabilitiesByNamespace, ns, caps); } - celix_arrayList_add(caps, cap); + celix_status_t status = celix_arrayList_add(caps, cap); + if (status != CELIX_SUCCESS) { + goto err_handling; + } + status = celix_arrayList_add(res->allCapabilities, cap); + if (status != CELIX_SUCCESS) { + goto err_handling; + } return true; +err_handling: + celix_rcmErr_push("Failed to add capability to resource. Out of memory."); + if (caps != NULL) { + celix_arrayList_remove(caps, cap); + } + return false; } bool celix_resource_addRequirement(celix_resource_t* res, celix_requirement_t* req) { @@ -191,17 +202,29 @@ bool celix_resource_addRequirement(celix_resource_t* res, celix_requirement_t* r return false; } - celix_arrayList_add(res->allRequirements, req); const char* ns = celix_requirement_getNamespace(req); celix_array_list_t* reqs = celix_stringHashMap_get(res->requirementsByNamespace, ns); if (reqs == NULL) { reqs = celix_arrayList_create(); if (reqs == NULL) { - celix_rcmErr_push("Failed to allocate requirement list. Out of memory."); - return false; + goto err_handling; } celix_stringHashMap_put(res->requirementsByNamespace, ns, reqs); } - celix_arrayList_add(reqs, req); + celix_status_t status = celix_arrayList_add(reqs, req); + if (status != CELIX_SUCCESS) { + goto err_handling; + } + status = celix_arrayList_add(res->allRequirements, req); + if (status != CELIX_SUCCESS) { + goto err_handling; + } + return true; +err_handling: + celix_rcmErr_push("Failed to add requirement to resource. Out of memory."); + if (reqs != NULL) { + celix_arrayList_remove(reqs, req); + } + return false; } diff --git a/libs/utils/include/celix_array_list.h b/libs/utils/include/celix_array_list.h index 77e174ec..28c48ec4 100644 --- a/libs/utils/include/celix_array_list.h +++ b/libs/utils/include/celix_array_list.h @@ -230,72 +230,81 @@ size_t celix_arrayList_getSize(const celix_array_list_t *list, int index); * * @param map The array list. * @param value The pointer value to add to the array list. + * @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory. */ -void celix_arrayList_add(celix_array_list_t *list, void* value); +celix_status_t celix_arrayList_add(celix_array_list_t *list, void* value); /** * @brief add pointer entry to the back of the array list. * * @param map The array list. * @param value The int value to add to the array list. + * @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory. */ -void celix_arrayList_addInt(celix_array_list_t *list, int value); +celix_status_t celix_arrayList_addInt(celix_array_list_t *list, int value); /** * @brief add pointer entry to the back of the array list. * * @param map The array list. * @param value The long value to add to the array list. + * @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory. */ -void celix_arrayList_addLong(celix_array_list_t *list, long value); +celix_status_t celix_arrayList_addLong(celix_array_list_t *list, long value); /** * @brief add pointer entry to the back of the array list. * * @param map The array list. * @param value The unsigned int value to add to the array list. + * @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory. */ -void celix_arrayList_addUInt(celix_array_list_t *list, unsigned int value); +celix_status_t celix_arrayList_addUInt(celix_array_list_t *list, unsigned int value); /** * @brief add pointer entry to the back of the array list. * * @param map The array list. * @param value The unsigned long value to add to the array list. + * @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory. */ -void celix_arrayList_addULong(celix_array_list_t *list, unsigned long value); +celix_status_t celix_arrayList_addULong(celix_array_list_t *list, unsigned long value); /** * @brief add pointer entry to the back of the array list. * * @param map The array list. * @param value The float value to add to the array list. + * @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory. */ -void celix_arrayList_addFloat(celix_array_list_t *list, float value); +celix_status_t celix_arrayList_addFloat(celix_array_list_t *list, float value); /** * @brief add pointer entry to the back of the array list. * * @param map The array list. * @param value The double value to add to the array list. + * @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory. */ -void celix_arrayList_addDouble(celix_array_list_t *list, double value); +celix_status_t celix_arrayList_addDouble(celix_array_list_t *list, double value); /** * @brief add pointer entry to the back of the array list. * * @param map The array list. * @param value The bool value to add to the array list. + * @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory. */ -void celix_arrayList_addBool(celix_array_list_t *list, bool value); +celix_status_t celix_arrayList_addBool(celix_array_list_t *list, bool value); /** * @brief add pointer entry to the back of the array list. * * @param map The array list. * @param value The size_t value to add to the array list. + * @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list is out of memory. */ -void celix_arrayList_addSize(celix_array_list_t *list, size_t value); +celix_status_t celix_arrayList_addSize(celix_array_list_t *list, size_t value); /** * @brief Returns the index of the provided entry, if found. diff --git a/libs/utils/include_deprecated/array_list.h b/libs/utils/include_deprecated/array_list.h index cde701da..ca4c23f7 100644 --- a/libs/utils/include_deprecated/array_list.h +++ b/libs/utils/include_deprecated/array_list.h @@ -47,7 +47,7 @@ UTILS_EXPORT void arrayList_destroy(celix_array_list_t *list); UTILS_EXPORT void arrayList_trimToSize(celix_array_list_t *list); -UTILS_EXPORT void arrayList_ensureCapacity(celix_array_list_t *list, int capacity); +UTILS_EXPORT celix_status_t arrayList_ensureCapacity(celix_array_list_t *list, int capacity); UTILS_EXPORT unsigned int arrayList_size(celix_array_list_t *list); diff --git a/libs/utils/src/array_list.c b/libs/utils/src/array_list.c index 27c32010..746f4dcd 100644 --- a/libs/utils/src/array_list.c +++ b/libs/utils/src/array_list.c @@ -90,7 +90,8 @@ void arrayList_trimToSize(array_list_pt list) { } } -void arrayList_ensureCapacity(array_list_pt list, int capacity) { +celix_status_t arrayList_ensureCapacity(array_list_pt list, int capacity) { + celix_status_t status = CELIX_SUCCESS; celix_array_list_entry_t *newList; list->modCount++; size_t oldCapacity = list->capacity; @@ -100,9 +101,13 @@ void arrayList_ensureCapacity(array_list_pt list, int capacity) { newCapacity = capacity; } newList = realloc(list->elementData, sizeof(celix_array_list_entry_t) * newCapacity); - list->capacity = newCapacity; - list->elementData = newList; + if (newList != NULL) { + list->capacity = newCapacity; + list->elementData = newList; + } + status = newList == NULL ? CELIX_ENOMEM : CELIX_SUCCESS; } + return status; } unsigned int arrayList_size(array_list_pt list) { @@ -420,65 +425,75 @@ double celix_arrayList_getDouble(const celix_array_list_t *list, int index) { re bool celix_arrayList_getBool(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).boolVal; } size_t celix_arrayList_getSize(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).sizeVal; } -static void arrayList_addEntry(celix_array_list_t *list, celix_array_list_entry_t entry) { - arrayList_ensureCapacity(list, (int)list->size + 1); - list->elementData[list->size++] = entry; +static celix_status_t celix_arrayList_addEntry(celix_array_list_t *list, celix_array_list_entry_t entry) { + celix_status_t status = arrayList_ensureCapacity(list, (int)list->size + 1); + if (status == CELIX_SUCCESS) { + list->elementData[list->size++] = entry; + } + return status; } -void celix_arrayList_add(celix_array_list_t *list, void * element) { +celix_status_t celix_arrayList_add(celix_array_list_t *list, void * element) { celix_array_list_entry_t entry; memset(&entry, 0, sizeof(entry)); entry.voidPtrVal = element; - arrayList_addEntry(list, entry); + return celix_arrayList_addEntry(list, entry); } -void celix_arrayList_addInt(celix_array_list_t *list, int val) { +celix_status_t celix_arrayList_addInt(celix_array_list_t *list, int val) { celix_array_list_entry_t entry; memset(&entry, 0, sizeof(entry)); entry.intVal = val; - arrayList_addEntry(list, entry); + return celix_arrayList_addEntry(list, entry); } -void celix_arrayList_addLong(celix_array_list_t *list, long val) { + +celix_status_t celix_arrayList_addLong(celix_array_list_t *list, long val) { celix_array_list_entry_t entry; memset(&entry, 0, sizeof(entry)); entry.longVal = val; - arrayList_addEntry(list, entry); + return celix_arrayList_addEntry(list, entry); } -void celix_arrayList_addUInt(celix_array_list_t *list, unsigned int val) { + +celix_status_t celix_arrayList_addUInt(celix_array_list_t *list, unsigned int val) { celix_array_list_entry_t entry; memset(&entry, 0, sizeof(entry)); entry.uintVal = val; - arrayList_addEntry(list, entry); + return celix_arrayList_addEntry(list, entry); } -void celix_arrayList_addULong(celix_array_list_t *list, unsigned long val) { + +celix_status_t celix_arrayList_addULong(celix_array_list_t *list, unsigned long val) { celix_array_list_entry_t entry; memset(&entry, 0, sizeof(entry)); entry.ulongVal = val; - arrayList_addEntry(list, entry); + return celix_arrayList_addEntry(list, entry); } -void celix_arrayList_addDouble(celix_array_list_t *list, double val) { + +celix_status_t celix_arrayList_addDouble(celix_array_list_t *list, double val) { celix_array_list_entry_t entry; memset(&entry, 0, sizeof(entry)); entry.doubleVal = val; - arrayList_addEntry(list, entry); + return celix_arrayList_addEntry(list, entry); } -void celix_arrayList_addFloat(celix_array_list_t *list, float val) { + +celix_status_t celix_arrayList_addFloat(celix_array_list_t *list, float val) { celix_array_list_entry_t entry; memset(&entry, 0, sizeof(entry)); entry.floatVal = val; - arrayList_addEntry(list, entry); + return celix_arrayList_addEntry(list, entry); } -void celix_arrayList_addBool(celix_array_list_t *list, bool val) { + +celix_status_t celix_arrayList_addBool(celix_array_list_t *list, bool val) { celix_array_list_entry_t entry; memset(&entry, 0, sizeof(entry)); entry.boolVal = val; - arrayList_addEntry(list, entry); + return celix_arrayList_addEntry(list, entry); } -void celix_arrayList_addSize(celix_array_list_t *list, size_t val) { + +celix_status_t celix_arrayList_addSize(celix_array_list_t *list, size_t val) { celix_array_list_entry_t entry; memset(&entry, 0, sizeof(entry)); entry.sizeVal = val; - arrayList_addEntry(list, entry); + return celix_arrayList_addEntry(list, entry); } int celix_arrayList_indexOf(celix_array_list_t *list, celix_array_list_entry_t entry) {
