This is an automated email from the ASF dual-hosted git repository. pengzheng pushed a commit to branch support/2.4 in repository https://gitbox.apache.org/repos/asf/celix.git
commit b20883755c582592a0c3e725e5340e42b2ab2066 Author: PengZheng <[email protected]> AuthorDate: Thu Nov 23 17:23:23 2023 +0800 [CID 331864]Fix race condition in http_admin. (cherry picked from commit cc48c2433aecbfb7850d2e7f4f3d4437518f893b) --- bundles/http_admin/http_admin/src/http_admin.c | 25 +++++++++------------- .../http_admin/http_admin/src/websocket_admin.c | 20 +++++++++-------- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/bundles/http_admin/http_admin/src/http_admin.c b/bundles/http_admin/http_admin/src/http_admin.c index a7e885b7..fb7ac6be 100755 --- a/bundles/http_admin/http_admin/src/http_admin.c +++ b/bundles/http_admin/http_admin/src/http_admin.c @@ -37,7 +37,7 @@ struct http_admin_manager { struct mg_context *mgCtx; char *root; - celix_thread_mutex_t admin_lock; //protects below + celix_thread_rwlock_t admin_lock; //protects below celix_http_info_service_t infoSvc; long infoSvcId; @@ -70,7 +70,7 @@ http_admin_manager_t *httpAdmin_create(celix_bundle_context_t *context, char *ro admin->root = root; admin->infoSvcId = -1L; - status = celixThreadMutex_create(&admin->admin_lock, NULL); + status = celixThreadRwlock_create(&admin->admin_lock, NULL); admin->aliasList = celix_arrayList_create(); if (status == CELIX_SUCCESS) { @@ -93,7 +93,7 @@ http_admin_manager_t *httpAdmin_create(celix_bundle_context_t *context, char *ro if (admin->mgCtx != NULL) { mg_stop(admin->mgCtx); } - celixThreadMutex_destroy(&admin->admin_lock); + celixThreadRwlock_destroy(&admin->admin_lock); celix_arrayList_destroy(admin->aliasList); free(admin); @@ -103,14 +103,13 @@ http_admin_manager_t *httpAdmin_create(celix_bundle_context_t *context, char *ro } void httpAdmin_destroy(http_admin_manager_t *admin) { - celixThreadMutex_lock(&(admin->admin_lock)); if(admin->mgCtx != NULL) { mg_stop(admin->mgCtx); } + celixThreadRwlock_writeLock(&(admin->admin_lock)); celix_bundleContext_unregisterService(admin->context, admin->infoSvcId); - destroyServiceTree(&admin->http_svc_tree); //Destroy alias map by removing symbolic links first. @@ -129,8 +128,8 @@ void httpAdmin_destroy(http_admin_manager_t *admin) { } celix_arrayList_destroy(admin->aliasList); - celixThreadMutex_unlock(&(admin->admin_lock)); - celixThreadMutex_destroy(&(admin->admin_lock)); + celixThreadRwlock_unlock(&(admin->admin_lock)); + celixThreadRwlock_destroy(&(admin->admin_lock)); free(admin->root); free(admin); @@ -147,11 +146,10 @@ void http_admin_addHttpService(void *handle, void *svc, const celix_properties_t const char *uri = celix_properties_get(props, HTTP_ADMIN_URI, NULL); if(uri != NULL) { - celixThreadMutex_lock(&(admin->admin_lock)); + celix_auto(celix_rwlock_wlock_guard_t) lock = celixRwlockWlockGuard_init(&(admin->admin_lock)); if(!addServiceNode(&admin->http_svc_tree, uri, httpSvc)) { printf("HTTP service with URI %s already exists!\n", uri); } - celixThreadMutex_unlock(&(admin->admin_lock)); } } @@ -161,7 +159,7 @@ void http_admin_removeHttpService(void *handle, void *svc CELIX_UNUSED, const ce const char *uri = celix_properties_get(props, HTTP_ADMIN_URI, NULL); if(uri != NULL) { - celixThreadMutex_lock(&(admin->admin_lock)); + celix_auto(celix_rwlock_wlock_guard_t) lock = celixRwlockWlockGuard_init(&(admin->admin_lock)); service_tree_node_t *node = NULL; node = findServiceNodeInTree(&admin->http_svc_tree, uri); @@ -171,8 +169,6 @@ void http_admin_removeHttpService(void *handle, void *svc CELIX_UNUSED, const ce } else { printf("Couldn't remove HTTP service with URI: %s, it doesn't exist\n", uri); } - - celixThreadMutex_unlock(&(admin->admin_lock)); } } @@ -189,6 +185,7 @@ int http_request_handle(struct mg_connection *connection) { ret_status = 0; //... so return zero to let the civetweb server handle the request. } else { + celix_auto(celix_rwlock_rlock_guard_t) lock = celixRwlockRlockGuard_init(&(admin->admin_lock)); const char *req_uri = ri->request_uri; node = findServiceNodeInTree(&admin->http_svc_tree, req_uri); @@ -367,7 +364,7 @@ static void httpAdmin_updateInfoSvc(http_admin_manager_t *admin) { } fclose(stream); - celixThreadMutex_lock(&admin->admin_lock); + celix_auto(celix_rwlock_wlock_guard_t) lock = celixRwlockWlockGuard_init(&(admin->admin_lock)); celix_bundleContext_unregisterService(admin->context, admin->infoSvcId); celix_properties_t *properties = celix_properties_create(); @@ -377,8 +374,6 @@ static void httpAdmin_updateInfoSvc(http_admin_manager_t *admin) { } admin->infoSvcId = celix_bundleContext_registerService(admin->context, &admin->infoSvc, HTTP_ADMIN_INFO_SERVICE_NAME, properties); - celixThreadMutex_unlock(&admin->admin_lock); - free(resources_urls); } diff --git a/bundles/http_admin/http_admin/src/websocket_admin.c b/bundles/http_admin/http_admin/src/websocket_admin.c index 503bbf91..2cd8a453 100644 --- a/bundles/http_admin/http_admin/src/websocket_admin.c +++ b/bundles/http_admin/http_admin/src/websocket_admin.c @@ -35,7 +35,7 @@ struct websocket_admin_manager { struct mg_context *mg_ctx; service_tree_t sock_svc_tree; - celix_thread_mutex_t admin_lock; + celix_thread_rwlock_t admin_lock; }; websocket_admin_manager_t *websocketAdmin_create(celix_bundle_context_t *context, struct mg_context *svr_ctx) { @@ -49,7 +49,7 @@ websocket_admin_manager_t *websocketAdmin_create(celix_bundle_context_t *context admin->context = context; admin->mg_ctx = svr_ctx; - status = celixThreadMutex_create(&admin->admin_lock, NULL); + status = celixThreadRwlock_create(&admin->admin_lock, NULL); if(status != CELIX_SUCCESS) { //No need to destroy other things @@ -60,14 +60,14 @@ websocket_admin_manager_t *websocketAdmin_create(celix_bundle_context_t *context } void websocketAdmin_destroy(websocket_admin_manager_t *admin) { - celixThreadMutex_lock(&(admin->admin_lock)); + celixThreadRwlock_writeLock(&(admin->admin_lock)); //Destroy tree with services destroyServiceTree(&admin->sock_svc_tree); - celixThreadMutex_unlock(&(admin->admin_lock)); + celixThreadRwlock_unlock(&(admin->admin_lock)); - celixThreadMutex_destroy(&(admin->admin_lock)); + celixThreadRwlock_destroy(&(admin->admin_lock)); free(admin); } @@ -79,14 +79,13 @@ void websocket_admin_addWebsocketService(void *handle, void *svc, const celix_pr const char *uri = celix_properties_get(props, WEBSOCKET_ADMIN_URI, NULL); if(uri != NULL) { - celixThreadMutex_lock(&(admin->admin_lock)); + celix_auto(celix_rwlock_wlock_guard_t) lock = celixRwlockWlockGuard_init(&(admin->admin_lock)); if(addServiceNode(&admin->sock_svc_tree, uri, websockSvc)) { mg_set_websocket_handler(admin->mg_ctx, uri, websocket_connect_handler, websocket_ready_handler, websocket_data_handler, websocket_close_handler, admin); } else { printf("Websocket service with URI %s already exists!\n", uri); } - celixThreadMutex_unlock(&(admin->admin_lock)); } } @@ -96,7 +95,7 @@ void websocket_admin_removeWebsocketService(void *handle, void *svc CELIX_UNUSED const char *uri = celix_properties_get(props, WEBSOCKET_ADMIN_URI, NULL); if(uri != NULL) { - celixThreadMutex_lock(&(admin->admin_lock)); + celix_auto(celix_rwlock_wlock_guard_t) lock = celixRwlockWlockGuard_init(&(admin->admin_lock)); service_tree_node_t *node = NULL; node = findServiceNodeInTree(&admin->sock_svc_tree, uri); @@ -107,7 +106,6 @@ void websocket_admin_removeWebsocketService(void *handle, void *svc CELIX_UNUSED printf("Couldn't remove websocket service with URI: %s, it doesn't exist\n", uri); } - celixThreadMutex_unlock(&(admin->admin_lock)); } } @@ -120,6 +118,7 @@ int websocket_connect_handler(const struct mg_connection *connection, void *hand const char *req_uri = ri->request_uri; service_tree_node_t *node = NULL; + celix_auto(celix_rwlock_rlock_guard_t) lock = celixRwlockRlockGuard_init(&(admin->admin_lock)); node = findServiceNodeInTree(&admin->sock_svc_tree, req_uri); if(node != NULL) { @@ -147,6 +146,7 @@ void websocket_ready_handler(struct mg_connection *connection, void *handle) { const char *req_uri = ri->request_uri; service_tree_node_t *node = NULL; + celix_auto(celix_rwlock_rlock_guard_t) lock = celixRwlockRlockGuard_init(&(admin->admin_lock)); node = findServiceNodeInTree(&admin->sock_svc_tree, req_uri); if(node != NULL) { @@ -169,6 +169,7 @@ int websocket_data_handler(struct mg_connection *connection, int op_code, char * const char *req_uri = ri->request_uri; service_tree_node_t *node = NULL; + celix_auto(celix_rwlock_rlock_guard_t) lock = celixRwlockRlockGuard_init(&(admin->admin_lock)); node = findServiceNodeInTree(&admin->sock_svc_tree, req_uri); if(node != NULL) { @@ -192,6 +193,7 @@ void websocket_close_handler(const struct mg_connection *connection, void *handl const char *req_uri = ri->request_uri; service_tree_node_t *node = NULL; + celix_auto(celix_rwlock_rlock_guard_t) lock = celixRwlockRlockGuard_init(&(admin->admin_lock)); node = findServiceNodeInTree(&admin->sock_svc_tree, req_uri); if(node != NULL) {
