diff --git a/src/cache.c b/src/cache.c
index b0b0748..74403a2 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -59,6 +59,7 @@
 #endif
 #include <sys/xattr.h>
 
+#include <pthread.h>
 #include "xalloc.h"
 #include "xstrndup.h"
 #include "xvasprintf.h"
@@ -234,6 +235,15 @@ static int debug;
 /* Buffer for xml_cdata callback. */
 static char *xml_data = NULL;
 
+/* Lock for all important operations, like executing fuse calls and
+   uploading files to the webdav server. To be unlocked only when nothing
+   changes, i.e. in an idle thread or during transfer of a file. */
+pthread_mutex_t* mutex_allops = NULL;
+
+/* block the background thread, used to make sure that when renaming
+   a directory, no file in the directory or in subdirectories is in transfer */
+static int no_bg_transfer=0;
+
 
 /* Private function prototypes and inline functions */
 /*==================================================*/
@@ -247,11 +257,39 @@ static void
 add_to_changed(dav_node *node);
 
 static inline void
+ensure_not_in_transfer(const dav_node *node)
+{
+    while (S_ISREG(node->mode) && node->in_transfer)
+    {
+      mutex_unlock(mutex_allops);
+      sleep(10);
+      mutex_lock(mutex_allops);
+    }
+}
+
+static inline void
+ensure_not_in_transfer_directory(const dav_node *node)
+{
+  ensure_not_in_transfer(node);
+
+  dav_node *child = node->childs;
+  while (child)
+  {
+    ensure_not_in_transfer(child);
+    child = child->next;
+  }
+}
+
+static inline void
 attr_from_cache_file(dav_node *node)
 {
     struct stat st;
     if (!node->cache_path || stat(node->cache_path, &st) != 0)
         return;
+
+    /* sleep until transfer has finished */
+    ensure_not_in_transfer(node);
+
     off_t old_size = node->size;
     node->size = st.st_size;
     cache_size += node->size - old_size;
@@ -585,6 +623,9 @@ test_alignment();
 void
 dav_init_cache(const dav_args *args, const char *mpoint)
 {
+    mutex_allops = calloc(1, sizeof(pthread_mutex_t));
+    pthread_mutex_init(mutex_allops, NULL);
+
     debug = args->debug & DAV_DBG_CACHE;
     if (debug)
         syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "Initializing cache");
@@ -770,14 +811,24 @@ dav_tidy_cache(void)
     if ((is_dirty(node) || is_created(node)) && !is_open_write(node)
             && !is_backup(node) && item->save_at
             && item-> save_at <= time(NULL)) {
+        // sleep while renaming/moving directories
+        while ( no_bg_transfer )
+        {
+          mutex_unlock(mutex_allops);
+          sleep(10);
+          mutex_lock(mutex_allops);
+        }
+
         if (debug)
             syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "tidy: %s", node->path);
         int set_execute = -1;
         if (is_created(node) && node->mode & (S_IXUSR | S_IXGRP | S_IXOTH))
             set_execute = 1;
-        int ret = dav_put(node->path, node->cache_path, &node->remote_exists,
-                          &node->lock_expire, &node->etag, &node->smtime,
-                          &node->mime_type, set_execute);
+        node->in_transfer=1;
+        int ret = dav_put_bg(node->path, node->cache_path, &node->remote_exists,
+                             &node->lock_expire, &node->etag, &node->smtime,
+                             &node->mime_type, set_execute);
+        node->in_transfer=0;
         if (!ret) {
             node->utime = time(NULL);
             node->dirty = 0;
@@ -787,7 +838,7 @@ dav_tidy_cache(void)
             if (debug) {
                 syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "tidy: neon error");
                 syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "      %s",
-                       dav_get_webdav_error());
+                       dav_get_webdav_error_bg());
             }
             if (ret == EACCES || ret == EINVAL || ret == ENOENT
                       || ret == EPERM || ret == ENOSPC || ret == EEXIST
@@ -1149,6 +1200,9 @@ dav_open(int *fd, dav_node *node, int flags, pid_t pid, pid_t pgid, uid_t uid,
     if (!open_create && !has_permission(node, uid, how))
         return EACCES;
 
+    /* sleep until transfer has finished */
+    ensure_not_in_transfer(node);
+
     if (is_dir(node)) {
         if ((how & W_OK) || (flags & O_TRUNC))
             return EINVAL;
@@ -1251,6 +1305,9 @@ dav_remove(dav_node *parent, const char *name, uid_t uid)
     if (is_dir(node))
         return EISDIR;
 
+    /* sleep until a possible transfer is finished */
+    ensure_not_in_transfer( node );
+
     int ret = 0;
     if (is_created(node)) {
         if (is_locked(node))
@@ -1313,6 +1370,15 @@ dav_rename(dav_node *src_parent, const char *src_name, dav_node *dst_parent,
     if (src == backup || (dst && is_backup(dst)))
         return EINVAL;
 
+    /* sleep until a possible transfer is finished */
+    /* disable bg transfer while moving/renaming, otherwise it is
+       difficult to ensure that no file in a subdirectory is in transfer */
+    no_bg_transfer=1;
+    if (src)
+      ensure_not_in_transfer_directory( src );
+    if (dst)
+      ensure_not_in_transfer_directory( dst );
+
     int ret;
     if (is_dir(src)) {
         ret = move_dir(src, dst, dst_parent, dst_name);
@@ -1342,6 +1408,7 @@ dav_rename(dav_node *src_parent, const char *src_name, dav_node *dst_parent,
         *flush = 1;
     }
 
+    no_bg_transfer=0;
     return ret;
 }
 
@@ -1409,6 +1476,9 @@ dav_setattr(dav_node *node, uid_t uid, int sm, mode_t mode, int so,
     if (node->parent != NULL && !has_permission(node->parent, uid, X_OK))
         return EACCES;
 
+    /* sleep until transfer has finished */
+    ensure_not_in_transfer(node);
+
     if (so) {
         if (debug)
             syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "  set owner to %i",
@@ -1846,7 +1916,6 @@ delete_tree(dav_node *node)
     }
 }
 
-
 /* Moves directory src to dst using WebDAV method MOVE. */
 static int
 move_dir(dav_node *src, dav_node *dst, dav_node *dst_parent,
@@ -2063,6 +2132,7 @@ new_node(dav_node *parent, mode_t mode)
     }
     node->remote_exists = 0;
     node->dirty = 0;
+    node->in_transfer = 0;
     node->uid = default_uid;
     node->gid = default_gid;
 
@@ -2287,6 +2357,9 @@ update_node(dav_node *node, dav_props *props)
         return 0;
     int ret = 0;
 
+    /* sleep until transfer has finished */
+    ensure_not_in_transfer(node);
+
     if ((is_dir(node) && !props->is_dir)
             || (!is_dir(node) && props->is_dir)) {
         add_node(node->parent, props);
@@ -2666,6 +2739,9 @@ update_cache_file(dav_node *node)
 
     int ret = 0;
 
+    /* sleep until transfer has finished */
+    ensure_not_in_transfer(node);
+
     if (is_dirty(node)) {
         if (get_upload_time(node) >= time(NULL))
             return 0;
diff --git a/src/cache.h b/src/cache.h
index e3dc6b7..b5204e1 100644
--- a/src/cache.h
+++ b/src/cache.h
@@ -127,6 +127,9 @@ struct dav_node {
     /* Files: Dirty flag. Must be set, when a file is opened for writing, and
               reset, when the file is saved back. */
     int dirty;
+    /* Files: if the file is presently uploaded to the server. No write access 
+              is allowed during this time. */
+    int in_transfer;
     /* mode, uid and gid are initially set to the default values, but may be
        changed by dav_setattr(). */
     mode_t mode;
diff --git a/src/dav_fuse.c b/src/dav_fuse.c
index 90f0792..fc9f794 100644
--- a/src/dav_fuse.c
+++ b/src/dav_fuse.c
@@ -46,6 +46,7 @@
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#include <pthread.h>
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -91,12 +92,17 @@ static uint64_t root;
 /* Send debug messages to syslog if != 0. */
 int debug;
 
+//Read- and write-lock for all important actions.
+extern pthread_mutex_t* mutex_allops;
 
 /* Private function prototypes */
 /*=============================*/
 
 /* Functions to handle upcalls fromthe kernel module. */
 
+static void
+dav_check_cache(void* arg);
+
 static uint32_t
 fuse_access(void);
 
@@ -179,14 +185,25 @@ dav_fuse_loop(int device, size_t bufsize, time_t idle_time,
     struct timeval tv;
     tv.tv_sec = idle_time;
     tv.tv_usec = 0;
-    time_t last_tidy_cache = time(NULL);
+    mutex_lock(mutex_allops);
+
+    pthread_t dav_check_cache_thread_id=0;
+    if(pthread_create(&dav_check_cache_thread_id, NULL,
+                      (void*) dav_check_cache, (void*) keep_on_running)){
+        syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), 
+               "starting thread for dav_check_cache() failed");
+        return;
+    }
 
     while (*keep_on_running) {
 
         fd_set fds;
         FD_ZERO(&fds);
         FD_SET(device, &fds);
+        mutex_unlock(mutex_allops);        
+        tv.tv_sec = idle_time;
         int ret = select(device + 1, &fds, NULL, NULL, &tv);
+        mutex_lock(mutex_allops);        
         if (debug)
             syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "SELECT: %i", ret);
 
@@ -198,11 +215,6 @@ dav_fuse_loop(int device, size_t bufsize, time_t idle_time,
                            strerror(errno));
                 if (bytes_read == 0 || errno == EINTR || errno == EAGAIN ||
                         errno == ENOENT) {
-                    if (time(NULL) < (last_tidy_cache + idle_time)) {
-                        tv.tv_sec = last_tidy_cache + idle_time - time(NULL);
-                    } else {
-                        tv.tv_sec = 0;
-                    }
                     continue;
                 }
                 break;
@@ -210,12 +222,6 @@ dav_fuse_loop(int device, size_t bufsize, time_t idle_time,
         } else if (ret == 0) {
             if (!is_mounted())
                 break;
-            if (dav_tidy_cache() == 0) {
-                tv.tv_sec = idle_time;
-                last_tidy_cache = time(NULL);
-            } else {
-                tv.tv_sec = 0;
-            }
             continue;
         } else {
             break;
@@ -312,7 +318,6 @@ dav_fuse_loop(int device, size_t bufsize, time_t idle_time,
             break;
         case FUSE_RELEASE:
             oh->len = fuse_release();
-            last_tidy_cache = 0;
             break;
         case FUSE_FSYNC:
             if (debug) {
@@ -394,20 +399,41 @@ dav_fuse_loop(int device, size_t bufsize, time_t idle_time,
             n += w;
         }
 
-        if (time(NULL) < (last_tidy_cache + idle_time)) {
-            tv.tv_sec = last_tidy_cache + idle_time - time(NULL);
-        } else {
-            dav_tidy_cache();
-            tv.tv_sec = idle_time;
-            last_tidy_cache = time(NULL);
-        }
-
     }
+    *keep_on_running=0;
+    mutex_unlock(mutex_allops);    
+    pthread_join(dav_check_cache_thread_id, NULL);
 }
 
 
 /* Private functions */
 /*===================*/
+/* Execute the function dav_tidy_cache in an endless loop for checking the
+ * cache. The mutex is released during sleep and during the upload of the files
+ * in dav_put()
+ * */
+
+static void
+dav_check_cache(void* arg)
+{
+    volatile int *keep_on_running = (volatile int *) arg;
+
+    while(*keep_on_running){
+        mutex_lock(mutex_allops);      
+        while ( dav_tidy_cache() )
+          ;
+        mutex_unlock(mutex_allops);        
+        sleep(10); 
+    }
+    if (debug) {
+      syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "dav_check_cache loop ended");
+    }
+
+    dav_close_webdav_bg();
+    if (debug) {
+      syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "dav_check_cache closed session");
+    }
+}
 
 /* Functions to handle upcalls fromthe kernel module.
    The cache module only uses data types from the C-library. For file access,
diff --git a/src/webdav.c b/src/webdav.c
index 86ea81d..53fdebe 100644
--- a/src/webdav.c
+++ b/src/webdav.c
@@ -56,6 +56,7 @@
 #include <sys/stat.h>
 #endif
 
+#include <pthread.h>
 #include "xalloc.h"
 #include "xstrndup.h"
 #include "xvasprintf.h"
@@ -163,9 +164,23 @@ static char *none_match_header = "If-None-Match: *\r\n";
 /* Private global variables */
 /*==========================*/
 
+//Infos for all webdav-connections, every thread uses an own connection.
+struct server_session{
+    //The neon session
+    ne_session *neon_session;
+    //Will be set to 1 when dav_init_connection() succeeded.
+    int initialized;
+    //PID of the process, which uses this connection.
+    //pid_t pid;
+};
+
 /* The neon session.
    Will be set by dav_init_webdav(). */
-static ne_session *session;
+static struct server_session fg_session;
+static struct server_session bg_session;
+
+//Read- and write-lock for all important operations.
+extern pthread_mutex_t* mutex_allops;
 
 /* Lock store, lock owner and lock timeout for session.
    Will be set by dav_init_webdav(). */
@@ -201,9 +216,6 @@ static int precheck;
 /* Ignore the information in the DAV-header because it is wrong. */
 static int ignore_dav_header;
 
-/* Will be set to 1 when dav_init_connection() succeeded. */
-static int initialized;
-
 /* Whether a terminal is available to communicate with the user.
    Should be reset with set_no_terminal() when forking into daemon mode.
    Needed by  ssl_verify() which may be called at any time. */
@@ -247,12 +259,15 @@ static void
 convert(char **s, iconv_t conv);
 #endif
 
-static int
-get_error(int ret, const char *method);
+static void 
+start_session(struct server_session* sess, dav_args *args);
 
 static int
-get_ne_error(const char *method);
-
+get_error(ne_session *session, int ret, const char *method);
+ 
+static int
+get_ne_error(ne_session *session, const char *method);
+ 
 static struct ne_lock *
 lock_by_path(const char *path);
 
@@ -323,6 +338,28 @@ update_cookie(ne_request *req, void *userdata, const ne_status *status);
 /* Public functions */
 /*==================*/
 
+int
+mutex_lock(pthread_mutex_t* mutex)
+{
+    int ret = 0;
+    if(mutex){
+        if((ret = pthread_mutex_lock(mutex)))
+            syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "mutex_lock failed: %d", ret);
+    }
+    return ret;
+}
+
+int
+mutex_unlock(pthread_mutex_t* mutex)
+{
+    int ret = 0;
+    if(mutex){
+        if((ret = pthread_mutex_unlock(mutex)))
+            syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "mutex_unlock failed: %d", ret);
+    }
+    return ret;
+}
+
 void
 dav_init_webdav(dav_args *args)
 {
@@ -373,7 +410,23 @@ dav_init_webdav(dav_args *args)
         ne_debug_init(log_stream, args->neon_debug);
     }
 
-    session = ne_session_create(args->scheme, args->host, args->port);
+    start_session(&fg_session, args);
+    start_session(&bg_session, args);
+
+    use_expect100 = args->expect100;
+    has_if_match_bug = args->if_match_bug;
+    drop_weak_etags = args->drop_weak_etags;
+    precheck = args->precheck;
+    ignore_dav_header = args->ignore_dav_header;
+}
+
+/*  Start a new webdav-connection.
+    sess: webdav-session to store the new created neon-session.
+*/
+static void start_session(struct server_session* sess, dav_args *args){
+    sess->neon_session = ne_session_create(args->scheme, args->host, 
+                                           args->port);
+    ne_session *session = sess->neon_session;
 
     ne_set_read_timeout(session, args->read_timeout);
 
@@ -452,23 +505,18 @@ dav_init_webdav(dav_args *args)
         ne_hook_post_send(session, update_cookie, NULL);
 #endif /* NE_VERSION_MINOR > 25 */
 
-    use_expect100 = args->expect100;
-    has_if_match_bug = args->if_match_bug;
-    drop_weak_etags = args->drop_weak_etags;
-    precheck = args->precheck;
-    ignore_dav_header = args->ignore_dav_header;
 }
 
 
 int
-dav_init_connection(const char *path)
+dav_init_connection(struct server_session *sess, const char *path)
 {
     char *spath = ne_path_escape(path);
     ne_server_capabilities caps = {0, 0, 0};
-    int ret = ne_options(session, spath, &caps);
+    int ret = ne_options(sess->neon_session, spath, &caps);
 
     if (!ret) {
-        initialized = 1;
+        sess->initialized = 1;
         if (!caps.dav_class1 && !ignore_dav_header) {
             if (have_terminal) {
                 error(EXIT_FAILURE, 0,
@@ -480,7 +528,7 @@ dav_init_connection(const char *path)
             }
         }
         if ((caps.dav_class2 || ignore_dav_header) && locks) {
-            ne_lockstore_register(locks, session);
+            ne_lockstore_register(locks, sess->neon_session);
         } else if (locks) {
             if (have_terminal)
                 error(0, 0, _("warning: the server does not support locks"));
@@ -488,17 +536,17 @@ dav_init_connection(const char *path)
             locks = NULL;
         }
     } else {
-        ret = get_error(ret, "OPTIONS");
+        ret = get_error(sess->neon_session, ret, "OPTIONS");
     }
 
     free(spath);
     return ret;
 }
 
-
 void
-dav_close_webdav(void)
+dav_close_webdav_sess(struct server_session *sess)
 {
+  ne_session *session=sess->neon_session;
     if(session && log_stream)
         syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "Closing connection to  %s",
                ne_get_server_hostport(session));
@@ -508,7 +556,7 @@ dav_close_webdav(void)
         while (lock) {
             if (session) {
                 int ret = ne_unlock(session, lock);
-                get_error(ret, "UNLOCK");
+                get_error(session, ret, "UNLOCK");
             }
             lock = ne_lockstore_next(locks);
         }
@@ -519,6 +567,19 @@ dav_close_webdav(void)
     ne_sock_exit();
 }
 
+void
+dav_close_webdav(void)
+{
+  dav_close_webdav_sess(&fg_session);
+}
+
+void
+dav_close_webdav_bg(void)
+{
+  dav_close_webdav_sess(&bg_session);
+}
+
+
 
 char *
 dav_conv_from_utf_8(const char *s)
@@ -572,22 +633,24 @@ int
 dav_delete(const char *path, time_t *expire)
 {
     int ret;
-    if (!initialized) {
-        ret = dav_init_connection(path);
+    struct server_session *sess=&fg_session;
+    if (!sess->initialized) {
+        ret = dav_init_connection(sess, path);
         if (ret) return ret;
     }
+    ne_session *session=sess->neon_session;
 
     struct ne_lock *lock = NULL;
     char *spath = ne_path_escape(path);
     ret = ne_delete(session, spath);
-    ret = get_error(ret, "DELETE");
+    ret = get_error(session, ret, "DELETE");
 
     if ((ret == EACCES || ret == ENOENT) && locks) {
         lock_discover(spath, expire);
         lock = lock_by_path(spath);
         if (lock && ret == EACCES) {
             ret = ne_delete(session, spath);
-            ret = get_error(ret, "DELETE");
+            ret = get_error(session, ret, "DELETE");
         } else if (lock) {
             ne_unlock(session, lock);
             ret = 0;
@@ -611,14 +674,16 @@ int
 dav_delete_dir(const char *path)
 {
     int ret;
-    if (!initialized) {
-        ret = dav_init_connection(path);
+    struct server_session *sess=&fg_session;
+    if (!sess->initialized) {
+        ret = dav_init_connection(sess, path);
         if (ret) return ret;
     }
+    ne_session *session=sess->neon_session;
 
     char *spath = ne_path_escape(path);
     ret = ne_delete(session, spath);
-    ret = get_error(ret, "DELETE");
+    ret = get_error(session, ret, "DELETE");
 
     free(spath);
     return ret;
@@ -642,10 +707,12 @@ int
 dav_get_collection(const char *path, dav_props **props)
 {
     int ret;
-    if (!initialized) {
-        ret = dav_init_connection(path);
+    struct server_session *sess=&fg_session;
+    if (!sess->initialized) {
+        ret = dav_init_connection(sess, path);
         if (ret) return ret;
     }
+    ne_session *session=sess->neon_session;
 
     propfind_context ctx;
     ctx.path = path;
@@ -654,7 +721,7 @@ dav_get_collection(const char *path, dav_props **props)
     char *spath = ne_path_escape(path);
     ne_propfind_handler *ph = ne_propfind_create(session, spath, NE_DEPTH_ONE);
     ret = ne_propfind_named(ph, prop_names, prop_result, &ctx);
-    ret = get_error(ret, "PROPFIND");
+    ret = get_error(session, ret, "PROPFIND");
     ne_propfind_destroy(ph);
     free(spath);
 
@@ -674,7 +741,13 @@ dav_get_collection(const char *path, dav_props **props)
 const char *
 dav_get_webdav_error()
 {
-    return ne_get_error(session);
+    return ne_get_error(fg_session.neon_session);
+}
+
+const char *
+dav_get_webdav_error_bg()
+{
+    return ne_get_error(bg_session.neon_session);
 }
 
 
@@ -683,10 +756,12 @@ dav_get_file(const char *path, const char *cache_path, off_t *size,
              char **etag, time_t *mtime, char **mime, int *modified)
 {
     int ret;
-    if (!initialized) {
-        ret = dav_init_connection(path);
+    struct server_session *sess=&fg_session;
+    if (!sess->initialized) {
+        ret = dav_init_connection(sess, path);
         if (ret) return ret;
     }
+    ne_session *session=sess->neon_session;
 
     get_context ctx;
     ctx.error = 0;
@@ -707,7 +782,7 @@ dav_get_file(const char *path, const char *cache_path, off_t *size,
     ne_add_response_body_reader(req, ne_accept_2xx, file_reader, &ctx);
 
     ret = ne_request_dispatch(req);
-    ret = get_error(ret, "GET");
+    ret = get_error(session, ret, "GET");
     if (ctx.error)
         ret = ctx.error;
     const ne_status *status = ne_get_status(req);
@@ -757,15 +832,17 @@ dav_head(const char *path, char **etag, time_t *mtime, off_t *length,
          char **mime)
 {
     int ret;
-    if (!initialized) {
-        ret = dav_init_connection(path);
+    struct server_session *sess=&fg_session;
+    if (!sess->initialized) {
+        ret = dav_init_connection(sess, path);
         if (ret) return ret;
     }
+    ne_session *session=sess->neon_session;
 
     char *spath = ne_path_escape(path);
     ne_request *req = ne_request_create(session, "HEAD", spath);
     ret = ne_request_dispatch(req);
-    ret = get_error(ret, "HEAD");
+    ret = get_error(session, ret, "HEAD");
 
     const char *value = ne_get_response_header(req, "ETag");
     if (!ret && etag && value) {
@@ -801,10 +878,12 @@ int
 dav_lock(const char *path, time_t *expire, int *exists)
 {
     int ret;
-    if (!initialized) {
-        ret = dav_init_connection(path);
+    struct server_session *sess=&fg_session;
+    if (!sess->initialized) {
+        ret = dav_init_connection(sess, path);
         if (ret) return ret;
     }
+    ne_session *session=sess->neon_session;
 
     if (!locks) {
         *expire = 0;
@@ -842,7 +921,7 @@ dav_lock(const char *path, time_t *expire, int *exists)
         ne_hook_pre_send(session, add_header, none_match_header);
 #endif /* NE_VERSION_MINOR > 25 */
     ret = ne_lock(session, lock);
-    ret = get_error(ret, "LOCK");
+    ret = get_error(session, ret, "LOCK");
 #if NE_VERSION_MINOR > 25
     if (!has_if_match_bug && !*exists) {
         ne_unhook_pre_send(session, add_header, none_match_header);
@@ -873,8 +952,12 @@ dav_lock(const char *path, time_t *expire, int *exists)
 void
 dav_lock_refresh(const char *path, time_t *expire)
 {
-    if (!initialized && dav_init_connection(path) != 0)
-        return;
+    int ret;
+    struct server_session *sess=&fg_session;
+    if (!sess->initialized) {
+        ret = dav_init_connection(sess, path);
+        if (ret) return;
+    }
 
     if (!locks) {
         *expire = 0;
@@ -898,14 +981,16 @@ int
 dav_make_collection(const char *path)
 {
     int ret;
-    if (!initialized) {
-        ret = dav_init_connection(path);
+    struct server_session *sess=&fg_session;
+    if (!sess->initialized) {
+        ret = dav_init_connection(sess, path);
         if (ret) return ret;
     }
+    ne_session *session=sess->neon_session;
 
     char *spath = ne_path_escape(path);
     ret = ne_mkcol(session, spath);
-    ret = get_error(ret, "MKCOL");
+    ret = get_error(session, ret, "MKCOL");
 
     free(spath);
     return ret;
@@ -916,15 +1001,17 @@ int
 dav_move(const char *src, const char *dst)
 {
     int ret;
-    if (!initialized) {
-        ret = dav_init_connection(src);
+    struct server_session *sess=&fg_session;
+    if (!sess->initialized) {
+        ret = dav_init_connection(sess, src);
         if (ret) return ret;
     }
+    ne_session *session=sess->neon_session;
 
     char *spath = ne_path_escape(src);
     char *dst_path = ne_path_escape(dst);
     ret = ne_move(session, 1, spath, dst_path); 
-    ret = get_error(ret, "MOVE");
+    ret = get_error(session, ret, "MOVE");
 
     if (!ret && locks) {
         struct ne_lock *lock = lock_by_path(spath);
@@ -939,17 +1026,17 @@ dav_move(const char *src, const char *dst)
     return ret;
 }
 
-
 int
-dav_put(const char *path, const char *cache_path, int *exists, time_t *expire,
-        char **etag, time_t *mtime, char **mime, int execute)
+dav_put_sess(struct server_session *sess, const char *path, const char *cache_path,
+             int *exists, time_t *expire,
+             char **etag, time_t *mtime, char **mime, int execute)
 {
-    int ret = 0;
-    if (!initialized) {
-        ret = dav_init_connection(path);
+    int ret;
+    if (!sess->initialized) {
+        ret = dav_init_connection(sess, path);
         if (ret) return ret;
     }
-
+    ne_session *session=sess->neon_session;
 
     if (precheck && (has_if_match_bug || (*exists && (!etag || !*etag)))
             && (!*exists || (etag && *etag) || (mtime && *mtime))) {
@@ -1013,8 +1100,10 @@ dav_put(const char *path, const char *cache_path, int *exists, time_t *expire,
     ne_set_request_body_fd(req, fd, 0, st.st_size);
 #endif /* _FILE_OFFSET_BITS != 64 || NE_VERSION_MINOR >= 27 */
 
+    mutex_unlock(mutex_allops);    
     ret = ne_request_dispatch(req);
-    ret = get_error(ret, "PUT");
+    mutex_lock(mutex_allops);
+    ret = get_error(session, ret, "PUT");
 
     if (ret == EACCES && lock_discover(spath, expire) == 0) {
 
@@ -1044,8 +1133,10 @@ dav_put(const char *path, const char *cache_path, int *exists, time_t *expire,
         ne_set_request_body_fd(req, fd, 0, st.st_size);
 #endif /* _FILE_OFFSET_BITS != 64 || NE_VERSION_MINOR >= 27 */
 
+        mutex_unlock(mutex_allops);        
         ret = ne_request_dispatch(req);
-        ret = get_error(ret, "PUT");
+        mutex_lock(mutex_allops);        
+        ret = get_error(session, ret, "PUT");
     }
 
     int need_head = 0;
@@ -1096,15 +1187,33 @@ dav_put(const char *path, const char *cache_path, int *exists, time_t *expire,
     return ret;
 }
 
+int
+dav_put_bg(const char *path, const char *cache_path, int *exists, time_t *expire,
+        char **etag, time_t *mtime, char **mime, int execute)
+{
+  return dav_put_sess(&bg_session, path, cache_path, exists, expire, etag,
+                      mtime, mime, execute);
+}
+
+int
+dav_put(const char *path, const char *cache_path, int *exists, time_t *expire,
+        char **etag, time_t *mtime, char **mime, int execute)
+{
+  return dav_put_sess(&fg_session, path, cache_path, exists, expire, etag,
+                      mtime, mime, execute);
+}
+
 
 int
 dav_quota(const char *path, off64_t *total, off64_t *used)
 {
     int ret;
-    if (!initialized) {
-        ret = dav_init_connection(path);
+    struct server_session *sess=&fg_session;
+    if (!sess->initialized) {
+        ret = dav_init_connection(sess, path);
         if (ret) return ret;
     }
+    ne_session *session=sess->neon_session;
 
     static int use_rfc = 1;
     static int use_userinfo = 1;
@@ -1123,7 +1232,7 @@ dav_quota(const char *path, off64_t *total, off64_t *used)
         ne_propfind_handler *ph = ne_propfind_create(session, spath,
                                                      NE_DEPTH_ZERO);
         ret = ne_propfind_named(ph, quota_names, quota_result, &ctx);
-        ret = get_error(ret, "PROPFIND");
+        ret = get_error(session, ret, "PROPFIND");
         ne_propfind_destroy(ph);
 
         if (!ret && ctx.error) {
@@ -1138,7 +1247,7 @@ dav_quota(const char *path, off64_t *total, off64_t *used)
         ne_request *req = ne_request_create(session, "USERINFO", spath);
         ne_add_response_body_reader(req, ne_accept_2xx, quota_reader, &ctx);
         ret = ne_request_dispatch(req);
-        ret = get_error(ret, "USERINFO");
+        ret = get_error(session, ret, "USERINFO");
         ne_request_destroy(req);
 
         if (!ret) {
@@ -1163,10 +1272,12 @@ int
 dav_set_execute(const char *path, int set)
 {
     int ret;
-    if (!initialized) {
-        ret = dav_init_connection(path);
+    struct server_session *sess=&fg_session;
+    if (!sess->initialized) {
+        ret = dav_init_connection(sess, path);
         if (ret) return ret;
     }
+    ne_session *session=sess->neon_session;
 
     ne_proppatch_operation op[2];
     op[0].name = &prop_names[EXECUTE];
@@ -1180,7 +1291,7 @@ dav_set_execute(const char *path, int set)
 
     char *spath = ne_path_escape(path);
     ret = ne_proppatch(session, spath, &op[0]);
-    ret = get_error(ret, "PROPPATCH");
+    ret = get_error(session, ret, "PROPPATCH");
     free(spath);
 
     return ret;
@@ -1198,10 +1309,12 @@ int
 dav_unlock(const char *path, time_t *expire)
 {
     int ret;
-    if (!initialized) {
-        ret = dav_init_connection(path);
+    struct server_session *sess=&fg_session;
+    if (!sess->initialized) {
+        ret = dav_init_connection(sess, path);
         if (ret) return ret;
     }
+    ne_session *session=sess->neon_session;
 
     if (!locks) {
         *expire = 0;
@@ -1218,7 +1331,7 @@ dav_unlock(const char *path, time_t *expire)
     }
 
     ret = ne_unlock(session, lock);
-    ret = get_error(ret, "UNLOCK");
+    ret = get_error(session, ret, "UNLOCK");
 
     if (!ret || ret == ENOENT || ret == EINVAL) {
         ne_lockstore_remove(locks, lock);
@@ -1265,13 +1378,13 @@ convert(char **s, iconv_t conv)
    method : name of the WebDAV method, used for debug messages.
    return value : a file error code according to errno.h. */
 static int
-get_error(int ret, const char *method)
+get_error(ne_session *session, int ret, const char *method)
 {
     int err;
     switch (ret) {
     case NE_OK:
     case NE_ERROR:
-        err = get_ne_error(method);
+        err = get_ne_error(session, method);
         break;
     case NE_LOOKUP:
         err = EIO;
@@ -1310,7 +1423,7 @@ get_error(int ret, const char *method)
    method : name of the WebDAV method, used for debug messages.
    return value : a file error code according to errno.h. */
 static int
-get_ne_error(const char *method)
+get_ne_error(ne_session *session, const char *method)
 {
     const char *text = ne_get_error(session);
 
@@ -1408,6 +1521,7 @@ lock_by_path(const char *path)
 static int
 lock_discover(const char *path, time_t *expire)
 {
+    ne_session *session=fg_session.neon_session;
     if (!locks) {
         *expire = 0;
         return -1;
@@ -1415,7 +1529,7 @@ lock_discover(const char *path, time_t *expire)
 
     struct ne_lock *lock = NULL;
     int ret = ne_lock_discover(session, path, lock_result, &lock);
-    ret = get_error(ret, "LOCKDISCOVER");
+    ret = get_error(session, ret, "LOCKDISCOVER");
 
     if (!ret && lock)  {
         *expire = -1;
@@ -1436,8 +1550,9 @@ lock_discover(const char *path, time_t *expire)
 static void
 lock_refresh(struct ne_lock *lock, time_t *expire)
 {
+    ne_session *session=fg_session.neon_session;
     int ret = ne_lock_refresh(session, lock);
-    ret = get_error(ret, "LOCKREFRESH");
+    ret = get_error(session, ret, "LOCKREFRESH");
 
     if (!ret) {
         if (lock->timeout <= 0) {
@@ -1597,6 +1712,8 @@ auth(void *userdata, const char *realm, int attempt, char *user, char *pwd)
 static int
 file_reader(void *userdata, const char *block, size_t length)
 {
+    ne_session *session=fg_session.neon_session;
+
     get_context *ctx = (get_context *) userdata;
     if (!ctx->fd)
         ctx->fd = open(ctx->file, O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR);
@@ -2008,6 +2125,7 @@ ssl_verify(void *userdata, int failures, const ne_ssl_certificate *cert)
 static int
 update_cookie(ne_request *req, void *userdata, const ne_status *status)
 {
+    ne_session *session=fg_session.neon_session;
     if (status->klass != 2)
         return NE_OK;
 
diff --git a/src/webdav.h b/src/webdav.h
index c1dd801..48f364b 100644
--- a/src/webdav.h
+++ b/src/webdav.h
@@ -44,6 +44,8 @@ struct dav_props {
     dav_props *next;    /* Next in the list. */
 };
 
+// forward declaration
+struct server_session;
 
 /* Function prototypes */
 /*=====================*/
@@ -65,7 +67,7 @@ dav_init_webdav(dav_args* args);
    path : Path to the root collection.
    return value : 0 on success or an apropriate error code. */
 int
-dav_init_connection(const char *path);
+dav_init_connection(struct server_session *sess, const char *path);
 
 
 /* Releases all locks (if possible) and closes the session.
@@ -160,6 +162,8 @@ dav_get_file(const char *path, const char *cache_path, off_t *size,
 const char *
 dav_get_webdav_error(void);
 
+const char *
+dav_get_webdav_error_bg(void);
 
 /* Tests for the existence of file path and uptdates etag, mtime and length.
    In case of an error etag and mtime are not changed. If the server does not
@@ -246,6 +250,10 @@ int
 dav_put(const char *path, const char *cache_path, int *exists, time_t *expire,
         char **etag, time_t *mtime, char **mime, int execute);
 
+int
+dav_put_bg(const char *path, const char *cache_path, int *exists, time_t *expire,
+           char **etag, time_t *mtime, char **mime, int execute);
+
 /* Makes a PROPFIND request for path to get quota information (RFC 4331)
    and places them in total and used.
    toatal is the sum of quota-available-bytes and quota-used-bytes.
@@ -276,5 +284,6 @@ dav_set_no_terminal(void);
 int
 dav_unlock(const char *path, time_t *expire);
 
-
+int mutex_unlock(pthread_mutex_t* mutex);
+int mutex_lock(pthread_mutex_t* mutex);
 #endif /* DAV_WEBDAV_H */
