diff --git a/inc/lektor/cmd.h b/inc/lektor/cmd.h
index 365a87596717660251a8bbd2bfbb73b4cca17a6a..23baa17b4ffdd9d1c51245399e99762871121cdb 100644
--- a/inc/lektor/cmd.h
+++ b/inc/lektor/cmd.h
@@ -26,4 +26,4 @@ noreturn void lkt_cmd_parse(struct lkt_cmd_opt *opts, int argc, const char **arg
    in case of errors. */
 extern const char *executable_name;
 
-noreturn void help__(void);
+noreturn void print_help(void);
diff --git a/inc/lektor/thread.h b/inc/lektor/thread.h
index d1fb59eb0214ad51948b931cba593c4e922c5641..56fe2cdf3b6951e20231c1cc37811cdbb73f5233 100644
--- a/inc/lektor/thread.h
+++ b/inc/lektor/thread.h
@@ -23,7 +23,6 @@ struct poller_thread_arg {
     void *args;
 };
 
-
 /* Create a new thread. Returns 0 on success, a non zero value on error. */
 int poller_new(struct poller_thread *th, void *(*func)(struct poller_thread_arg *), void *args);
 
diff --git a/inc/mthread/mthread.h b/inc/mthread/mthread.h
index 869e0ddd4c3b0ecfc0b1e4eaca697a5a5761046a..6806967497f838685af43acaeb86b8f7fac5bfdd 100644
--- a/inc/mthread/mthread.h
+++ b/inc/mthread/mthread.h
@@ -36,8 +36,6 @@ typedef struct mthread_cond_s mthread_cond_t;
 struct mthread_condattr_s;
 typedef struct mthread_condattr_s mthread_condattr_t;
 
-typedef unsigned int mthread_key_t;
-
 typedef mthread_tst_t mthread_once_t;
 
 struct mthread_sem_s {
@@ -54,53 +52,7 @@ extern mthread_t mthread_self(void);
 extern int  mthread_equal (mthread_t __thread1, mthread_t __thread2);
 extern void mthread_exit  (void *__retval);
 extern int  mthread_join  (mthread_t __th, void **__thread_return);
-
-/* Functions for mutex handling.  */
-
-extern int mthread_mutex_init   (mthread_mutex_t *__mutex, const mthread_mutexattr_t *__mutex_attr);
-extern int mthread_mutex_destroy(mthread_mutex_t *__mutex);
-extern int mthread_mutex_trylock(mthread_mutex_t *__mutex);
-extern int mthread_mutex_lock   (mthread_mutex_t *__mutex);
-extern int mthread_mutex_unlock (mthread_mutex_t *__mutex);
-
-/* Functions for handling conditional variables.  */
-
-extern int mthread_cond_init     (mthread_cond_t *__cond, const mthread_condattr_t *__cond_attr);
-extern int mthread_cond_destroy  (mthread_cond_t *__cond);
-extern int mthread_cond_signal   (mthread_cond_t *__cond);
-extern int mthread_cond_broadcast(mthread_cond_t *__cond);
-extern int mthread_cond_wait     (mthread_cond_t *__cond, mthread_mutex_t *__mutex);
-
-/* Functions for handling thread-specific data.  */
-
-extern int  mthread_key_create  (mthread_key_t *__key, void (*__destr_function) (void *));
-extern int  mthread_key_delete  (mthread_key_t __key);
-extern int  mthread_setspecific (mthread_key_t __key, const void *__pointer);
-extern void *mthread_getspecific(mthread_key_t __key);
-
-
-/* Functions for handling initialization.  */
-
-/* Guarantee that the initialization function INIT_ROUTINE will be called
-   only once, even if mthread_once is executed several times with the
-   same ONCE_CONTROL argument. ONCE_CONTROL must point to a static or
-   variable initialized to MTHREAD_ONCE_INIT.
-
-   The initialization functions might throw exception which is why
-   this function is not marked with .  */
-extern int mthread_once(mthread_once_t *__once_control, void (*__init_routine) (void));
-
-/* Functions for handling semaphore.  */
-
-extern int mthread_sem_init(mthread_sem_t *sem, unsigned int value);
-extern int mthread_sem_wait(mthread_sem_t *sem);     /* P(sem), wait(sem) */
-extern int mthread_sem_post(mthread_sem_t *sem);     /* V(sem), signal(sem) */
-
-extern int mthread_sem_getvalue(mthread_sem_t *sem, int *sval);
-extern int mthread_sem_trywait (mthread_sem_t *sem);
-extern int mthread_sem_destroy (mthread_sem_t *sem);  /* undo sem_init() */
-
-extern void mthread_yield();
+extern void mthread_yield ();
 
 /* Initialize mthread. */
 
diff --git a/inc/mthread/mthread_internal.h b/inc/mthread/mthread_internal.h
index 285f337ed5d1ad1393382f36a9d2c4983a9cdcfb..832a019ddd28a08b7a88c22caf28402d04fd6e2b 100644
--- a/inc/mthread/mthread_internal.h
+++ b/inc/mthread/mthread_internal.h
@@ -31,14 +31,6 @@ typedef struct {
 typedef enum { RUNNING, BLOCKED, ZOMBIE } mthread_status_t;
 typedef volatile enum { JOINABLE = 0, DETACHED = 1, DETACHED_FREE = 2 } mthread_detached_flag_t;
 
-#define INIT_KEYS_LIST 48
-
-struct keys_list {
-    volatile mthread_key_t *list;
-    unsigned int first_avail;
-    unsigned int size;
-};
-
 struct mthread_s {
     ucontext_t uc;
     volatile void *res;
@@ -50,7 +42,6 @@ struct mthread_s {
     int not_migrable;
     mthread_virtual_processor_t *vp;
     void *stack;
-    struct keys_list keys;
 };
 
 #define MTHREAD_LIST_INIT { .first = NULL, .last = NULL, .lock = 0 }
diff --git a/meson.build b/meson.build
index c73a83c2b77a585050199de16d311ac03bd6888f..480f732ba20fc552b9673890c0d80b4a51991040 100644
--- a/meson.build
+++ b/meson.build
@@ -3,7 +3,6 @@ project( 'lektor'
        , version: '0.1.0'
        , license: 'ISC'
        , default_options: [ 'c_std=c18'
-                          , 'cpp_std=c++17'
                           , 'warning_level=3'
                           , 'werror=true'
                           , 'strip=true'
@@ -38,16 +37,6 @@ endif
 ## Module list
 lektor_modules = []
 
-## Sources for mthread
-mthread_sources = [ 'src/mthread/mthread.c'
-                  , 'src/mthread/mthread_cond.c'
-                  , 'src/mthread/mthread_key.c'
-                  , 'src/mthread/mthread_mutex.c'
-                  , 'src/mthread/mthread_once.c'
-                  , 'src/mthread/mthread_sem.c'
-                  , 'src/mthread/mthread_tst.c'
-                  ]
-
 ## Common files
 common_sources = [ 'src/common.c'
                  , 'src/stack.c'
@@ -59,7 +48,6 @@ common_sources = [ 'src/common.c'
 core_sources =  [ 'src/mkv/write.c'
                 , 'src/mkv/utils.c'
                 , 'src/mkv/mkv.c'
-                , 'src/commands.c'
                 , 'src/database/stickers.c'
                 , 'src/database/open.c'
                 , 'src/database/queue.c'
@@ -72,6 +60,8 @@ core_sources =  [ 'src/mkv/write.c'
                 , 'src/net/listen.c'
                 , 'src/net/message.c'
                 , 'src/module/repo.c'
+                , 'src/mthread.c'
+                , 'src/commands.c'
                 , 'src/config.c'
                 , 'src/uri.c'
                 , 'src/thread.c'
@@ -110,7 +100,7 @@ xxd = generator( find_program('xxd')
                , arguments: [ '-i', '@INPUT@', '@OUTPUT@' ] )
 
 lib = both_libraries( 'lektor'
-                    , files(core_sources + mthread_sources)
+                    , files(core_sources)
                     , xxd.process('src/database/disk.sql')
                     , xxd.process('src/database/memory.sql')
                     , manpath
diff --git a/meson_options.txt b/meson_options.txt
index 9791739bdcb0f6034c5d537074d5d3adb1d3e768..5ac48a6a141ddd789bd84ff77a2308f8a5c7a862 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,4 +1,3 @@
-option('static_modules', type: 'feature', value: 'enabled'
-      , description: 'Build modules and link them statically with lektord')
-option('module_sdl', type: 'feature', value: 'enabled', description: 'Build the sdl module')
-option('static_liblektor', type: 'boolean', value: true, description: 'Link the liblektor statically')
+option('static_modules',    type: 'feature', value: 'enabled',  description: 'Build modules and link them statically with lektord')
+option('module_sdl',        type: 'feature', value: 'enabled',  description: 'Build the sdl module')
+option('static_liblektor',  type: 'boolean', value: true,       description: 'Link the liblektor statically')
diff --git a/src/cmd.c b/src/cmd.c
index 4f19b19519eafe19127bb3c2dc7245c35e0ebd85..3edfaa237d9960e7e84087ae476cc8e41c268bc3 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -13,7 +13,7 @@ const char *executable_name = NULL;
 extern const char *man_executable_path;
 
 noreturn void
-help__(void)
+print_help(void)
 {
     if (!executable_name)
         exit(EXIT_FAILURE);
@@ -71,7 +71,7 @@ not_found:
     exit(EXIT_FAILURE);
 
 help:
-    help__();
+    print_help();
 
 not_exclusive:
     LOG_ERROR("COMMAND", "Failed to determine option, '%s' not exclusive",
diff --git a/src/database/playlist.c b/src/database/playlist.c
index a4b9b26c71516502a54e74277a9fd2ea12841cd2..d882ef0b125af1b09eafa29d6c65789d4bb68529 100644
--- a/src/database/playlist.c
+++ b/src/database/playlist.c
@@ -163,38 +163,15 @@ database_plt_add_uri(volatile sqlite3 *db, const char *name,
                      struct lkt_uri *uri)
 {
     static const char *SQL =
-        "WITH plt_id(id) AS (SELECT playlist.id AS id FROM playlist"
-        " WHERE name COLLATE nocase = ?) "
-        "INSERT INTO kara_playlist (kara_id, playlist_id) "
-        "SELECT plt_id.id, kara.id "
-        "  FROM kara, plt_id "
-        "  WHERE kara.%s LIKE ? "
-        "  ORDER BY RANDOM();";
+        "INSERT OR REPLACE INTO kara_playlist (kara_id, playlist_id) "
+        "SELECT"
+        " kara.id,"
+        " (SELECT playlist.id FROM playlist WHERE name = ? COLLATE NOCASE)"
+        "FROM kara WHERE kara.%s LIKE ?;";
     char SQL_STMT[LKT_MAX_SQLITE_STATEMENT], sta = false;
-    const char *column;
     sqlite3_stmt *stmt;
 
-    switch (uri->type) {
-    case uri_type:
-        column = LKT_DB_TYPE;
-        break;
-    case uri_author:
-        column = LKT_DB_AUTHOR;
-        break;
-    case uri_category:
-        column = LKT_DB_CAT;
-        break;
-    case uri_language:
-        column = LKT_DB_LANG;
-        break;
-    case uri_query:
-        column = LKT_DB_ALL;
-        break;
-    default:
-        return false;
-    }
-
-    safe_snprintf(SQL_STMT, LKT_MAX_SQLITE_STATEMENT, SQL, column);
+    safe_snprintf(SQL_STMT, LKT_MAX_SQLITE_STATEMENT, SQL, uri->column_name);
     SQLITE_PREPARE(db, stmt, SQL_STMT, error);
     SQLITE_BIND_TEXT(db, stmt, 1, name, error);
     SQLITE_BIND_TEXT(db, stmt, 2, (char *) uri->value, error);
diff --git a/src/database/queue.c b/src/database/queue.c
index 92d82e63b59c3e80a1a30828716d045993e21578..9762414cc190ac529b71ceaa860eea0cff1c9277 100644
--- a/src/database/queue.c
+++ b/src/database/queue.c
@@ -119,8 +119,10 @@ error:
     if (prio > 1) {                                             \
         if (__queue_reorder(db)) {                              \
             LOG_INFO("DB", "%s", "Queue has been reordered");   \
-        } else                                                  \
+        } else {                                                \
+            LOG_INFO("DB", "%s", "Failed to reorder");          \
             goto error;                                         \
+        }                                                       \
     }
 
 static bool
@@ -131,7 +133,7 @@ __queue_reorder(volatile sqlite3 *db)
     " ELSE (SELECT current FROM queue_state) END AS val LIMIT 1)"
     static const char *SQL_REORDER =
         /* Create temporary tables */
-        "CREATE TEMPORARY TABLE queue_tmp"
+        "CREATE TEMPORARY TABLE queue_tmp IF NOT EXISTS"
         " ( position INTEGER PRIMARY KEY AUTOINCREMENT CHECK(position > 0)"
         " , kara_id INTEGER"
         " , priority INTEGER NOT NULL DEFAULT 1 CHECK(priority > 0 AND priority < 6)"
@@ -146,7 +148,7 @@ __queue_reorder(volatile sqlite3 *db)
         " SELECT position + " CURRENT_POS_OR_0 ", kara_id, priority"
         " FROM queue_tmp;"
         /* Drop temporary tables */
-        "DROP TABLE queue_tmp;"
+        "DELETE FROM queue_tmp;"
         "DELETE FROM sqlite_sequence WHERE name = 'queue_tmp';";
 #undef CURRENT_POS_OR_0
     SQLITE_EXEC(db, SQL_REORDER, error);
@@ -274,7 +276,7 @@ database_queue_add_uri(volatile sqlite3 *db, struct lkt_uri *uri, int prio)
     case uri_author:
         return queue_add_with_col_like_str(db, LKT_DB_AUTHOR, uri->value, prio);
     case uri_playlist:
-        return database_queue_add_plt(db, (char *) uri->value, prio);
+        return database_queue_add_plt(db, uri->value, prio);
     default:
         LOG_WARN("DB", "Add to queue for uri of type %d is not"
                  " implemented", uri->type);
diff --git a/src/main/lkt.c b/src/main/lkt.c
index f1f24c32e29c4770a3f5b38ef748536782f0ac57..ecf48701a9824fcfc2c2b9a4cfdaacb1b24217d9 100644
--- a/src/main/lkt.c
+++ b/src/main/lkt.c
@@ -733,7 +733,17 @@ plt_add__(struct lkt_cmd_args *args)
     FILE *sock = lkt_connect();
     fail_if(args->argc < 3,                 "Invalid argument, need at least three arguments: plt add <plt> <query>");
     fail_if(!lkt_valid_type(args->argv[1]), "Invalid argument, type for the query is invalid");
-    send_cmd_with_uri(sock, "playlistadd", args->argc, args->argv);
+
+    int i;
+    char buf[LKT_MESSAGE_MAX] = {0};
+    for (i = 2; i < args->argc - 1; ++i) {
+        strncat(buf, args->argv[i], LKT_MESSAGE_MAX - 1);
+        strncat(buf, " ", LKT_MESSAGE_MAX - 1);
+    }
+    strncat(buf, args->argv[i], LKT_MESSAGE_MAX - 1);
+    strncat(buf, "\n", LKT_MESSAGE_MAX - 1);
+    write_socket(sock, "playlistadd %s %s://%s", args->argv[0], args->argv[1], buf);
+
     exit_with_status(sock, buff);
 }
 
diff --git a/src/main/server.c b/src/main/server.c
index eb9054adff6f3dca159e2efb1fa555c3a1102274..0742684c853e1dc3f2a8e2d1c4efdf46e508f1ea 100644
--- a/src/main/server.c
+++ b/src/main/server.c
@@ -54,7 +54,7 @@ main(int argc, char *argv[])
             break;
         case 'h':
         default:
-            help__();
+            print_help();
             exit(EXIT_SUCCESS);
         }
     }
diff --git a/src/mthread/mthread.c b/src/mthread.c
similarity index 85%
rename from src/mthread/mthread.c
rename to src/mthread.c
index 3cd1d0ac2227e4deb4b93e90967dad36f471e787..48506d509401d38c1f9f90b258e4838aaba44f72 100644
--- a/src/mthread/mthread.c
+++ b/src/mthread.c
@@ -7,30 +7,83 @@
 
 #define MTHREAD_LWP 1
 
-static mthread_virtual_processor_t virtual_processors[MTHREAD_MAX_VIRUTAL_PROCESSORS];
-static mthread_list_t joined_list;
+#if defined(i686_ARCH) || defined(x86_64_ARCH)
 
-/* Is mthread initialized */
-static volatile int is_mthread_init = 0;
+static inline int
+__mthread_test_and_set(mthread_tst_t *atomic)
+{
+    int ret;
+    __asm__ __volatile__("lock; xchgl %0, %1":"=r"(ret), "=m"(*atomic):"0"(1), "m"(*atomic):"memory");
+    return ret;
+}
 
-static void
-__mthread_clear_keys(mthread_t *thread)
+#elif defined(sparc_ARCH)
+static inline int
+__mthread_test_and_set(mthread_tst_t *spinlock)
 {
-    RETURN_UNLESS(thread, "Invalid argument", NOTHING);
-    unsigned int i;
-    struct keys_list *keys = &(*thread)->keys;
+    char ret = 0;
+    __asm__ __volatile__("ldstub [%0], %1": "=r"(spinlock), "=r"(ret): "0"(spinlock), "1" (ret) : "memory");
+    return (unsigned) ret;
+}
 
-    if (!keys) {
-        keys->first_avail = 0;
-        return;
-    }
+#elif defined(ia64_ARCH)
+static __inline__ int
+__mthread_test_and_set(mthread_tst_t *atomic)
+{
+    int ret;
+    __asm__ __volatile__("xchg4 %0=%1, %2":"=r"(ret), "=m"(*atomic):"0"(1), "m"(*atomic):"memory");
+    return ret;
+}
+#else
+#define USE_GENERIC_ASM
+#include <pthread.h>
+static pthread_mutex_t tst_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static inline int
+__mthread_test_and_set(mthread_tst_t *atomic)
+{
+    int res;
+    pthread_mutex_lock(&tst_mutex);
+    res = *atomic;
+    if (*atomic == 0)
+        *atomic = 1;
+    pthread_mutex_unlock(&tst_mutex);
+    return res;
+}
+#endif
 
-    for (i = 0; i < keys->first_avail; ++i)
-        mthread_key_delete(keys->list[i]);
+int
+mthread_test_and_set(mthread_tst_t *atomic)
+{
+    return __mthread_test_and_set(atomic);
+}
 
-    keys->first_avail = 0;
+void
+mthread_spinlock_lock(mthread_tst_t *atomic)
+{
+#ifdef USE_GENERIC_ASM
+    static pthread_mutex_t spin_tst_mutex = PTHREAD_MUTEX_INITIALIZER;
+    pthread_mutex_lock(&spin_tst_mutex);
+#endif
+    while (mthread_test_and_set(atomic))
+        sched_yield();
+#ifdef USE_GENERIC_ASM
+    pthread_mutex_unlock(&spin_tst_mutex);
+#endif
 }
 
+void
+mthread_spinlock_unlock(mthread_tst_t *atomic)
+{
+    *atomic = 0;
+}
+
+static mthread_virtual_processor_t virtual_processors[MTHREAD_MAX_VIRUTAL_PROCESSORS];
+static mthread_list_t joined_list;
+
+/* Is mthread initialized */
+static volatile int is_mthread_init = 0;
+
 static inline void
 mthread_list_init(mthread_list_t *list)
 {
@@ -370,7 +423,6 @@ mthread_join(mthread_t __th, void **__thread_return)
     if (__thread_return != NULL)
         *__thread_return = (void *)__th->res;
 
-    __mthread_clear_keys(&__th);
     LOG_INFO("THREAD END", "Thread %p joined", (void *) __th);
     mthread_insert_last(__th, &(joined_list));
     return 0;
diff --git a/src/mthread/mthread_cond.c b/src/mthread/mthread_cond.c
deleted file mode 100644
index 1956f4420e5c3bbae4a10546c247369b9e9d3c01..0000000000000000000000000000000000000000
--- a/src/mthread/mthread_cond.c
+++ /dev/null
@@ -1,101 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-
-#include <mthread/mthread_internal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* Functions for handling conditional variables.  */
-
-/* Initialize condition variable COND using attributes ATTR, or use
-   the default values if later is NULL.  */
-int
-mthread_cond_init(mthread_cond_t *__cond, const mthread_condattr_t *__cond_attr)
-{
-    (void)__cond_attr;
-    __cond->lock = 0;
-    __cond->list = safe_malloc(sizeof(struct mthread_list_s));
-    memset(__cond->list, 0, sizeof(struct mthread_list_s));
-    LOG_INFO("MTHREAD", "%s", "Successfully created a condition");
-    return 0;
-}
-
-/* Destroy condition variable COND.  */
-int
-mthread_cond_destroy(mthread_cond_t *__cond)
-{
-    if (__cond->list)
-        free((void *) __cond->list);
-    return 0;
-}
-
-/* Wake up one thread waiting for condition variable COND.  */
-int
-mthread_cond_signal(mthread_cond_t *__cond)
-{
-    mthread_t first, self = mthread_self();
-    mthread_virtual_processor_t *vp;
-    int ret = 1;
-    mthread_spinlock_lock(&__cond->lock);
-
-    if (__cond->list->first != NULL) {
-        first = mthread_remove_first(__cond->list);
-        vp = mthread_get_vp();
-        first->status = RUNNING;
-        mthread_insert_last(first, &(vp->ready_list));
-        LOG_INFO("MTHREAD", "Wake up the thread %p from the thread %p",
-                 (void *) first, (void *) self);
-        ret = 0;
-    } else
-        LOG_INFO("MTHREAD", "No thread to wake up found from the thread %p",
-                 (void *) self);
-
-    mthread_spinlock_unlock(&__cond->lock);
-    return ret;
-}
-
-/* Wake up all threads waiting for condition variables COND.  */
-int
-mthread_cond_broadcast(mthread_cond_t *__cond)
-{
-    mthread_t first, self = mthread_self();
-    mthread_virtual_processor_t *vp;
-    mthread_spinlock_lock(&__cond->lock);
-
-    while (__cond->list->first != NULL) {
-        first = mthread_remove_first(__cond->list);
-        vp = mthread_get_vp();
-        first->status = RUNNING;
-        LOG_INFO("MTHREAD", "Wake up the thread %p from the thread %p",
-                 (void *) first, (void *) self);
-        mthread_insert_last(first, &(vp->ready_list));
-    }
-
-    mthread_spinlock_unlock(&__cond->lock);
-    return 0;
-}
-
-/* Wait for condition variable COND to be signaled or broadcast.
-   MUTEX is assumed to be locked before.  */
-int
-mthread_cond_wait(mthread_cond_t *__cond, mthread_mutex_t *__mutex)
-{
-    mthread_spinlock_lock(&__cond->lock);
-    mthread_t self = mthread_self();
-    mthread_virtual_processor_t *vp = mthread_get_vp();
-    mthread_insert_last(self, __cond->list);
-    self->status = BLOCKED;
-    mthread_mutex_unlock(__mutex);
-
-    LOG_ERROR("MTHREAD", "Waiting in condition for thread %p",
-              (void *) self);
-
-    vp->p = &__cond->lock;
-    mthread_yield();
-
-    mthread_mutex_lock(__mutex);
-    LOG_ERROR("MTHREAD", "Waike up in condition for thread %p",
-              (void *) self);
-
-    return 0;
-}
diff --git a/src/mthread/mthread_key.c b/src/mthread/mthread_key.c
deleted file mode 100644
index 96d650ddc7cb9eaf7b7923c894be5fbc84445a9d..0000000000000000000000000000000000000000
--- a/src/mthread/mthread_key.c
+++ /dev/null
@@ -1,165 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-
-#include <mthread/mthread_internal.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* TODO -> use binaty trees for better performance in searches. */
-typedef struct cell_s {
-    mthread_key_t key;
-    const volatile void *volatile spec;
-    void (* destr)(void *);
-    volatile struct cell_s *volatile next;
-} cell_t;
-
-/* Default is 0. Index start at zero. Because of that the vairables hold the
-   first available slots and not the last used slots in memory. */
-static volatile mthread_key_t first_avail_key   = 1;
-static volatile cell_t *volatile key_table      = NULL;
-
-/* Protects anything concerning the keys. */
-static mthread_tst_t lock = 0;
-
-/* Functions for handling thread-specific data. */
-
-/* Create a key value identifying a location in the thread-specific
-   data area.  Each thread maintains a distinct thread-specific data
-   area. DESTR_FUNCTION, if non-NULL, is called with the value
-   associated to that key when the key is destroyed.
-   DESTR_FUNCTION is not called if the value associated is NULL when
-   the key is destroyed. */
-int
-mthread_key_create(mthread_key_t *__key, void (*__destr_function) (void *))
-{
-    cell_t *new_cell = (cell_t *) safe_malloc(sizeof(cell_t));
-    mthread_spinlock_lock(&lock);
-
-    /* Creation. */
-    new_cell->key   = first_avail_key;
-    new_cell->spec  = NULL;
-    new_cell->destr = __destr_function;
-    new_cell->next  = NULL;
-
-    first_avail_key++;
-
-    if (key_table) {
-        new_cell->next = key_table;
-        key_table = new_cell;
-    } else
-        key_table = new_cell;
-
-    /* Register key into the thread. */
-
-    struct keys_list *keys = &(mthread_self()->keys);
-    if (!keys->list) {
-        keys->list = (mthread_key_t *) safe_malloc(INIT_KEYS_LIST * sizeof(mthread_key_t));
-        keys->first_avail = 0;
-        keys->size = INIT_KEYS_LIST;
-    }
-
-    if (keys->size == keys->first_avail) {
-        /* Extend size if no space left. */
-        void *new = realloc((void *) keys->list, (keys->size + INIT_KEYS_LIST) * sizeof(mthread_key_t));
-        GOTO_UNLESS(new, "Could not increase the size of the key list", end);
-        keys->size += INIT_KEYS_LIST;
-        keys->list = new;
-    }
-
-    /* Register the key into the thread. */
-    keys->list[keys->first_avail] = new_cell->key;
-    keys->first_avail++;
-
-    /* Returns. */
-    *__key = new_cell->key;
-end:
-    mthread_spinlock_unlock(&lock);
-    return errno;
-}
-
-/* Destroy KEY. */
-int
-mthread_key_delete(mthread_key_t __key)
-{
-    mthread_spinlock_lock(&lock);
-
-    cell_t *it = (cell_t *) key_table;
-    cell_t *last = NULL;
-
-    while (it != NULL && it->key != __key) {
-        last = it;
-        it = (cell_t *) it->next;
-    }
-
-    if (!it) {
-        errno = EINVAL;
-        LOG_ERROR("MTHREAD", "Key %u not found", __key);
-        goto end;
-    }
-
-    if (it->destr) {
-        LOG_INFO("MTHREAD", "Call function on data at %p",
-                 (void *) it->spec);
-        it->destr((void *) it->spec);
-    }
-
-    /* Handle deletion in the linked list. */
-
-    if (last)
-        last->next = it->next;
-    else
-        key_table = it->next;
-
-    free(it);
-    LOG_INFO("MTHREAD", "Deleted key %u successfully", __key);
-    /* End of the function, simply returns. */
-end:
-    mthread_spinlock_unlock(&lock);
-    return errno;
-}
-
-/* Store POINTER in the thread-specific data slot identified by KEY. */
-int
-mthread_setspecific(mthread_key_t __key, const void *__pointer)
-{
-    mthread_spinlock_lock(&lock);
-
-    cell_t *it = (cell_t *) key_table;
-    while (it != NULL && it->key != __key)
-        it = (cell_t *) it->next;
-
-    if (!it) {
-        errno = EINVAL;
-        LOG_ERROR("MTHREAD", "Key %u not found", __key);
-        goto end;
-    }
-
-    it->spec = __pointer;
-    /* End of the function, simply returns. */
-end:
-    mthread_spinlock_unlock(&lock);
-    return errno;
-}
-
-/* Return current value of the thread-specific data slot identified by KEY. */
-void *
-mthread_getspecific(mthread_key_t __key)
-{
-    void *ret = NULL;
-    mthread_spinlock_lock(&lock);
-
-    cell_t *it = (cell_t *) key_table;
-    while (it != NULL && it->key != __key)
-        it = (cell_t *) it->next;
-
-    if (!it) {
-        errno = EINVAL;
-        LOG_ERROR("MTHREAD", "Key %u not found", __key);
-        goto end;
-    }
-
-    ret = (void *) it->spec;
-    /* End of the function, simply returns. */
-end:
-    mthread_spinlock_unlock(&lock);
-    return (void *) ret;
-}
diff --git a/src/mthread/mthread_mutex.c b/src/mthread/mthread_mutex.c
deleted file mode 100644
index beb344bae6282d57d80d78c82aa8efbed26864f8..0000000000000000000000000000000000000000
--- a/src/mthread/mthread_mutex.c
+++ /dev/null
@@ -1,120 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-
-#include <common/common.h>
-#include <errno.h>
-#include <string.h>
-#include <mthread/mthread_internal.h>
-
-/* Functions for mutex handling.  */
-
-/* Initialize MUTEX using attributes in *MUTEX_ATTR, or use the
-   default values if later is NULL.  */
-int
-mthread_mutex_init(mthread_mutex_t *__mutex, const mthread_mutexattr_t *__mutex_attr)
-{
-    UNUSED(__mutex_attr);
-    __mutex->list        = safe_malloc(sizeof(mthread_list_t));
-    __mutex->list->first = NULL;
-    __mutex->list->last  = NULL;
-    __mutex->nb_thread   = 0;
-    __mutex->lock        = 0;
-    LOG_INFO("MTHREAD", "%s", "MUTEX initialized");
-    return 0;
-}
-
-/* Destroy MUTEX.  */
-int
-mthread_mutex_destroy(mthread_mutex_t *__mutex)
-{
-    mthread_spinlock_lock(&__mutex->lock);
-
-    if (__mutex->nb_thread != 0)
-        return EBUSY;
-    free(__mutex->list);
-    __mutex->list = NULL;
-
-    mthread_spinlock_unlock(&__mutex->lock);
-    return 0;
-}
-
-/* Try to lock MUTEX.  */
-int
-mthread_mutex_trylock(mthread_mutex_t *__mutex)
-{
-    int retval = EINVAL;
-
-    if (__mutex->list == NULL) {
-        __mutex->list = safe_malloc(sizeof(mthread_list_t));
-        memset(__mutex->list, 0, sizeof(mthread_list_t));
-    }
-
-    mthread_spinlock_lock(&__mutex->lock);
-
-    if (__mutex->nb_thread == 0) {
-        __mutex->nb_thread = 1;
-        mthread_spinlock_unlock(&__mutex->lock);
-        retval = 0;
-        goto end;
-    }
-
-    mthread_spinlock_unlock(&__mutex->lock);
-    LOG_WARN("MTHREAD", "%s", "MUTEX busy");
-    retval = EBUSY;
-
-end:
-    return retval;
-}
-
-/* Wait until lock for MUTEX becomes available and lock it.  */
-int
-mthread_mutex_lock(mthread_mutex_t *__mutex)
-{
-    mthread_t self;
-    mthread_virtual_processor_t *vp;
-
-    if (__mutex->list == NULL) {
-        __mutex->list = safe_malloc(sizeof(mthread_list_t));
-        memset(__mutex->list, 0, sizeof(mthread_list_t));
-    }
-
-    mthread_spinlock_lock(&__mutex->lock);
-
-    if (__mutex->nb_thread == 0) {
-        __mutex->nb_thread = 1;
-        mthread_spinlock_unlock(&__mutex->lock);
-    } else {
-        self = mthread_self();
-        mthread_insert_last(self, __mutex->list);
-        self->status = BLOCKED;
-        vp = mthread_get_vp();
-        vp->p = &__mutex->lock;
-        mthread_yield();
-    }
-
-    return 0;
-}
-
-/* Unlock MUTEX.  */
-int
-mthread_mutex_unlock(mthread_mutex_t *__mutex)
-{
-    mthread_t first;
-    mthread_virtual_processor_t *vp;
-
-    if (__mutex->list == NULL) {
-        __mutex->list = safe_malloc(sizeof(mthread_list_t));
-        memset(__mutex->list, 0, sizeof(mthread_list_t));
-    }
-
-    mthread_spinlock_lock(&__mutex->lock);
-    if (__mutex->list->first != NULL) {
-        first = mthread_remove_first(__mutex->list);
-        vp = mthread_get_vp();
-        first->status = RUNNING;
-        mthread_insert_last(first, &(vp->ready_list));
-    } else
-        __mutex->nb_thread = 0;
-
-    mthread_spinlock_unlock(&__mutex->lock);
-    return 0;
-}
diff --git a/src/mthread/mthread_once.c b/src/mthread/mthread_once.c
deleted file mode 100644
index 9a269a39c13c61a7fac78fd713321ee9d8a17416..0000000000000000000000000000000000000000
--- a/src/mthread/mthread_once.c
+++ /dev/null
@@ -1,22 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-
-#include <mthread/mthread_internal.h>
-#include <errno.h>
-
-/* Functions for handling initialization.  */
-
-/* Guarantee that the initialization function INIT_ROUTINE will be called
-   only once, even if mthread_once is executed several times with the
-   same ONCE_CONTROL argument. ONCE_CONTROL must point to a static or
-   extern variable initialized to MTHREAD_ONCE_INIT.
-
-   The initialization functions might throw exception which is why
-   this function is not marked with .  */
-int
-mthread_once (mthread_once_t *__once_control, void (*__init_routine) (void))
-{
-    if (mthread_test_and_set(__once_control))
-        return EAGAIN;
-    __init_routine();
-    return 0;
-}
diff --git a/src/mthread/mthread_sem.c b/src/mthread/mthread_sem.c
deleted file mode 100644
index 6d5acbcfc7b2ea4ce26c15b13e2fc33b364e21c8..0000000000000000000000000000000000000000
--- a/src/mthread/mthread_sem.c
+++ /dev/null
@@ -1,74 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-
-#include <mthread/mthread_internal.h>
-
-/* Functions for handling semaphore.  */
-
-int
-mthread_sem_init(mthread_sem_t *sem, unsigned int value)
-{
-    sem->value = value;
-    mthread_mutex_init(&sem->mutex, NULL);
-    return 0;
-}
-
-/* P(sem), wait(sem) */
-int
-mthread_sem_wait(mthread_sem_t *sem)
-{
-    /* Here we loop while we can't enter the semaphore because there are already
-       the maximum number of clients. */
-loop:
-    mthread_mutex_lock(&sem->mutex);
-    if (sem->value == 0) {
-        mthread_mutex_unlock(&sem->mutex);
-        mthread_yield();
-        goto loop;
-    }
-
-    sem->value --;
-    mthread_mutex_unlock(&sem->mutex);
-    return 0;
-}
-
-/* V(sem), signal(sem) */
-int
-mthread_sem_post(mthread_sem_t *sem)
-{
-    mthread_mutex_lock(&sem->mutex);
-    sem->value ++;
-    mthread_mutex_unlock(&sem->mutex);
-    return 0;
-}
-
-int
-mthread_sem_getvalue(mthread_sem_t *sem, int *sval)
-{
-    *sval = sem->value;
-    return 0;
-}
-
-int
-mthread_sem_trywait(mthread_sem_t *sem)
-{
-    if (mthread_mutex_trylock(&sem->mutex))
-        return 1;
-
-    if (sem->value == 0) {
-        mthread_mutex_unlock(&sem->mutex);
-        return 1;
-    }
-
-    sem->value --;
-    mthread_mutex_unlock(&sem->mutex);
-    return 0;
-}
-
-/* undo sem_init() */
-int
-mthread_sem_destroy(mthread_sem_t *sem)
-{
-    mthread_mutex_destroy(&sem->mutex);
-    sem->value = 0;
-    return 0;
-}
diff --git a/src/mthread/mthread_tst.c b/src/mthread/mthread_tst.c
deleted file mode 100644
index 422eb485afe966b0e3aa996f797bdb03da6dcf9b..0000000000000000000000000000000000000000
--- a/src/mthread/mthread_tst.c
+++ /dev/null
@@ -1,75 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-
-#include <mthread/mthread_internal.h>
-#include <sched.h>
-
-#if defined(i686_ARCH) || defined(x86_64_ARCH)
-
-static inline int
-__mthread_test_and_set(mthread_tst_t *atomic)
-{
-    int ret;
-    __asm__ __volatile__("lock; xchgl %0, %1":"=r"(ret), "=m"(*atomic):"0"(1), "m"(*atomic):"memory");
-    return ret;
-}
-
-#elif defined(sparc_ARCH)
-static inline int
-__mthread_test_and_set(mthread_tst_t *spinlock)
-{
-    char ret = 0;
-    __asm__ __volatile__("ldstub [%0], %1": "=r"(spinlock), "=r"(ret): "0"(spinlock), "1" (ret) : "memory");
-    return (unsigned) ret;
-}
-
-#elif defined(ia64_ARCH)
-static __inline__ int
-__mthread_test_and_set(mthread_tst_t *atomic)
-{
-    int ret;
-    __asm__ __volatile__("xchg4 %0=%1, %2":"=r"(ret), "=m"(*atomic):"0"(1), "m"(*atomic):"memory");
-    return ret;
-}
-#else
-#define USE_GENERIC_ASM
-#include <pthread.h>
-static pthread_mutex_t tst_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static inline int
-__mthread_test_and_set(mthread_tst_t *atomic)
-{
-    int res;
-    pthread_mutex_lock(&tst_mutex);
-    res = *atomic;
-    if (*atomic == 0)
-        *atomic = 1;
-    pthread_mutex_unlock(&tst_mutex);
-    return res;
-}
-#endif
-
-int
-mthread_test_and_set(mthread_tst_t *atomic)
-{
-    return __mthread_test_and_set(atomic);
-}
-
-void
-mthread_spinlock_lock(mthread_tst_t *atomic)
-{
-#ifdef USE_GENERIC_ASM
-    static pthread_mutex_t spin_tst_mutex = PTHREAD_MUTEX_INITIALIZER;
-    pthread_mutex_lock(&spin_tst_mutex);
-#endif
-    while (mthread_test_and_set(atomic))
-        sched_yield();
-#ifdef USE_GENERIC_ASM
-    pthread_mutex_unlock(&spin_tst_mutex);
-#endif
-}
-
-void
-mthread_spinlock_unlock(mthread_tst_t *atomic)
-{
-    *atomic = 0;
-}
diff --git a/src/uri.c b/src/uri.c
index eaf64887a11c1a402e42baec6da808fee1191add..fd46447148178714dac4a0864d0adabcd8fd6c6a 100644
--- a/src/uri.c
+++ b/src/uri.c
@@ -29,7 +29,7 @@ __prefix(char *str, struct lkt_uri *ret)
     } else if (STR_NMATCH(str, "playlist", 8)) {
         ret->column_name = NULL;
         ret->type = uri_playlist;
-        val = str + 3;
+        val = str + 8;
     } else if (STR_NMATCH(str, "type", 4)) {
         ret->column_name = LKT_DB_TYPE;
         ret->type = uri_type;