libidav/webdav.c

changeset 18
af411868ab9b
parent 1
b5bb7b3cd597
--- a/libidav/webdav.c	Wed Jan 31 12:55:11 2024 +0100
+++ b/libidav/webdav.c	Tue Feb 06 14:17:22 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) {

mercurial