Thu, 01 Feb 2024 10:41:39 +0100
make DavContext mt-safe
--- a/libidav/config.c Mon Jan 29 11:20:34 2024 +0100 +++ b/libidav/config.c Thu Feb 01 10:41:39 2024 +0100 @@ -579,6 +579,9 @@ stype = "https"; } else if(type == DAV_HTTP_PROXY) { stype = "http"; + } else { + fprintf(stderr, "unknown proxy type\n"); + return 1; } if(!proxy) {
--- a/libidav/session.c Mon Jan 29 11:20:34 2024 +0100 +++ b/libidav/session.c Thu Feb 01 10:41:39 2024 +0100 @@ -94,7 +94,7 @@ curl_easy_setopt(sn->handle, CURLOPT_URL, base_url); // add to context - cxListAdd(context->sessions, sn); + dav_context_add_session(context, sn); sn->context = context; return sn; @@ -302,12 +302,8 @@ void dav_session_destroy(DavSession *sn) { // remove session from context - CxList *sessions = sn->context->sessions; - ssize_t i = cxListFind(sessions, sn); - if(i >= 0) { - cxListRemove(sessions, i); - } else { - printf("Error: session not found in ctx->sessions\n"); + if (dav_context_remove_session(sn->context, sn)) { + fprintf(stderr, "Error: session not found in ctx->sessions\n"); dav_session_destructor(sn); } }
--- a/libidav/webdav.c Mon Jan 29 11:20:34 2024 +0100 +++ b/libidav/webdav.c Thu Feb 01 10:41:39 2024 +0100 @@ -146,15 +146,68 @@ free(ctx); } +#ifndef _WIN32 + +void dav_context_set_mtsafe(DavContext *ctx, DavBool enable) { + if (enable) { + pthread_mutex_init(&ctx->mutex, NULL); + } else { + pthread_mutex_destroy(&ctx->mutex); + } + ctx->mtsafe = enable; +} + +void dav_context_lock(DavContext *ctx) { + if (ctx->mtsafe) { + pthread_mutex_lock(&ctx->mutex); + } +} + +void dav_context_unlock(DavContext *ctx) { + if (ctx->mtsafe) { + pthread_mutex_unlock(&ctx->mutex); + } +} + +#else + +void dav_context_set_mtsafe(DavContext *ctx, DavBool enable) { + if (enable) { + ctx->mutex = CreateMutex(NULL, FALSE, NULL); + } else { + CloseHandle(ctx->mutex); + } + ctx->mtsafe = enable; +} + +void dav_context_lock(DavContext *ctx) { + if (ctx->mtsafe) { + WaitForSingleObject(ctx->mutex, INFINITE); + } +} + +void dav_context_unlock(DavContext *ctx) { + if (ctx->mtsafe) { + ReleaseMutex(ctx->mutex); + } +} + +#endif + void dav_context_add_key(DavContext *context, DavKey *key) { + dav_context_lock(context); cxMapPut(context->keys, cx_hash_key_str(key->name), key); + dav_context_unlock(context); } DavKey* dav_context_get_key(DavContext *context, const char *name) { + DavKey *key = NULL; + dav_context_lock(context); if(name) { - return cxMapGet(context->keys, cx_hash_key_str(name)); + key = cxMapGet(context->keys, cx_hash_key_str(name)); } - return NULL; + dav_context_unlock(context); + return key; } int dav_add_namespace(DavContext *context, const char *prefix, const char *name) { @@ -164,8 +217,19 @@ } char *p = strdup(prefix); + if (!p) { + free(namespace); + return 1; + } char *n = strdup(name); - + if (!n) { + free(namespace); + free(p); + return 1; + } + + dav_context_lock(context); + int err = 0; if(p && n) { namespace->prefix = p; @@ -178,19 +242,29 @@ if(p) free(p); if(n) free(n); } + + dav_context_unlock(context); return err; } DavNamespace* dav_get_namespace(DavContext *context, const char *prefix) { - return cxMapGet(context->namespaces, cx_hash_key_str(prefix)); + dav_context_lock(context); + DavNamespace *ns = cxMapGet(context->namespaces, cx_hash_key_str(prefix)); + dav_context_unlock(context); + return ns; } DavNamespace* dav_get_namespace_s(DavContext *context, cxstring prefix) { - return cxMapGet(context->namespaces, cx_hash_key(prefix.ptr, prefix.length)); + dav_context_lock(context); + DavNamespace *ns = cxMapGet(context->namespaces, cx_hash_key(prefix.ptr, prefix.length)); + dav_context_unlock(context); + return ns; } int dav_enable_namespace_encryption(DavContext *context, const char *ns, DavBool encrypt) { + dav_context_lock(context); + CxHashKey hkey = cx_hash_key_str(ns); DavNSInfo *info = cxMapGet(context->namespaceinfo, hkey); if(!info) { @@ -200,15 +274,21 @@ } else { info->encrypt = encrypt; } + + dav_context_unlock(context); return 0; } int dav_namespace_is_encrypted(DavContext *context, const char *ns) { + int ret = 0; + dav_context_lock(context); + DavNSInfo *info = cxMapGet(context->namespaceinfo, cx_hash_key_str(ns)); if(info) { - return info->encrypt; + ret = info->encrypt; } - return 0; + dav_context_unlock(context); + return ret; } void dav_get_property_namespace_str( @@ -262,6 +342,28 @@ } } +int dav_context_add_session(DavContext *context, DavSession *sn) { + dav_context_lock(context); + int ret = cxListAdd(context->sessions, sn); + dav_context_unlock(context); + return ret; +} + +int dav_context_remove_session(DavContext *context, DavSession *sn) { + int ret = 0; + dav_context_lock(context); + CxList *sessions = context->sessions; + ssize_t i = cxListFind(sessions, sn); + if(i >= 0) { + cxListRemove(sessions, i); + } else { + ret = 1; + } + dav_context_unlock(context); + return ret; +} + + // TODO: add sstr_t version of dav_get_property_ns void dav_set_effective_href(DavSession *sn, DavResource *resource) {
--- a/libidav/webdav.h Mon Jan 29 11:20:34 2024 +0100 +++ b/libidav/webdav.h Thu Feb 01 10:41:39 2024 +0100 @@ -39,6 +39,12 @@ #include <curl/curl.h> #include <libxml/tree.h> +#ifndef _WIN32 +#include <pthread.h> +#else +#include <Windows.h> +#endif + #ifdef __cplusplus extern "C" { #endif @@ -67,6 +73,12 @@ typedef struct DavInputStream DavInputStream; typedef struct DavOutputStream DavOutputStream; +#ifndef _WIN32 +#define DAV_MUTEX pthread_mutex_t +#else +#define DAV_MUTEX HANDLE +#endif + typedef size_t(*dav_read_func)(void*, size_t, size_t, void*); typedef size_t(*dav_write_func)(const void*, size_t, size_t, void*); typedef int(*dav_seek_func)(const void *, long, int); @@ -180,12 +192,14 @@ }; struct DavContext { - CxMap *namespaces; - CxMap *namespaceinfo; - CxMap *keys; - CxList *sessions; - DavProxy *http_proxy; - DavProxy *https_proxy; + CxMap *namespaces; + CxMap *namespaceinfo; + CxMap *keys; + CxList *sessions; + DavProxy *http_proxy; + DavProxy *https_proxy; + DAV_MUTEX mutex; + DavBool mtsafe; }; struct DavProxy { @@ -251,6 +265,10 @@ DavContext* dav_context_new(void); void dav_context_destroy(DavContext *ctx); +void dav_context_set_mtsafe(DavContext *ctx, DavBool enable); + +void dav_context_lock(DavContext *ctx); +void dav_context_unlock(DavContext *ctx); void dav_context_add_key(DavContext *context, DavKey *key); DavKey* dav_context_get_key(DavContext *context, const char *name); @@ -262,6 +280,9 @@ int dav_enable_namespace_encryption(DavContext *context, const char *ns, DavBool encrypt); int dav_namespace_is_encrypted(DavContext *context, const char *ns); +int dav_context_add_session(DavContext *context, DavSession *sn); +int dav_context_remove_session(DavContext *context, DavSession *sn); + DavSession* dav_session_new(DavContext *context, char *base_url); DavSession* dav_session_new_auth( DavContext *context,
--- a/make/vs/libidav/libidav.vcxproj Mon Jan 29 11:20:34 2024 +0100 +++ b/make/vs/libidav/libidav.vcxproj Thu Feb 01 10:41:39 2024 +0100 @@ -109,7 +109,7 @@ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ClCompile> <WarningLevel>Level3</WarningLevel> - <SDLCheck>true</SDLCheck> + <SDLCheck>false</SDLCheck> <PreprocessorDefinitions>_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ConformanceMode>true</ConformanceMode> <LanguageStandard_C>stdc11</LanguageStandard_C> @@ -144,6 +144,7 @@ </Link> </ItemDefinitionGroup> <ItemGroup> + <ClCompile Include="..\..\..\libidav\config.c" /> <ClCompile Include="..\..\..\libidav\crypto.c" /> <ClCompile Include="..\..\..\libidav\davqlexec.c" /> <ClCompile Include="..\..\..\libidav\davqlparser.c" /> @@ -156,6 +157,7 @@ <ClCompile Include="..\..\..\libidav\xml.c" /> </ItemGroup> <ItemGroup> + <ClInclude Include="..\..\..\libidav\config.h" /> <ClInclude Include="..\..\..\libidav\crypto.h" /> <ClInclude Include="..\..\..\libidav\davqlexec.h" /> <ClInclude Include="..\..\..\libidav\davqlparser.h" />
--- a/make/vs/libidav/libidav.vcxproj.filters Mon Jan 29 11:20:34 2024 +0100 +++ b/make/vs/libidav/libidav.vcxproj.filters Thu Feb 01 10:41:39 2024 +0100 @@ -45,6 +45,9 @@ <ClCompile Include="..\..\..\libidav\xml.c"> <Filter>Quelldateien</Filter> </ClCompile> + <ClCompile Include="..\..\..\libidav\config.c"> + <Filter>Quelldateien</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\..\libidav\crypto.h"> @@ -77,5 +80,8 @@ <ClInclude Include="..\..\..\libidav\xml.h"> <Filter>Headerdateien</Filter> </ClInclude> + <ClInclude Include="..\..\..\libidav\config.h"> + <Filter>Headerdateien</Filter> + </ClInclude> </ItemGroup> </Project> \ No newline at end of file