This is an automated email from the ASF dual-hosted git repository.
pengzheng pushed a commit to branch feature/574-scope-based-resource-management
in repository https://gitbox.apache.org/repos/asf/celix.git
The following commit(s) were added to
refs/heads/feature/574-scope-based-resource-management by this push:
new 2be8778c Replace some gotos in rsa_shm_v2 with celix_autoptr.
2be8778c is described below
commit 2be8778ceb47e25bca54736a7634525ea4e64223
Author: PengZheng <[email protected]>
AuthorDate: Fri Jul 21 20:48:20 2023 +0800
Replace some gotos in rsa_shm_v2 with celix_autoptr.
---
.../log_helper/gtest/src/LogHelperTestSuite.cc | 5 ++
.../logging/log_helper/include/celix_log_helper.h | 3 +
.../rsa_shm/src/rsa_shm_activator.c | 28 ++++------
.../rsa_shm/src/rsa_shm_client.c | 64 ++++++++++------------
.../rsa_shm/src/rsa_shm_impl.h | 3 +
.../shm_pool/include/shm_pool.h | 5 +-
libs/framework/CMakeLists.txt | 2 +-
libs/utils/CMakeLists.txt | 2 +-
libs/utils/gtest/src/ArrayListTestSuite.cc | 5 ++
.../gtest/src/CelixUtilsAutoCleanupTestSuite.cc | 18 ++++++
libs/utils/gtest/src/HashMapTestSuite.cc | 5 ++
libs/utils/include/celix_array_list.h | 3 +
libs/utils/include/celix_string_hash_map.h | 3 +
libs/utils/include/celix_threads.h | 4 ++
14 files changed, 93 insertions(+), 57 deletions(-)
diff --git a/bundles/logging/log_helper/gtest/src/LogHelperTestSuite.cc
b/bundles/logging/log_helper/gtest/src/LogHelperTestSuite.cc
index dc7b7c3c..98b01a00 100644
--- a/bundles/logging/log_helper/gtest/src/LogHelperTestSuite.cc
+++ b/bundles/logging/log_helper/gtest/src/LogHelperTestSuite.cc
@@ -205,4 +205,9 @@ TEST_F(LogHelperTestSuite, CxxLogHelper) {
celix_err_pushf("celix error message");
helper.logTssErrors(CELIX_LOG_LEVEL_ERROR);
EXPECT_EQ(6, helper.count());
+}
+
+TEST_F(LogHelperTestSuite, CLogHelperAutoCleanup) {
+ celix_autoptr(celix_log_helper_t) helper =
celix_logHelper_create(ctx->getCBundleContext(), "test::Log");
+ celix_logHelper_info(helper, "Auto cleanup test");
}
\ No newline at end of file
diff --git a/bundles/logging/log_helper/include/celix_log_helper.h
b/bundles/logging/log_helper/include/celix_log_helper.h
index 94e1b378..7e5cd2bc 100644
--- a/bundles/logging/log_helper/include/celix_log_helper.h
+++ b/bundles/logging/log_helper/include/celix_log_helper.h
@@ -24,6 +24,7 @@
#include "celix_log_level.h"
#include "celix_bundle_context.h"
+#include "celix_cleanup.h"
#ifdef __cplusplus
extern "C" {
@@ -35,6 +36,8 @@ celix_log_helper_t*
celix_logHelper_create(celix_bundle_context_t* ctx, const ch
void celix_logHelper_destroy(celix_log_helper_t* logHelper);
+CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(celix_log_helper_t, celix_logHelper_destroy)
+
/**
* @brief Logs to celix_logHelper_log using the CELIX_LOG_LEVEL_TRACE level,
printf style
*/
diff --git
a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_activator.c
b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_activator.c
index 405595f0..c3029ff9 100755
---
a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_activator.c
+++
b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_activator.c
@@ -37,19 +37,18 @@ celix_status_t rsaShmActivator_start(rsa_shm_activator_t
*activator, celix_bundl
assert(activator != NULL);
assert(context != NULL);
- activator->logHelper = celix_logHelper_create(context, "celix_rsa_shm");
- if (activator->logHelper == NULL) {
- status = CELIX_BUNDLE_EXCEPTION;
- goto err_creating_log_helper;
+ celix_autoptr(celix_log_helper_t) logger = celix_logHelper_create(context,
"celix_rsa_shm");
+ if (logger == NULL) {
+ return CELIX_BUNDLE_EXCEPTION;
}
-
- status = rsaShm_create(context, activator->logHelper, &activator->admin);
+ celix_autoptr(rsa_shm_t) admin = NULL;
+ status = rsaShm_create(context, logger, &admin);
if (status != CELIX_SUCCESS) {
- goto rsa_shm_err;
+ return status;
}
- activator->adminService.admin = (void*)activator->admin;
+ activator->adminService.admin = (void*)admin;
activator->adminService.exportService = (void*)rsaShm_exportService;
activator->adminService.getExportedServices =
(void*)rsaShm_getExportedServices;
@@ -73,18 +72,11 @@ celix_status_t rsaShmActivator_start(rsa_shm_activator_t
*activator, celix_bundl
activator->adminSvcId = celix_bundleContext_registerServiceAsync(context,
&activator->adminService,
OSGI_RSA_REMOTE_SERVICE_ADMIN, NULL);
if (activator->adminSvcId < 0) {
- status = CELIX_BUNDLE_EXCEPTION;
- goto err_registering_svc;
+ return CELIX_BUNDLE_EXCEPTION;
}
-
+ activator->logHelper = celix_steal_ptr(logger);
+ activator->admin = celix_steal_ptr(admin);
return CELIX_SUCCESS;
-
-err_registering_svc:
- rsaShm_destroy(activator->admin);
-rsa_shm_err:
- celix_logHelper_destroy(activator->logHelper);
-err_creating_log_helper:
- return status;
}
celix_status_t rsaShmActivator_stop(rsa_shm_activator_t *activator,
celix_bundle_context_t *context) {
diff --git
a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_client.c
b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_client.c
index 0f5a216e..0d009403 100644
---
a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_client.c
+++
b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_client.c
@@ -22,9 +22,11 @@
#include "rsa_shm_constants.h"
#include "celix_log_helper.h"
#include "shm_pool.h"
-#include "celix_api.h"
#include "celix_long_hash_map.h"
+#include "celix_stdlib_cleanup.h"
#include "celix_string_hash_map.h"
+#include "celix_threads.h"
+#include "celix_utils.h"
#include <sys/un.h>
#include <sys/socket.h>
#include <sys/types.h>
@@ -104,7 +106,7 @@ celix_status_t
rsaShmClientManager_create(celix_bundle_context_t *ctx,
if (loghelper == NULL || ctx == NULL || clientManagerOut == NULL) {
return CELIX_ILLEGAL_ARGUMENT;
}
- rsa_shm_client_manager_t *clientManager = (rsa_shm_client_manager_t
*)malloc(sizeof(*clientManager));
+ celix_autofree rsa_shm_client_manager_t *clientManager =
(rsa_shm_client_manager_t *)malloc(sizeof(*clientManager));
if (clientManager == NULL) {
return CELIX_ENOMEM;
}
@@ -118,32 +120,38 @@ celix_status_t
rsaShmClientManager_create(celix_bundle_context_t *ctx,
long shmPoolSize = celix_bundleContext_getPropertyAsLong(ctx,
RSA_SHM_MEMORY_POOL_SIZE_KEY,
RSA_SHM_MEMORY_POOL_SIZE_DEFAULT);
- status = shmPool_create(shmPoolSize, &clientManager->shmPool);
+
+ celix_autoptr(shm_pool_t) shmPool = NULL;
+ status = shmPool_create(shmPoolSize, &shmPool);
if (status != CELIX_SUCCESS) {
celix_logHelper_logTssErrors(loghelper, CELIX_LOG_LEVEL_ERROR);
- celix_logHelper_error(loghelper, "RsaShmClient: Error Creating shared
memory pool.");
- goto shm_pool_err;
+ celix_logHelper_error(loghelper, "RsaShmClient: Error Creating shared
memory shmPool.");
+ return status;
}
+ clientManager->shmPool = shmPool;
status = celixThreadMutex_create(&clientManager->clientsMutex, NULL);
if (status != CELIX_SUCCESS) {
celix_logHelper_error(loghelper, "RsaShmClient: Error creating clients
mutex.");
- goto client_list_lock_err;
+ return status;
}
- clientManager->clients = celix_stringHashMap_create();
+ celix_autoptr(celix_thread_mutex_t) clientsMutex =
&clientManager->clientsMutex;
+ celix_autoptr(celix_string_hash_map_t) clients = clientManager->clients =
celix_stringHashMap_create();
assert(clientManager->clients != NULL);
status = celixThreadMutex_create(&clientManager->exceptionMsgListMutex,
NULL);
if (status != CELIX_SUCCESS) {
celix_logHelper_error(loghelper, "RsaShmClient: Error creating msg
list mutex.");
- goto msg_list_lock_err;
+ return status;
}
+ celix_autoptr(celix_thread_mutex_t) exceptionMsgListMutex =
&clientManager->exceptionMsgListMutex;
status =
celixThreadCondition_init(&clientManager->exceptionMsgListNotEmpty, NULL);
if (status != CELIX_SUCCESS) {
celix_logHelper_error(loghelper, "RsaShmClient: Error creating msg
list signal.");
- goto msg_list_cond_err;
+ return status;
}
- clientManager->exceptionMsgList = celix_arrayList_create();
+ celix_autoptr(celix_thread_cond_t) exceptionMsgListNotEmpty =
&clientManager->exceptionMsgListNotEmpty;
+ celix_autoptr(celix_array_list_t) exceptionMsgList =
clientManager->exceptionMsgList = celix_arrayList_create();
assert(clientManager->exceptionMsgList != NULL);
clientManager->threadActive = true;
@@ -151,26 +159,18 @@ celix_status_t
rsaShmClientManager_create(celix_bundle_context_t *ctx,
rsaShmClientManager_exceptionMsgHandlerThread, clientManager);
if (status != CELIX_SUCCESS) {
celix_logHelper_error(loghelper, "RsaShmClient: Error creating msg
list management thread.");
- goto msg_life_manage_thread_err;
+ return status;
}
celixThread_setName(&clientManager->msgExceptionHandlerThread,
"rsaShmMsgLifeManager");
- *clientManagerOut = clientManager;
-
+ celix_steal_ptr(exceptionMsgList);
+ celix_steal_ptr(exceptionMsgListNotEmpty);
+ celix_steal_ptr(exceptionMsgListMutex);
+ celix_steal_ptr(clients);
+ celix_steal_ptr(clientsMutex);
+ celix_steal_ptr(shmPool);
+ *clientManagerOut = celix_steal_ptr(clientManager);
return CELIX_SUCCESS;
-msg_life_manage_thread_err:
- celix_arrayList_destroy(clientManager->exceptionMsgList);
-
(void)celixThreadCondition_destroy(&clientManager->exceptionMsgListNotEmpty);
-msg_list_cond_err:
- (void)celixThreadMutex_destroy(&clientManager->exceptionMsgListMutex);
-msg_list_lock_err:
- celix_stringHashMap_destroy(clientManager->clients);
- (void)celixThreadMutex_destroy(&clientManager->clientsMutex);
-client_list_lock_err:
- shmPool_destroy(clientManager->shmPool);
-shm_pool_err:
- free(clientManager);
- return status;
}
void rsaShmClientManager_destroy(rsa_shm_client_manager_t *clientManager) {
@@ -205,27 +205,19 @@ celix_status_t
rsaShmClientManager_createOrAttachClient(rsa_shm_client_manager_t
if (clientManager == NULL || peerServerName == NULL) {
return CELIX_ILLEGAL_ARGUMENT;
}
- celixThreadMutex_lock(&clientManager->clientsMutex);
+ celix_autoptr(celix_mutex_locker_t) locker =
celixThreadMutexLocker_new(&clientManager->clientsMutex);
rsa_shm_client_t *client = (rsa_shm_client_t
*)celix_stringHashMap_get(clientManager->clients, peerServerName);
if (client == NULL) {
status = rsaShmClientManager_createClient(clientManager,
peerServerName, &client);
if (status != CELIX_SUCCESS) {
celix_logHelper_error(clientManager->logHelper,"%s create shm
client failed", peerServerName);
- goto shm_client_err;
+ return status;
}
celix_stringHashMap_put(clientManager->clients,
client->peerServerName, client);
}
client->refCnt ++;
-
rsaShmClient_createOrAttachSvcDiagInfo(client, serviceId);
-
- celixThreadMutex_unlock(&clientManager->clientsMutex);
-
return CELIX_SUCCESS;
-
-shm_client_err:
- celixThreadMutex_unlock(&clientManager->clientsMutex);
- return status;
}
void rsaShmClientManager_destroyOrDetachClient(rsa_shm_client_manager_t
*clientManager,
diff --git
a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_impl.h
b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_impl.h
index db0872aa..4d8e4a39 100644
---
a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_impl.h
+++
b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_impl.h
@@ -26,6 +26,7 @@ extern "C" {
#include "rsa_shm_export_registration.h"
#include "rsa_shm_import_registration.h"
#include "endpoint_description.h"
+#include "celix_cleanup.h"
#include "celix_types.h"
#include "celix_properties.h"
#include "celix_errno.h"
@@ -38,6 +39,8 @@ celix_status_t rsaShm_create(celix_bundle_context_t *context,
celix_log_helper_t
void rsaShm_destroy(rsa_shm_t *admin);
+CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(rsa_shm_t, rsaShm_destroy)
+
celix_status_t rsaShm_send(rsa_shm_t *admin, endpoint_description_t *endpoint,
celix_properties_t *metadata, const struct iovec *request, struct
iovec *response);
diff --git
a/bundles/remote_services/remote_service_admin_shm_v2/shm_pool/include/shm_pool.h
b/bundles/remote_services/remote_service_admin_shm_v2/shm_pool/include/shm_pool.h
index 5e8b1ae6..35944920 100644
---
a/bundles/remote_services/remote_service_admin_shm_v2/shm_pool/include/shm_pool.h
+++
b/bundles/remote_services/remote_service_admin_shm_v2/shm_pool/include/shm_pool.h
@@ -23,7 +23,8 @@
#ifdef __cplusplus
extern "C" {
#endif
-#include <celix_errno.h>
+#include "celix_errno.h"
+#include "celix_cleanup.h"
#include <stddef.h>
#include <sys/types.h>
@@ -56,6 +57,8 @@ int shmPool_getShmId(shm_pool_t *pool);
*/
void shmPool_destroy(shm_pool_t *pool);
+CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(shm_pool_t, shmPool_destroy)
+
/**
* @brief Allocate memory from shared memory pool
*
diff --git a/libs/framework/CMakeLists.txt b/libs/framework/CMakeLists.txt
index 3cde3860..4ad7a2a7 100644
--- a/libs/framework/CMakeLists.txt
+++ b/libs/framework/CMakeLists.txt
@@ -42,10 +42,10 @@ add_library(framework SHARED ${FRAMEWORK_SRC})
set_target_properties(framework
PROPERTIES
- C_VISIBILITY_PRESET hidden
"VERSION" "${CELIX_MAJOR}.${CELIX_MINOR}.${CELIX_MICRO}"
"SOVERSION" ${CELIX_MAJOR}
OUTPUT_NAME "celix_framework")
+celix_target_hide_symbols(framework)
target_include_directories(framework PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
)
diff --git a/libs/utils/CMakeLists.txt b/libs/utils/CMakeLists.txt
index 5fcf41c1..a685e707 100644
--- a/libs/utils/CMakeLists.txt
+++ b/libs/utils/CMakeLists.txt
@@ -58,9 +58,9 @@ add_library(utils SHARED ${UTILS_SRC} src/celix_log_level.c)
target_link_libraries(utils PRIVATE libzip::libzip)
set_target_properties(utils
PROPERTIES
- C_VISIBILITY_PRESET hidden
SOVERSION ${CELIX_MAJOR}
OUTPUT_NAME "celix_utils")
+celix_target_hide_symbols(utils)
if (NOT OPEN_MEMSTREAM_EXISTS)
target_compile_definitions(utils PUBLIC
-DCELIX_UTILS_NO_MEMSTREAM_AVAILABLE)
diff --git a/libs/utils/gtest/src/ArrayListTestSuite.cc
b/libs/utils/gtest/src/ArrayListTestSuite.cc
index acb86d14..5a0e60c3 100644
--- a/libs/utils/gtest/src/ArrayListTestSuite.cc
+++ b/libs/utils/gtest/src/ArrayListTestSuite.cc
@@ -256,4 +256,9 @@ TEST_F(ArrayListTestSuite, TestReturnStatusAddFunctions) {
EXPECT_EQ(6, celix_arrayList_size(list));
celix_arrayList_destroy(list);
+}
+
+TEST_F(ArrayListTestSuite, AutoCleanupTest) {
+ celix_autoptr(celix_array_list_t) list = celix_arrayList_create();
+ EXPECT_NE(nullptr, list);
}
\ No newline at end of file
diff --git a/libs/utils/gtest/src/CelixUtilsAutoCleanupTestSuite.cc
b/libs/utils/gtest/src/CelixUtilsAutoCleanupTestSuite.cc
index c7414121..929174bc 100644
--- a/libs/utils/gtest/src/CelixUtilsAutoCleanupTestSuite.cc
+++ b/libs/utils/gtest/src/CelixUtilsAutoCleanupTestSuite.cc
@@ -47,11 +47,23 @@ TEST_F(CelixUtilsCleanupTestSuite, AutoFreeTest) {
ASSERT_EQ(nullptr, alwaysNull);
}
+TEST_F(CelixUtilsCleanupTestSuite, StealPtrTest) {
+ celix_autofree char* p = NULL;
+ p = (char*)malloc(10);
+ free(celix_steal_ptr(p));
+}
+
TEST_F(CelixUtilsCleanupTestSuite, ThradAttrTest) {
celix_auto(celix_thread_attr_t) attr;
EXPECT_EQ(0, pthread_attr_init(&attr));
}
+TEST_F(CelixUtilsCleanupTestSuite, MutexTest) {
+ celix_thread_mutex_t mutex;
+ EXPECT_EQ(0, celixThreadMutex_create(&mutex, nullptr));
+ celix_autoptr(celix_thread_mutex_t) mutex2 = &mutex;
+}
+
static void* mutexLockedThread(void* data) {
celix_thread_mutex_t* mutex = (celix_thread_mutex_t*) data;
EXPECT_NE(0, celixThreadMutex_tryLock(mutex));
@@ -148,6 +160,12 @@ TEST_F(CelixUtilsCleanupTestSuite, RwLockAttrTest) {
EXPECT_EQ(0, celixThreadRwlockAttr_create(&attr));
}
+TEST_F(CelixUtilsCleanupTestSuite, CondTest) {
+ celix_thread_cond_t cond;
+ EXPECT_EQ(0, celixThreadCondition_init(&cond, nullptr));
+ celix_autoptr(celix_thread_cond_t) cond2 = &cond;
+}
+
TEST_F(CelixUtilsCleanupTestSuite, CondAttrTest) {
celix_auto(celix_thread_condattr_t) attr;
EXPECT_EQ(0, pthread_condattr_init(&attr));
diff --git a/libs/utils/gtest/src/HashMapTestSuite.cc
b/libs/utils/gtest/src/HashMapTestSuite.cc
index fa0e7f62..b25df6fb 100644
--- a/libs/utils/gtest/src/HashMapTestSuite.cc
+++ b/libs/utils/gtest/src/HashMapTestSuite.cc
@@ -546,3 +546,8 @@ TEST_F(HashMapTestSuite, IterateWithRemoveTest) {
EXPECT_TRUE(celix_longHashMapIterator_isEnd(&iter2));
celix_longHashMap_destroy(lMap);
}
+
+TEST_F(HashMapTestSuite, StringHashMapCleanup) {
+ celix_autoptr(celix_string_hash_map_t) map = celix_stringHashMap_create();
+ EXPECT_NE(nullptr, map);
+}
diff --git a/libs/utils/include/celix_array_list.h
b/libs/utils/include/celix_array_list.h
index bbcc52d6..b38772b8 100644
--- a/libs/utils/include/celix_array_list.h
+++ b/libs/utils/include/celix_array_list.h
@@ -19,6 +19,7 @@
#include <stdbool.h>
+#include "celix_cleanup.h"
#include "celix_errno.h"
#include "celix_utils_export.h"
@@ -148,6 +149,8 @@ celix_array_list_t* celix_arrayList_createWithOptions(const
celix_array_list_cre
CELIX_UTILS_EXPORT
void celix_arrayList_destroy(celix_array_list_t *list);
+CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(celix_array_list_t, celix_arrayList_destroy)
+
/**
* @brief Returns the size of the array list.
*/
diff --git a/libs/utils/include/celix_string_hash_map.h
b/libs/utils/include/celix_string_hash_map.h
index 620fe10e..9cd70fd7 100644
--- a/libs/utils/include/celix_string_hash_map.h
+++ b/libs/utils/include/celix_string_hash_map.h
@@ -20,6 +20,7 @@
#ifndef CELIX_STRING_HASH_MAP_H_
#define CELIX_STRING_HASH_MAP_H_
+#include "celix_cleanup.h"
#include "celix_hash_map_value.h"
#include "celix_utils_export.h"
@@ -164,6 +165,8 @@ CELIX_UTILS_EXPORT celix_string_hash_map_t*
celix_stringHashMap_createWithOption
*/
CELIX_UTILS_EXPORT void celix_stringHashMap_destroy(celix_string_hash_map_t*
map);
+CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(celix_string_hash_map_t,
celix_stringHashMap_destroy)
+
/**
* @brief Returns the size of the hashmap.
*/
diff --git a/libs/utils/include/celix_threads.h
b/libs/utils/include/celix_threads.h
index eb23b644..a73ce8a9 100644
--- a/libs/utils/include/celix_threads.h
+++ b/libs/utils/include/celix_threads.h
@@ -95,6 +95,8 @@ CELIX_UTILS_EXPORT celix_status_t
celixThreadMutex_create(celix_thread_mutex_t *
CELIX_UTILS_EXPORT celix_status_t
celixThreadMutex_destroy(celix_thread_mutex_t *mutex);
+CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(celix_thread_mutex_t,
celixThreadMutex_destroy)
+
CELIX_UTILS_EXPORT celix_status_t celixThreadMutex_lock(celix_thread_mutex_t
*mutex);
CELIX_UTILS_EXPORT celix_status_t
celixThreadMutex_tryLock(celix_thread_mutex_t *mutex);
@@ -257,6 +259,8 @@ CELIX_UTILS_EXPORT celix_status_t
celixThreadCondition_init(celix_thread_cond_t
CELIX_UTILS_EXPORT celix_status_t
celixThreadCondition_destroy(celix_thread_cond_t *condition);
+CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(celix_thread_cond_t,
celixThreadCondition_destroy)
+
CELIX_UTILS_EXPORT celix_status_t
celixThreadCondition_wait(celix_thread_cond_t *cond, celix_thread_mutex_t
*mutex);
CELIX_UTILS_DEPRECATED_EXPORT celix_status_t
celixThreadCondition_timedwaitRelative(celix_thread_cond_t *cond,
celix_thread_mutex_t *mutex, long seconds, long nanoseconds);