Sat, 20 Jun 2026 19:00:56 +0200
implement reference counting for DavContext and DavSession
| libidav/atomic.h | file | annotate | diff | comparison | revisions | |
| libidav/session.c | file | annotate | diff | comparison | revisions | |
| libidav/webdav.c | file | annotate | diff | comparison | revisions | |
| libidav/webdav.h | file | annotate | diff | comparison | revisions | |
| test/Makefile | file | annotate | diff | comparison | revisions | |
| test/context.c | file | annotate | diff | comparison | revisions | |
| test/context.h | file | annotate | diff | comparison | revisions | |
| test/main.c | file | annotate | diff | comparison | revisions | |
| test/session.c | file | annotate | diff | comparison | revisions | |
| test/session.h | file | annotate | diff | comparison | revisions |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libidav/atomic.h Sat Jun 20 19:00:56 2026 +0200 @@ -0,0 +1,57 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DAV_ATOMIC_H +#define DAV_ATOMIC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__gnu_linux__) || defined(OSX) || defined(BSD) + +#define dav_atomic_inc32(intptr) __sync_fetch_and_add(intptr, 1) +#define dav_atomic_dec32(intptr) (__sync_fetch_and_sub(intptr, 1) - 1) + +#else +// use atomic.h +#include <atomic.h> + +#define dav_atomic_inc32(intptr) atomic_inc_32_nv(intptr) +#define dav_atomic_dec32(intptr) atomic_dec_32_nv(intptr) +// TODO + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* DAV_ATOMIC_H */ +
--- a/libidav/session.c Sat Feb 14 18:11:29 2026 +0100 +++ b/libidav/session.c Sat Jun 20 19:00:56 2026 +0200 @@ -38,6 +38,7 @@ #include "session.h" #include "resource.h" #include "methods.h" +#include "atomic.h" DavSession* dav_session_new(DavContext *context, char *base_url) { if(!base_url) { @@ -95,6 +96,9 @@ // add to context dav_context_add_session(context, sn); sn->context = context; + dav_context_ref(context); + + sn->ref = 1; return sn; } @@ -138,10 +142,23 @@ // add to context dav_context_add_session(sn->context, newsn); newsn->context = sn->context; + dav_context_ref(sn->context); + + newsn->ref = 1; return newsn; } +void dav_session_ref(DavSession *sn) { + dav_atomic_inc32(&sn->ref); +} + +void dav_session_unref(DavSession *sn) { + if(dav_atomic_dec32(&sn->ref) == 0) { + dav_session_destroy(sn); + } +} + void dav_session_set_auth(DavSession *sn, const char *user, const char *password) { if(user && password) { dav_session_set_auth_s(sn, cx_str(user), cx_str(password)); @@ -344,15 +361,19 @@ void dav_session_destroy(DavSession *sn) { // remove session from context - if (dav_context_remove_session(sn->context, sn)) { + DavContext *ctx = sn->context; + dav_context_ref(ctx); + if (dav_context_remove_session(ctx, sn)) { fprintf(stderr, "Error: session not found in ctx->sessions\n"); dav_session_destructor(sn); } + dav_context_unref(ctx); } void dav_session_destructor(DavSession *sn) { cxMempoolFree(sn->mp); curl_easy_cleanup(sn->handle); + dav_context_unref(sn->context); free(sn); }
--- a/libidav/webdav.c Sat Feb 14 18:11:29 2026 +0100 +++ b/libidav/webdav.c Sat Jun 20 19:00:56 2026 +0200 @@ -41,6 +41,7 @@ #include <cx/compare.h> #include "davqlparser.h" #include "davqlexec.h" +#include "atomic.h" DavContext* dav_context_new(void) { @@ -94,10 +95,22 @@ dav_context_destroy(context); return NULL; } + + context->ref = 1; return context; } +void dav_context_ref(DavContext *ctx) { + dav_atomic_inc32(&ctx->ref); +} + +void dav_context_unref(DavContext *ctx) { + if(dav_atomic_dec32(&ctx->ref) == 0) { + dav_context_destroy(ctx); + } +} + void dav_context_destroy(DavContext *ctx) { // destroy all sessions assoziated with this context // ctx->sessions destructor must be dav_session_destructor
--- a/libidav/webdav.h Sat Feb 14 18:11:29 2026 +0100 +++ b/libidav/webdav.h Sat Jun 20 19:00:56 2026 +0200 @@ -189,17 +189,20 @@ void(*get_progress)(DavResource *res, int64_t total, int64_t now, void *userdata); void(*put_progress)(DavResource *res, int64_t total, int64_t now, void *userdata); void *progress_userdata; + + unsigned int ref; }; struct DavContext { - CxMap *namespaces; - CxMap *namespaceinfo; - CxMap *keys; - CxList *sessions; - DavProxy *http_proxy; - DavProxy *https_proxy; - DAV_MUTEX mutex; - DavBool mtsafe; + CxMap *namespaces; + CxMap *namespaceinfo; + CxMap *keys; + CxList *sessions; + DavProxy *http_proxy; + DavProxy *https_proxy; + DAV_MUTEX mutex; + DavBool mtsafe; + unsigned int ref; }; struct DavProxy { @@ -264,6 +267,8 @@ }; DavContext* dav_context_new(void); +void dav_context_ref(DavContext *ctx); +void dav_context_unref(DavContext *ctx); void dav_context_destroy(DavContext *ctx); void dav_context_set_mtsafe(DavContext *ctx, DavBool enable); @@ -290,6 +295,8 @@ char *user, char *password); DavSession* dav_session_clone(DavSession *sn); +void dav_session_ref(DavSession *sn); +void dav_session_unref(DavSession *sn); void dav_session_set_auth(DavSession *sn, const char *user, const char *password); void dav_session_set_auth_s(DavSession *sn, cxstring user, cxstring password); void dav_session_set_baseurl(DavSession *sn, char *base_url);
--- a/test/Makefile Sat Feb 14 18:11:29 2026 +0100 +++ b/test/Makefile Sat Jun 20 19:00:56 2026 +0200 @@ -33,6 +33,8 @@ TEST_SRC += base64.c TEST_SRC += crypto.c TEST_SRC += utils.c +TEST_SRC += context.c +TEST_SRC += session.c TEST_SRC += webdav.c TEST_SRC += webdav_resource.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/context.c Sat Jun 20 19:00:56 2026 +0200 @@ -0,0 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2026 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "context.h" + +CX_TEST(test_context_ref_counting) { + CX_TEST_DO { + DavContext *ctx = dav_context_new(); + CX_TEST_ASSERT(ctx->ref == 1); + dav_context_ref(ctx); + CX_TEST_ASSERT(ctx->ref == 2); + dav_context_unref(ctx); + CX_TEST_ASSERT(ctx->ref == 1); + dav_context_unref(ctx); + // context destroyed + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/context.h Sat Jun 20 19:00:56 2026 +0200 @@ -0,0 +1,47 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2026 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TEST_DAV_CONTEXT_H +#define TEST_DAV_CONTEXT_H + +#include <cx/test.h> +#include <libidav/webdav.h> + +#ifdef __cplusplus +extern "C" { +#endif + +CX_TEST(test_context_ref_counting); + + +#ifdef __cplusplus +} +#endif + +#endif /* TEST_DAV_CONTEXT_H */ +
--- a/test/main.c Sat Feb 14 18:11:29 2026 +0100 +++ b/test/main.c Sat Jun 20 19:00:56 2026 +0200 @@ -35,6 +35,8 @@ #include "crypto.h" #include "utils.h" +#include "context.h" +#include "session.h" #include "webdav.h" #include "webdav_resource.h" @@ -81,6 +83,8 @@ cx_test_register(suite, test_util_path_isabsolut); cx_test_register(suite, test_util_path_normalize); cx_test_register(suite, test_util_parent_path); + cx_test_register(suite, test_context_ref_counting); + cx_test_register(suite, test_session_ref_counting); CxTestSuite* suite_webdav = cx_test_suite_new("libidav webdav"); test_webdav_init();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/session.c Sat Jun 20 19:00:56 2026 +0200 @@ -0,0 +1,48 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2026 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "session.h" + +CX_TEST(test_session_ref_counting) { + CX_TEST_DO { + DavContext *ctx = dav_context_new(); + DavSession *sn = dav_session_new(ctx, "http://example.com/webdav/"); + + CX_TEST_ASSERT(sn->ref == 1); + CX_TEST_ASSERT(ctx->ref == 2); + + dav_session_ref(sn); + CX_TEST_ASSERT(sn->ref == 2); + + dav_context_unref(ctx); + CX_TEST_ASSERT(ctx->ref == 1); + dav_session_unref(sn); + CX_TEST_ASSERT(sn->ref == 1); + dav_session_unref(sn); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/session.h Sat Jun 20 19:00:56 2026 +0200 @@ -0,0 +1,46 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2026 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TEST_DAV_SESSION_H +#define TEST_DAV_SESSION_H + +#include <cx/test.h> +#include <libidav/webdav.h> + +#ifdef __cplusplus +extern "C" { +#endif + +CX_TEST(test_session_ref_counting); + +#ifdef __cplusplus +} +#endif + +#endif /* TEST_DAV_SESSION_H */ +