diff --git a/inc/Makefile.am b/inc/Makefile.am
index d2d08268ba85cbef43c70a9ebaf34055a6a1453a..285fe6069208aa0fb53aa774670ec048dcd65670 100644
--- a/inc/Makefile.am
+++ b/inc/Makefile.am
@@ -1,5 +1,4 @@
 nobase_include_HEADERS  = lektor/cmd.h lektor/commands.h lektor/config.h lektor/database.h
 nobase_include_HEADERS += lektor/mkv.h lektor/net.h lektor/reg.h lektor/thread.h lektor/uri.h
-nobase_include_HEADERS += lektor/module/mpv.h
-nobase_include_HEADERS += mthread/mthread.h mthread/mthread_internal.h
-# nobase_include_HEADERS += common/bufferfd.h common/common.h common/macro.h common/queue.h common/stack.h
+nobase_include_HEADERS += lektor/bufferfd.h lektor/common.h lektor/macro.h lektor/queue.h
+nobase_include_HEADERS += lektor/stack.h
diff --git a/inc/lektor/.gitignore b/inc/lektor/.gitignore
deleted file mode 100644
index 4e590e782720fdc68c237406971b0d0c7afd437a..0000000000000000000000000000000000000000
--- a/inc/lektor/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-!*.inc
-!config.inc
diff --git a/inc/common/bufferfd.h b/inc/lektor/bufferfd.h
similarity index 91%
rename from inc/common/bufferfd.h
rename to inc/lektor/bufferfd.h
index 8e03dc79903a51e1391d250ff284290e1ecda014..3b0190324720b66788d41907fe374a64db61538d 100644
--- a/inc/common/bufferfd.h
+++ b/inc/lektor/bufferfd.h
@@ -20,10 +20,10 @@
  * Note: the user should not interfere with the members of `bufferfd` once
  * initialized.
  */
+#if ! defined(__LKT_BUFFERFD_H__)
+#define __LKT_BUFFERFD_H__
 
-#pragma once
-
-#include <common/common.h>
+#include <lektor/common.h>
 #include <stdint.h>
 #include <stdlib.h>
 
@@ -48,3 +48,5 @@ ssize_t bufferfd_skip(struct bufferfd *bf, const size_t n);
  * the file).
  * Internally calls `lseek(bf->fd, pos, SEEK_SET)`. */
 ssize_t bufferfd_seek(struct bufferfd *bf, size_t pos);
+
+#endif /* __LKT_BUFFERFD_H__ */
diff --git a/inc/lektor/cmd.h b/inc/lektor/cmd.h
index 23baa17b4ffdd9d1c51245399e99762871121cdb..406970c0aab81334942de212af6891426103f849 100644
--- a/inc/lektor/cmd.h
+++ b/inc/lektor/cmd.h
@@ -1,4 +1,5 @@
-#pragma once
+#if ! defined(__LKT_CMD_H__)
+#define __LKT_CMD_H__
 
 #include <stdnoreturn.h>
 #include <stddef.h>
@@ -27,3 +28,5 @@ noreturn void lkt_cmd_parse(struct lkt_cmd_opt *opts, int argc, const char **arg
 extern const char *executable_name;
 
 noreturn void print_help(void);
+
+#endif /* __LKT_CMD_H__ */
diff --git a/inc/lektor/commands.h b/inc/lektor/commands.h
index 9e3424a40660e2f87f57b19ea7b1c50b21d24ae9..64cc7793b5eec055cb9cbd2d03bbaf11e5761ea8 100644
--- a/inc/lektor/commands.h
+++ b/inc/lektor/commands.h
@@ -1,6 +1,7 @@
-#pragma once
+#if ! defined(__LKT_COMMANDS_H__)
+#define __LKT_COMMANDS_H__
 
-#include <common/common.h>
+#include <lektor/common.h>
 #include <lektor/net.h>
 #include <lektor/database.h>
 
@@ -90,3 +91,5 @@ bool command_sticker_create(struct lkt_state *srv, size_t c, char *argv[LKT_MESS
 bool command_sticker_get   (struct lkt_state *srv, size_t c, char *argv[LKT_MESSAGE_ARGS_MAX]);
 bool command_sticker_set   (struct lkt_state *srv, size_t c, char *argv[LKT_MESSAGE_ARGS_MAX]);
 bool command_sticker_delete(struct lkt_state *srv, size_t c, char *argv[LKT_MESSAGE_ARGS_MAX]);
+
+#endif /* __LKT_COMMANDS_H__ */
diff --git a/inc/common/common.h b/inc/lektor/common.h
similarity index 94%
rename from inc/common/common.h
rename to inc/lektor/common.h
index e07e7bf97544ed240ac2377cbdf92cf7ca203069..fd0cf4f2e77950ffc900e665a35cac38f1e94b99 100644
--- a/inc/common/common.h
+++ b/inc/lektor/common.h
@@ -1,6 +1,7 @@
-#pragma once
+#if ! defined(__LKT_COMMON_H__)
+#define __LKT_COMMON_H__
 
-#include <common/macro.h>
+#include <lektor/macro.h>
 #include <unistd.h>
 #include <stdint.h>
 
@@ -51,3 +52,5 @@ int read_self_exe(char *path, size_t len);
 int safe_snprintf(char *dest, const size_t max_len, const char *format, ...);
 
 long long_length(long integer);
+
+#endif /* __LKT_COMMON_H__ */
diff --git a/inc/lektor/config.h b/inc/lektor/config.h
index 5746e7b73103e19c4bede54429414962e1974d49..074fb50b3a1ce06d972ba11945e1a302d5b50399 100644
--- a/inc/lektor/config.h
+++ b/inc/lektor/config.h
@@ -1,6 +1,7 @@
-#pragma once
+#if ! defined(__LKT_CONFIG_H__)
+#define __LKT_CONFIG_H__
 
-#include <common/common.h>
+#include <lektor/common.h>
 #include <stddef.h>
 #include <sqlite3.h>
 #include <stdio.h>
@@ -39,3 +40,5 @@ void config_default(FILE *output);
 /* Manipulate Environment Variables */
 #define env_set(var, val)   setenv(var, val, 1)
 #define env_get             getenv
+
+#endif /* __LKT_CONFIG_H__ */
diff --git a/inc/lektor/database.h b/inc/lektor/database.h
index daae958341105a4897375ec7a9ba47e4cd8b809a..c6c291fbbcc62390947edc9a95dd2d0a9522a96c 100644
--- a/inc/lektor/database.h
+++ b/inc/lektor/database.h
@@ -1,6 +1,7 @@
-#pragma once
+#if ! defined(__LKT_DATABASE_H__)
+#define __LKT_DATABASE_H__
 
-#include <common/common.h>
+#include <lektor/common.h>
 #include <lektor/mkv.h>
 #include <lektor/uri.h>
 
@@ -172,3 +173,5 @@ bool database_sticker_create        (volatile sqlite3 *db, const char *name);
 bool database_sticker_delete        (volatile sqlite3 *db, const char *name);
 bool database_sticker_delete_specify(volatile sqlite3 *sb, const char *type, int uri, const char *name);
 bool database_sticker_set           (volatile sqlite3 *db, const char *type, const char *name, int uri, int value);
+
+#endif /* __LKT_DATABASE_H__ */
diff --git a/inc/common/macro.h b/inc/lektor/macro.h
similarity index 98%
rename from inc/common/macro.h
rename to inc/lektor/macro.h
index 5fa3a11342add3c059335e351af3c138e4e75578..7938570bde04f568c905fec68aeaa154aca12804 100644
--- a/inc/common/macro.h
+++ b/inc/lektor/macro.h
@@ -1,4 +1,5 @@
-#pragma once
+#if ! defined(__LKT_MACRO_H__)
+#define __LKT_MACRO_H__
 
 #include <stdint.h>
 #include <stdlib.h>
@@ -191,3 +192,5 @@ typedef volatile enum {
                     29,28,27,26,25,24,23,22,21,20, \
                     19,18,17,16,15,14,13,12,11,10, \
                     9,8,7,6,5,4,3,2,1,0
+
+#endif /* __LKT_MACRO_H__ */
diff --git a/inc/lektor/mkv.h b/inc/lektor/mkv.h
index c2d4efd074ca09032a1b235a8f59b1ab90d536a1..07e531899e960d7147d188c65ac5b4a79add8d2a 100644
--- a/inc/lektor/mkv.h
+++ b/inc/lektor/mkv.h
@@ -21,9 +21,10 @@
  *   | song_type    | GENRE        |   50            |
  *   +--------------+--------------+-----------------+
  */
-#pragma once
+#if ! defined(__LKT_MKV_H__)
+#define __LKT_MKV_H__
 
-#include <common/common.h>
+#include <lektor/common.h>
 #include <linux/limits.h>
 #include <stddef.h>
 
@@ -67,3 +68,5 @@ int metadata_set_file(char *karapath, const char *mkvpropedit);
 
 /* Set metadata for files under a given directory by their path. */
 int metadata_set_directory(const char *kara_dir, const char *mkvpropedit);
+
+#endif /* __LKT_MKV_H__ */
diff --git a/inc/lektor/module/mthread.h b/inc/lektor/module/mthread.h
deleted file mode 100644
index 6806967497f838685af43acaeb86b8f7fac5bfdd..0000000000000000000000000000000000000000
--- a/inc/lektor/module/mthread.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#pragma once
-
-/* Types */
-typedef volatile unsigned int mthread_tst_t;
-
-struct mthread_list_s;
-typedef struct mthread_list_s mthread_list_t;
-
-struct mthread_s;
-typedef struct mthread_s *mthread_t;
-
-typedef enum {
-    ATTR_NONE           = 0,
-    ATTR_DETACHED       = (1 << 1),
-    ATTR_DETACHED_FREE  = (1 << 2),
-} mthread_attr_t;
-
-struct mthread_mutex_s {
-    volatile int nb_thread;
-    mthread_tst_t lock;
-    mthread_list_t *list;   /* lock management already handled */
-};
-typedef struct mthread_mutex_s mthread_mutex_t;
-
-#define MTHREAD_MUTEX_INITIALIZER { .nb_thread = 0, .lock = 0, .list = NULL }
-
-struct mthread_mutexattr_s;
-typedef struct mthread_mutexattr_s mthread_mutexattr_t;
-
-struct mthread_cond_s {
-    mthread_tst_t lock;         /* Protects the structure.  */
-    mthread_list_t *list;       /* List of waiting threads. */
-};
-typedef struct mthread_cond_s mthread_cond_t;
-
-struct mthread_condattr_s;
-typedef struct mthread_condattr_s mthread_condattr_t;
-
-typedef mthread_tst_t mthread_once_t;
-
-struct mthread_sem_s {
-    volatile unsigned int value;    /* Number of wait that are done at the same time. */
-    mthread_mutex_t mutex;          /* Protect max_permit.                            */
-};
-typedef struct mthread_sem_s mthread_sem_t;
-
-/* Function for handling threads.  */
-
-extern int mthread_create(mthread_t *__threadp, const mthread_attr_t __attr, void *(*__start_routine) (void *), void *__arg);
-
-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);
-extern void mthread_yield ();
-
-/* Initialize mthread. */
-
-extern void mthread_init(void);
-extern void *mthread_main(void *arg);
diff --git a/inc/lektor/module/mthread_internal.h b/inc/lektor/module/mthread_internal.h
deleted file mode 100644
index 2705f1f4cf0b0a3fecbf776ea9e9416091268ac5..0000000000000000000000000000000000000000
--- a/inc/lektor/module/mthread_internal.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#pragma once
-
-#define TWO_LEVEL
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <ucontext.h>
-
-#include <lektor/module/mthread.h>
-#include <common/common.h>
-
-#define MTHREAD_DEFAULT_STACK           BRACKETS_THAT(128*1024) /* 128 kB */
-#define MTHREAD_MAX_VIRUTAL_PROCESSORS  256
-
-struct mthread_list_s {
-    volatile struct mthread_s *first;
-    volatile struct mthread_s *last;
-    mthread_tst_t lock;
-};
-
-typedef struct {
-    struct mthread_s *idle;
-    volatile struct mthread_s *current;
-    mthread_list_t ready_list;
-    int rank;
-    volatile int state;
-    volatile struct mthread_s *resched;
-    volatile mthread_tst_t *p;
-} mthread_virtual_processor_t;
-
-typedef enum { RUNNING, BLOCKED, ZOMBIE } mthread_status_t;
-typedef volatile enum { JOINABLE = 0, DETACHED = 1, DETACHED_FREE = 2 } mthread_detached_flag_t;
-
-struct mthread_s {
-    ucontext_t uc;
-    volatile void *res;
-    void *arg;
-    void *(*__start_routine) (void *);
-    volatile struct mthread_s *next;
-    volatile mthread_status_t status;
-    mthread_detached_flag_t detached;
-    int not_migrable;
-    mthread_virtual_processor_t *vp;
-    void *stack;
-};
-
-#define MTHREAD_LIST_INIT { .first = NULL, .last = NULL, .lock = 0 }
-
-int  mthread_test_and_set   (mthread_tst_t *atomic);
-void mthread_spinlock_lock  (mthread_tst_t *atomic);
-void mthread_spinlock_unlock(mthread_tst_t *atomic);
-int  mthread_get_vp_rank();
-
-void mthread_insert_first(struct mthread_s *item, mthread_list_t *list);
-void mthread_insert_last (struct mthread_s *item, mthread_list_t *list);
-int  mthread_list_test   (struct mthread_s *item, mthread_list_t *list);
-struct mthread_s *mthread_remove_first(mthread_list_t *list);
-
-void __mthread_yield(mthread_virtual_processor_t *vp);
-mthread_virtual_processor_t *mthread_get_vp();
diff --git a/inc/lektor/net.h b/inc/lektor/net.h
index c17fc4657f682d1b737b57826bd5949bb72e7e28..d5bc4d36c88e86ed4cbe92c2b4978c3ed516ad2c 100644
--- a/inc/lektor/net.h
+++ b/inc/lektor/net.h
@@ -1,7 +1,8 @@
-#pragma once
+#if ! defined(__LKT_NET_H__)
+#define __LKT_NET_H__
 
-#include <common/common.h>
-#include <common/queue.h>
+#include <lektor/common.h>
+#include <lektor/queue.h>
 #include <lektor/mkv.h>
 #include <lektor/config.h>
 #include <lektor/thread.h>
@@ -26,30 +27,6 @@ struct lkt_command {
     long cont;
 };
 
-/* Repository, e.g. Kurisu */
-struct lkt_repo {
-    /* Just the repo */
-    char *name;
-    char *base_url;
-    char *kara_dir;
-    char *get_all_json;
-    char *get_id_json;
-    char *get_id_file;
-    const uint64_t version;
-
-    /* The database */
-    volatile sqlite3 *db;
-    struct lkt_state *srv;
-};
-
-/* Load the repo as a module */
-int load_repo_https(va_list *);
-
-/* Download stuff */
-int repo_get_id          (struct lkt_repo *const repo, const uint64_t id, struct kara_metadata *mdt);
-int repo_update          (struct lkt_repo *const repo);
-int repo_download_id_sync(struct lkt_repo *const repo, const uint64_t id, const char *kara_path, struct kara_metadata *mdt);
-
 /* Create and destruct a command structure. */
 struct lkt_command lkt_command_parse(char *raw);
 struct lkt_command lkt_command_clone(struct lkt_command *c);
@@ -106,3 +83,5 @@ bool lkt_client_auth(struct lkt_state *srv, size_t c, bool set_auth);
 
 /* The server's listen function. */
 void lkt_listen(struct lkt_state *srv);
+
+#endif /* __LKT_NET_H__ */
diff --git a/inc/common/queue.h b/inc/lektor/queue.h
similarity index 94%
rename from inc/common/queue.h
rename to inc/lektor/queue.h
index 0779f98eaa4db683325b41fe3ed635ca5e59e81e..194110bd5e852a8445364528b3cbd5a7ffda05ad 100644
--- a/inc/common/queue.h
+++ b/inc/lektor/queue.h
@@ -1,7 +1,8 @@
-#pragma once
+#if ! defined(__LKT_QUEUE_H__)
+#define __LKT_QUEUE_H__
 
 #include <pthread.h>
-#include <common/common.h>
+#include <lektor/common.h>
 
 enum {
     _LKT_PLAY_STOP   = 0,
@@ -58,3 +59,5 @@ void lkt_queue_send(struct queue *, enum lkt_event_type, void *attr);
 lkt_event lkt_queue_handle(struct queue *);
 
 void lkt_queue_make_available(struct queue *, enum lkt_event_type);
+
+#endif /* __LKT_QUEUE_H__ */
diff --git a/inc/lektor/reg.h b/inc/lektor/reg.h
index ba8a6021bd4400bccfc1e833e11f7bdc7feace54..bc52f2571315a3dfd5c9157e6d836f9092fc902c 100644
--- a/inc/lektor/reg.h
+++ b/inc/lektor/reg.h
@@ -1,9 +1,9 @@
-#if ! defined(__REG_H__)
-#define __REG_H__
+#if ! defined(__LKT_REG_H__)
+#define ___LKT_REG_H__
 
 struct lkt_state;
 
-#include <common/macro.h>
+#include <lektor/macro.h>
 #include <stdarg.h>
 
 typedef int (*reg_func)(va_list *);
@@ -61,4 +61,4 @@ int reg_import(const char *mod, struct module_reg **ret, void **handle);
 /* Set the __reg__ pointer. */
 void reg_export(struct module_reg *reg);
 
-#endif /* __REG_H__ */
+#endif /* __LKT_REG_H__ */
diff --git a/inc/common/stack.h b/inc/lektor/stack.h
similarity index 83%
rename from inc/common/stack.h
rename to inc/lektor/stack.h
index 8eaf6c27d2a48ceb124d8162aad8114b5c4168e0..675620120207b1f520ac466106f36a0ebe780a8c 100644
--- a/inc/common/stack.h
+++ b/inc/lektor/stack.h
@@ -1,4 +1,6 @@
-#pragma once
+#if ! defined(__LKT_STACK_H__)
+#define __LKT_STACK_H__
+
 #include <stddef.h>
 
 /* NOTE: Will not exit on out-of-memory error. */
@@ -16,3 +18,5 @@ int  stack_empty(struct stack *lst);
 int stack_push(struct stack *lst, void *item);
 int stack_pop (struct stack *lst, void **item);
 int stack_head(struct stack *lst, void **item);
+
+#endif /* __LKT_STACK_H__ */
diff --git a/inc/lektor/thread.h b/inc/lektor/thread.h
index 56fe2cdf3b6951e20231c1cc37811cdbb73f5233..da681f162cf125a56e18c593bcd6c9f332de27bb 100644
--- a/inc/lektor/thread.h
+++ b/inc/lektor/thread.h
@@ -1,7 +1,8 @@
-#pragma once
+#if ! defined(__LKT_THREAD_H__)
+#define __LKT_THREAD_H__
 
-#include <common/common.h>
-#include <common/stack.h>
+#include <lektor/common.h>
+#include <lektor/stack.h>
 #include <pthread.h>
 #include <sys/types.h>
 
@@ -38,3 +39,5 @@ int poller_head_input  (struct poller_thread *th, void **ptr);
 int poller_append_output(struct poller_thread *th, void *ptr);
 int poller_pop_output   (struct poller_thread *th, void **ptr);
 int poller_head_output  (struct poller_thread *th, void **ptr);
+
+#endif /* __LKT_THREAD_H__ */
diff --git a/inc/lektor/uri.h b/inc/lektor/uri.h
index ca506f69d3813fcc050a0785dc71970b94515da8..70aa791d470dc567ecfc4ab4acfb4500e6e4be95 100644
--- a/inc/lektor/uri.h
+++ b/inc/lektor/uri.h
@@ -1,4 +1,5 @@
-#pragma once
+#if ! defined(__LKT_URI_H__)
+#define __LKT_URI_H__
 
 #include <stddef.h>
 #include <stddef.h>
@@ -34,3 +35,5 @@ void lkt_uri_free(struct lkt_uri *ret);
 /* Make an URL to download from kurisu.
    base_url is the prefix for the api, e.g. https://kurisu.iiens.net/api_kara.php */
 int lkt_uri_to_url(struct lkt_uri *uri, const char *base_url, char *ret, size_t len);
+
+#endif /* __LKT_URI_H__ */
diff --git a/meson.build b/meson.build
deleted file mode 100644
index 480f732ba20fc552b9673890c0d80b4a51991040..0000000000000000000000000000000000000000
--- a/meson.build
+++ /dev/null
@@ -1,157 +0,0 @@
-project( 'lektor'
-       , 'c'
-       , version: '0.1.0'
-       , license: 'ISC'
-       , default_options: [ 'c_std=c18'
-                          , 'warning_level=3'
-                          , 'werror=true'
-                          , 'strip=true'
-                          , 'debug=true'
-                          , 'buildtype=debug'
-                          ]
-       )
-
-libdl   = meson.get_compiler('c').find_library('dl')
-dep_x11 = dependency('x11',  required: false)
-dep_mpv = dependency('mpv',  required: false)
-dep_sdl = dependency('sdl2', required: false)
-
-## Get architecture
-archi = run_command('uname', '-p').stdout().strip()
-if archi == 'unknown'
-  archi = run_command('uname', '-m').stdout().strip()
-endif
-if archi == 'unknown'
-  archi = run_command('arch').stdout().strip()
-endif
-add_global_arguments('-D_REENTRANT', '-D' + archi + '_ARCH', '-D_' + build_machine.endian().to_upper() + '_ENDIAN', language: 'c')
-
-## Static modules ?
-if get_option('static_modules').enabled()
-  add_global_arguments('-D_STATIC_MODULES', language: 'c')
-  if get_option('module_sdl').enabled()
-    add_global_arguments('-D_STATIC_SDL2', language: 'c')
-  endif
-endif
-
-## Module list
-lektor_modules = []
-
-## Common files
-common_sources = [ 'src/common.c'
-                 , 'src/stack.c'
-                 , 'src/queue.c'
-                 , 'src/bufferfd.c'
-                 ]
-
-## Sources for the server
-core_sources =  [ 'src/mkv/write.c'
-                , 'src/mkv/utils.c'
-                , 'src/mkv/mkv.c'
-                , 'src/database/stickers.c'
-                , 'src/database/open.c'
-                , 'src/database/queue.c'
-                , 'src/database/update.c'
-                , 'src/database/find.c'
-                , 'src/database/config.c'
-                , 'src/database/playlist.c'
-                , 'src/database/user.c'
-                , 'src/net/command.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'
-                , 'src/cmd.c'
-                , 'src/reg.c'
-                ]
-
-## Man pages
-man_files  = [ [ 'lektord', '1' ]
-             , [ 'lektor',  '1' ]
-             , [ 'lkt',     '1' ]
-             ]
-
-# Global includes
-includes = include_directories('inc')
-
-# Server
-core_deps = [ dependency('sqlite3', version: '>= 3.31.0')
-            , dependency('libcurl', required: true)
-            , dependency('json-c',  required: true)
-            , dependency('threads', required: true)
-            , libdl
-            ]
-
-manpath = custom_target( 'manpath'
-                       , output: 'manpath.c'
-                       , input: 'meson.build'
-                       , command: [ find_program('sh'), '-c', 'echo \'const char *man_executable_path = "\'"$(which man)"\'";\' > @OUTPUT@' ] )
-
-common_deps = [ declare_dependency( link_with: [ static_library( 'common'
-                                  , files(common_sources), manpath
-                                  , include_directories: includes ) ] ) ]
-
-xxd = generator( find_program('xxd')
-               , output: '@BASENAME@.c'
-               , arguments: [ '-i', '@INPUT@', '@OUTPUT@' ] )
-
-lib = both_libraries( 'lektor'
-                    , files(core_sources)
-                    , xxd.process('src/database/disk.sql')
-                    , xxd.process('src/database/memory.sql')
-                    , manpath
-                    , include_directories: includes
-                    , dependencies: [ core_deps, common_deps ] )
-
-if get_option('static_liblektor')
-  bin_deps = [ declare_dependency( link_with: lib.get_static_lib(), include_directories: includes) ]
-else
-  bin_deps = [ declare_dependency( link_with: lib.get_shared_lib(), include_directories: includes) ]
-endif
-
-# SQL2 window module
-if get_option('module_sdl').enabled()
-  assert(dep_x11.found() and dep_mpv.found(), 'Asking to build x11 module, but missing dependencies')
-  lib_mod_sdl = both_libraries ( '_module_sdl2'
-                               , files(['src/module/module_sdl2.c', 'src/module/mpv.c'])
-                               , include_directories: includes
-                               , dependencies: [ dep_sdl, dep_mpv, bin_deps ]
-                               , install: get_option('static_modules').disabled()
-                               , install_dir: 'lib/lektor' )
-  if get_option('static_modules').enabled()
-    lektor_modules += [ lib_mod_sdl.get_static_lib() ]
-  endif
-endif
-
-srv = executable( meson.project_name() + 'd'
-                , files('src/main/server.c')
-                , include_directories: includes
-                , dependencies: [ declare_dependency( link_with: lektor_modules ), bin_deps ]
-                , install: true )
-
-# Client executable
-lkt = executable( 'lkt'
-                , files('src/main/lkt.c', 'src/cmd.c', 'src/common.c'), manpath
-                , include_directories: includes
-                , install: true )
-
-# Man pages
-man_sh     = find_program('scripts/man.sh')
-man_header = run_command('realpath', 'doc/header').stdout().strip()
-man_footer = run_command('realpath', 'doc/footer').stdout().strip()
-
-foreach man: man_files
-  man_name    = man.get(0)
-  man_section = man.get(1, '1')
-  custom_target( '@0@.@1@'.format(man_name, man_section)
-               , input: 'doc/@0@.@1@'.format(man_name, man_section)
-               , output: '@0@.@1@'.format(man_name, man_section)
-               , command: [ man_sh, '@INPUT@', '@OUTPUT@', man_header, man_footer ]
-               , depend_files: [ man_header, man_footer ]
-               , install: true
-               , install_dir: join_paths(get_option('mandir'), 'man@0@'.format(man_section)) )
-endforeach
diff --git a/meson_options.txt b/meson_options.txt
deleted file mode 100644
index 5ac48a6a141ddd789bd84ff77a2308f8a5c7a862..0000000000000000000000000000000000000000
--- a/meson_options.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-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/Makefile.am b/src/Makefile.am
index a264d237d9955b18bc609ba30d3c1a71d64d5635..d96bbc4eb1449129b6a5bee4c39584d80e00b442 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,9 +6,19 @@ AM_CPPFLAGS = -I$(abs_top_srcdir)/inc/ -I$(abs_top_builddir)/inc/
 
 lib_LTLIBRARIES = liblektor.la
 if LKT_STATIC_MODULE
-noinst_LTLIBRARIES = liblktmodsdl.la
+noinst_LTLIBRARIES = liblktmodsdl.la liblktmodrepo.la
 else
-lib_LTLIBRARIES += liblktmodsdl.la
+lib_LTLIBRARIES += liblktmodsdl.la liblktmodrepo.la
+endif
+
+## REPO module
+liblktmodrepo_la_SOURCES = module/module_repo.c module/worker.c
+liblktmodrepo_la_CFLAGS  = -fPIC
+liblktmodrepo_la_LDFLAGS = -avoid-version -pthread
+if LKT_STATIC_MODULE
+liblktmodrepo_la_LDFLAGS += -static
+else
+liblktmodrepo_la_LDFLAGS += -shared
 endif
 
 ## SDL2 module
@@ -24,8 +34,9 @@ endif
 
 ## Lib lektor
 # Base sources
-liblektor_la_SOURCES  = bufferfd.c cmd.c commands.c common.c config.c
-liblektor_la_SOURCES += queue.c reg.c stack.c thread.c uri.c
+liblektor_la_SOURCES  = base/bufferfd.c base/cmd.c base/common.c base/config.c
+liblektor_la_SOURCES += base/queue.c base/reg.c base/stack.c base/uri.c
+liblektor_la_SOURCES += base/thread.c base/commands.c
 
 # Database sources
 liblektor_la_SOURCES += database/disk.c database/memory.c
@@ -33,22 +44,18 @@ liblektor_la_SOURCES += database/open.c database/playlist.c database/queue.c
 liblektor_la_SOURCES += database/stickers.c database/update.c database/user.c
 liblektor_la_SOURCES += database/config.c database/find.c
 
-# Mkv interactions sources
+# MKV interactions sources
 liblektor_la_SOURCES += mkv/mkv.c mkv/utils.c mkv/write.c
 
 # Net sources
 liblektor_la_SOURCES += net/command.c net/listen.c net/message.c
 
-# False module
-liblektor_la_SOURCES += module/repo.c module/mthread.c
-
-# Lib conf
+# Liblektor configuration
 liblektor_la_CFLAGS   = -fPIC
 liblektor_la_LDFLAGS  = -avoid-version -shared -pthread -ljson-c -lsqlite3 -lcurl
-
 if LKT_STATIC_MODULE
 liblektor_la_LDFLAGS += -lSDL2 -lmpv
-liblektor_la_LIBADD   = liblktmodsdl.la
+liblektor_la_LIBADD   = liblktmodsdl.la liblktmodrepo.la
 endif
 
 # Generated with `xxd`
@@ -61,9 +68,6 @@ database/memory.c: database/memory.sql
 	$(XXD) -i < $< >> $@
 	echo ', 0x00 };' >> $@
 
-# Additional rules
-open.c: disk.c memory.c
-
 CLEANFILES = database/disk.c database/memory.c
 EXTRA_DIST = database/disk.sql database/memory.sql
 
diff --git a/src/bufferfd.c b/src/base/bufferfd.c
similarity index 97%
rename from src/bufferfd.c
rename to src/base/bufferfd.c
index 9904c65234b394f0861fa152f3544a1e4af17970..aa9c7a6ee93a524b03b4e318aca2ae726eab4c00 100644
--- a/src/bufferfd.c
+++ b/src/base/bufferfd.c
@@ -2,7 +2,7 @@
 
 #include <string.h>
 #include <unistd.h>
-#include <common/bufferfd.h>
+#include <lektor/bufferfd.h>
 
 static inline ssize_t
 __fill(struct bufferfd *bf)
diff --git a/src/cmd.c b/src/base/cmd.c
similarity index 98%
rename from src/cmd.c
rename to src/base/cmd.c
index e58cc15e42f4b7e2bc07a265c0460fb02a1a2033..99cabff73069cddb7e0cdb163139eb64ce0f53c9 100644
--- a/src/cmd.c
+++ b/src/base/cmd.c
@@ -2,7 +2,7 @@
 
 #include <lektor/lktconfig.h>
 #include <lektor/cmd.h>
-#include <common/common.h>
+#include <lektor/common.h>
 #include <sys/types.h>
 #include <stdlib.h>
 #include <strings.h>
diff --git a/src/commands.c b/src/base/commands.c
similarity index 99%
rename from src/commands.c
rename to src/base/commands.c
index 413386561ae09d5a38a08f2a2b45da81b10b0126..d99a246caed95da07597999b199101d5bbbd15b6 100644
--- a/src/commands.c
+++ b/src/base/commands.c
@@ -1,12 +1,11 @@
 #define _POSIX_C_SOURCE 200809L
 
-#include <common/common.h>
+#include <lektor/common.h>
 #include <lektor/commands.h>
 #include <lektor/database.h>
 #include <lektor/net.h>
 #include <lektor/uri.h>
 #include <lektor/cmd.h>
-#include <mthread/mthread.h>
 
 #include <errno.h>
 #include <linux/limits.h>
@@ -58,7 +57,7 @@ command_update(struct lkt_state *srv, size_t c, char *argv[LKT_MESSAGE_ARGS_MAX]
     RETURN_UNLESS(lkt_client_auth(srv, c, false), "Failed to authentificate user", false);
     srv->mpd_idle_events |= MPD_IDLE_UPDATE;
     srv->mpd_idle_events |= MPD_IDLE_DATABASE;
-    return ! repo_update(srv->repo_mod.data);
+    return ! MOD_CALL(srv.repo_mod, "update", 0);
 }
 
 static inline void *
diff --git a/src/common.c b/src/base/common.c
similarity index 99%
rename from src/common.c
rename to src/base/common.c
index b4d48b37707bcd1a20e200495cd56a14152a0bac..f46e6146dd38f78c79a14f5bdc8934257d0fc0c5 100644
--- a/src/common.c
+++ b/src/base/common.c
@@ -1,6 +1,6 @@
 #define _POSIX_C_SOURCE 200809L
 
-#include <common/common.h>
+#include <lektor/common.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/src/config.c b/src/base/config.c
similarity index 99%
rename from src/config.c
rename to src/base/config.c
index 647bb9e0e3b9b70771164a943c1a567a424bf66c..0627b348f5cf15a49239f13bfd85a79d2c1569bf 100644
--- a/src/config.c
+++ b/src/base/config.c
@@ -1,6 +1,6 @@
 #define _POSIX_C_SOURCE 200809L
 
-#include <common/common.h>
+#include <lektor/common.h>
 #include <lektor/config.h>
 #include <lektor/database.h>
 #include <lektor/net.h>
diff --git a/src/queue.c b/src/base/queue.c
similarity index 97%
rename from src/queue.c
rename to src/base/queue.c
index af034c55401f8657836668db37c4a8f1700ce6f5..ae9be02a664b89d4c48a7de579fc804ba453c60d 100644
--- a/src/queue.c
+++ b/src/base/queue.c
@@ -5,8 +5,8 @@
 #include <stddef.h>
 #include <string.h>
 #include <stdio.h>
-#include <common/common.h>
-#include <common/queue.h>
+#include <lektor/common.h>
+#include <lektor/queue.h>
 #include <pthread.h>
 
 int
diff --git a/src/reg.c b/src/base/reg.c
similarity index 98%
rename from src/reg.c
rename to src/base/reg.c
index 42192654931894ca348f3e5dfdeea8b8e8741517..5a92130142a629d67b315b9cb96468e633cc9ea7 100644
--- a/src/reg.c
+++ b/src/base/reg.c
@@ -1,6 +1,6 @@
 #define _POSIX_C_SOURCE 200809L
 
-#include <common/common.h>
+#include <lektor/common.h>
 #include <lektor/reg.h>
 #include <lektor/database.h>
 #include <lektor/config.h>
diff --git a/src/stack.c b/src/base/stack.c
similarity index 96%
rename from src/stack.c
rename to src/base/stack.c
index 683a54db2df68dbdc70e3a30b2bfd79a8310c1e1..8e13dccaaeaf44fed397d9ab5f571f5526c17c1b 100644
--- a/src/stack.c
+++ b/src/base/stack.c
@@ -1,6 +1,6 @@
 #define _POSIX_C_SOURCE 200809L
-#include <common/stack.h>
-#include <common/common.h>
+#include <lektor/stack.h>
+#include <lektor/common.h>
 #include <stdlib.h>
 #include <unistd.h>
 
diff --git a/src/thread.c b/src/base/thread.c
similarity index 99%
rename from src/thread.c
rename to src/base/thread.c
index b63f0fb49820fc59529ec1b9e5eef3ba105a27aa..72014fd0f6600f65f62f767c245af5fd2ada24a8 100644
--- a/src/thread.c
+++ b/src/base/thread.c
@@ -1,6 +1,6 @@
 #define _POSIX_C_SOURCE 200809L
 
-#include <common/common.h>
+#include <lektor/common.h>
 #include <lektor/thread.h>
 #include <pthread.h>
 #include <sys/types.h>
diff --git a/src/uri.c b/src/base/uri.c
similarity index 99%
rename from src/uri.c
rename to src/base/uri.c
index fd46447148178714dac4a0864d0adabcd8fd6c6a..a75f942017d0cb8490e5be1af4cc750d8af33ead 100644
--- a/src/uri.c
+++ b/src/base/uri.c
@@ -1,6 +1,6 @@
 #define _POSIX_C_SOURCE 200809L
 
-#include <common/common.h>
+#include <lektor/common.h>
 #include <lektor/uri.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/src/main/server.c b/src/main/server.c
index b6e35d6d9c4d7a4b61daaa877da8c06871fbbc1c..43184f496df740429fcba6ca790aeaec1ded3f6a 100644
--- a/src/main/server.c
+++ b/src/main/server.c
@@ -7,7 +7,6 @@
 #include <lektor/cmd.h>
 #include <lektor/reg.h>
 #include <lektor/database.h>
-#include <mthread/mthread.h>
 #include <lektor/commands.h>
 
 #include <assert.h>
@@ -29,8 +28,8 @@ main(int argc, char *argv[])
 {
     REG_BEGIN(server_reg)
     REG_ADD(load_repo_https)
-    REG_REGISTER("repo", repo_reg)
 #if defined (LKT_STATIC_MODULE)
+    REG_REGISTER("repo", repo_reg)
     REG_REGISTER("sdl2", sdl2_reg)
 #endif
     REG_END()
@@ -58,8 +57,6 @@ main(int argc, char *argv[])
     }
 
     reg_export(server_reg);
-    mthread_init();
-    pthread_create(&th, NULL, mthread_main, NULL);
     if (read_self_exe(exe, PATH_MAX))
         LOG_WARN("GENERAL", "%s", "Failed to read self executable path, "
                  "restart may not work");
@@ -111,18 +108,21 @@ main(int argc, char *argv[])
     database_config_queue_default(srv.db);
     if (!env_get(LKT_ENV_RESTART) && autoclear)
         database_queue_clear(srv.db);
-
     lkt_queue_make_available(&srv.queue, lkt_event_prop);
-    char *module = safe_malloc(sizeof(char) * PATH_MAX);
-    database_config_get_text(srv.db, "player", "module", module, PATH_MAX);
-    reg_import(module, &srv.window_mod.reg, &srv.window_mod.handle);
-    reg_import("repo", &srv.repo_mod.reg, &srv.repo_mod.handle);
-    free(module);
-
-    if (MOD_CALL(srv.repo_mod, "new", &srv, srv.repo_mod.handle))
-        return 100;
-    if (MOD_CALL(srv.window_mod, "new", &srv.queue, srv.db))
-        return 101;
+
+    {   /* Module initialization */
+        char *module = safe_malloc(sizeof(char) * PATH_MAX);
+        database_config_get_text(srv.db, "player", "module", module, PATH_MAX);
+        reg_import(module, &srv.window_mod.reg, &srv.window_mod.handle);
+        database_config_get_text(srv.db, "repo", "module", module, PATH_MAX);
+        reg_import(module, &srv.repo_mod.reg, &srv.repo_mod.handle);
+        free(module);
+
+        if (MOD_CALL(srv.repo_mod, "new", &srv.queue, srv.db))
+            return 100;
+        if (MOD_CALL(srv.window_mod, "new", &srv.queue, srv.db))
+            return 101;
+    }
 
     /* Get ENV */
     /* Not working -> race condition with player module */
diff --git a/src/module/module_repo.c b/src/module/module_repo.c
index 265e9afad2f19855b1ced4222479eeeb85ca96fc..1df562fccc72c51b6b838b3cc08ea22352ab2f89 100644
--- a/src/module/module_repo.c
+++ b/src/module/module_repo.c
@@ -46,7 +46,7 @@ struct module_repo_internal {
 
     /* Worker threads */
     worker_pool workers;
-    int updating;
+    volatile int updating;
 
     /* The database and the queue */
     struct queue *queue;
@@ -161,6 +161,14 @@ err:
     return ret;
 }
 
+static void *
+__worker_update(void *__repo)
+{
+    struct module_repo_internal *repo = __repo;
+    repo->updating = 1;
+    pthread_exit(NULL);
+}
+
 /***********************************************
  * Functions that will be wrapped and exported *
  ***********************************************/
@@ -281,10 +289,36 @@ mod_free(va_list *va)
     return 0;
 }
 
+static int
+mod_update(va_list *va)
+{
+    va_list copy;
+    struct module_repo_internal **repo;
+    va_copy(copy, *va);
+    repo = (struct module_repo_internal **) va_arg(copy, void **);
+
+    if ((*repo)->updating) {
+        LOG_WARN("REPO", "Already updating");
+        va_end(copy);
+        return 0;
+    }
+    (*repo)->updating = 1;
+    if (worker_pool_push(&(*repo)->workers), __worker_update, (void *) *repo)) {
+        LOG_ERROR("REPO", "Out of memory");
+        va_end(copy);
+        return 1;
+    }
+
+    va_end(copy);
+    LOG_INFO("REPO", "Update started");
+    return 0;
+}
+
 REG_BEGIN(repo_reg)
-REG_ADD_NAMED("new",   mod_new)
-REG_ADD_NAMED("free",  mod_free)
-REG_ADD_NAMED("close", mod_close)
+REG_ADD_NAMED("new",    mod_new)
+REG_ADD_NAMED("free",   mod_free)
+REG_ADD_NAMED("close",  mod_close)
+REG_ADD_NAMED("update", mod_update)
 REG_END()
 #if defined (LKT_STATIC_MODULE)
 REG_EXPORT(repo_reg)
diff --git a/src/module/module_sdl2.c b/src/module/module_sdl2.c
index 2b64182f57ce8be0d59fb2e821eb4b3a6cafca42..0dacc41e15a5434b395028e678ba24659d4e7efc 100644
--- a/src/module/module_sdl2.c
+++ b/src/module/module_sdl2.c
@@ -3,11 +3,12 @@
 #include <lektor/lktconfig.h>
 #include <common/common.h>
 #include <common/queue.h>
-#include <lektor/module/mpv.h>
 #include <lektor/thread.h>
 #include <lektor/reg.h>
 #include <lektor/net.h>
 
+#include "mpv.h"
+
 #include <sqlite3.h>
 #include <sched.h>
 #include <assert.h>
diff --git a/inc/lektor/module/mpv.h b/src/module/mpv.h
similarity index 100%
rename from inc/lektor/module/mpv.h
rename to src/module/mpv.h
diff --git a/src/module/mthread.c b/src/module/mthread.c
deleted file mode 100644
index 48506d509401d38c1f9f90b258e4838aaba44f72..0000000000000000000000000000000000000000
--- a/src/module/mthread.c
+++ /dev/null
@@ -1,437 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-
-#include <mthread/mthread_internal.h>
-#include <sched.h>
-#include <string.h>
-#include <unistd.h>
-
-#define MTHREAD_LWP 1
-
-#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;
-}
-
-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)
-{
-    mthread_list_t INIT = MTHREAD_LIST_INIT;
-    *list = INIT;
-}
-
-static inline void
-mthread_init_thread(struct mthread_s *thread)
-{
-    thread->detached = JOINABLE;
-    thread->next     = NULL;
-    thread->status   = RUNNING;
-    thread->res      = NULL;
-}
-
-void
-mthread_insert_first(struct mthread_s *item, mthread_list_t *list)
-{
-    mthread_spinlock_lock(&(list->lock));
-    if (list->first == NULL) {
-        item->next  = NULL;
-        list->first = item;
-        list->last  = item;
-    } else {
-        item ->next = list->first;
-        list->first = item;
-    }
-    mthread_spinlock_unlock(&(list->lock));
-}
-
-void
-mthread_insert_last(struct mthread_s *item, mthread_list_t *list)
-{
-    mthread_spinlock_lock(&(list->lock));
-    if (list->first == NULL) {
-        item->next  = NULL;
-        list->first = item;
-        list->last  = item;
-    } else {
-        item->next = NULL;
-        list->last->next = item;
-        list->last = item;
-    }
-    mthread_spinlock_unlock(&(list->lock));
-}
-
-struct mthread_s *
-mthread_remove_first(mthread_list_t *list)
-{
-    struct mthread_s *res = NULL;
-    mthread_spinlock_lock(&(list->lock));
-    if (list->first != NULL) {
-        res = (struct mthread_s *)list->first;
-        list->first = res->next;
-        if (list->first == NULL)
-            list->last = NULL;
-    }
-    mthread_spinlock_unlock(&(list->lock));
-    return res;
-}
-
-extern int
-mthread_list_test(struct mthread_s *item, mthread_list_t *list)
-{
-    struct mthread_s *it = (struct mthread_s *) list->last;
-    while (it && it != item)
-        it = (struct mthread_s *) it->next;
-    return it == item;
-}
-
-static inline int
-mthread_mctx_set(struct mthread_s *mctx, void (*func) (void *), char *stack, size_t size, void *arg)
-{
-    /* fetch current context */
-    RETURN_IF(getcontext(&(mctx->uc)) != 0, "Error in getcontext", 1);
-
-    /* remove parent link */
-    mctx->uc.uc_link = NULL;
-
-    /* configure new stack */
-    mctx->uc.uc_stack.ss_sp    = stack;
-    mctx->uc.uc_stack.ss_size  = size;
-    mctx->uc.uc_stack.ss_flags = 0;
-    mctx->stack                = stack;
-
-    /* configure startup function (with one argument) */
-    makecontext(&(mctx->uc), (void (*)(void)) func, 1 + 1, arg);
-    return 0;
-}
-
-static inline int
-mthread_mctx_swap(struct mthread_s *cur_mctx, struct mthread_s *new_mctx)
-{
-    swapcontext(&(cur_mctx->uc), &(new_mctx->uc));
-    return 0;
-}
-
-void
-__mthread_yield(mthread_virtual_processor_t *vp)
-{
-    struct mthread_s *current = (struct mthread_s *)vp->current;
-    struct mthread_s *next    = mthread_remove_first(&(vp->ready_list));
-
-    if (vp->resched != NULL) {
-        mthread_insert_last((struct mthread_s *)vp->resched, &(vp->ready_list));
-        vp->resched = NULL;
-    }
-
-    if (current != vp->idle) {
-        if ((current->status != BLOCKED) && (current->status != ZOMBIE)) {
-            if (current->status == RUNNING)
-                vp->resched = current;
-
-            else
-                not_implemented();
-        }
-
-        if (next == NULL)
-            next = vp->idle;
-    }
-
-    /* always true at this point - except for idle thread */
-    if (next != NULL) {
-        if (vp->current != next) {
-            vp->current = next;
-            mthread_mctx_swap(current, next);
-        }
-    }
-
-    vp = mthread_get_vp();
-
-    if (vp->p != NULL) {
-        mthread_spinlock_unlock(vp->p);
-        vp->p = NULL;
-    }
-}
-
-static void
-mthread_idle_task(void *arg)
-{
-    mthread_virtual_processor_t *vp = arg;
-    long j;
-    int done = 0;
-
-    vp->state = 1;
-    while (done == 0) {
-        done = 1;
-        sched_yield();
-        for (j = 0; j < MTHREAD_LWP; j++) {
-            if (virtual_processors[j].state == 0)
-                done = 0;
-        }
-    }
-    LOG_INFO("SCHEDULER", "Virtual processor %d started", vp->rank);
-    while (1)
-        __mthread_yield(vp);
-    not_implemented();
-}
-
-mthread_virtual_processor_t *
-mthread_get_vp()
-{
-    return &(virtual_processors[0]);
-}
-
-int
-mthread_get_vp_rank()
-{
-    return mthread_get_vp()->rank;
-}
-
-static inline void
-mthread_init_vp(mthread_virtual_processor_t *vp, struct mthread_s *idle, struct mthread_s *current, int rank)
-{
-    vp->current = current;
-    vp->idle    = idle;
-    mthread_list_init(&(vp->ready_list));
-    vp->rank    = rank;
-    vp->resched = NULL;
-    vp->p       = NULL;
-}
-
-void *
-mthread_main(void *arg)
-{
-    UNUSED(arg);
-    mthread_virtual_processor_t *vp = mthread_get_vp();
-    while (1) {
-        sched_yield();
-        sleep(1);
-        __mthread_yield(vp);
-    }
-    return NULL;
-}
-
-static inline void
-mthread_init_lib(long i)
-{
-    struct mthread_s *current = NULL;
-    char *stack               = (char *) safe_malloc(MTHREAD_DEFAULT_STACK);
-    struct mthread_s *mctx    = (struct mthread_s *) safe_malloc(sizeof(struct mthread_s));
-    mthread_init_thread(mctx);
-    mthread_list_init(&(joined_list));
-
-    if (i == 0) {
-        current = (struct mthread_s *)safe_malloc(sizeof(struct mthread_s));
-        mthread_init_thread(current);
-        current->__start_routine = mthread_main;
-        current->stack = NULL;
-    }
-
-    mthread_init_vp(&(virtual_processors[i]), mctx, mctx, i);
-    mthread_mctx_set(mctx, mthread_idle_task, stack, MTHREAD_DEFAULT_STACK, &(virtual_processors[i]));
-    if (i != 0) {
-        virtual_processors[i].current = mctx;
-        setcontext(&(mctx->uc));
-    } else
-        virtual_processors[i].current = current;
-}
-
-static void
-mthread_start_thread(void *arg)
-{
-    struct mthread_s *mctx = (struct mthread_s *)arg;
-    LOG_INFO("THREAD", "Thread %p started", arg);
-    mthread_virtual_processor_t *vp = mthread_get_vp();
-    __mthread_yield(vp);
-    mctx->res    = mctx->__start_routine(mctx->arg);
-    mctx->status = ZOMBIE;
-    LOG_INFO("THREAD", "Thread %p ended (%d)", arg, vp->rank);
-    if (mctx->detached) {
-        LOG_INFO("THREAD", "Thread %p (vp: %d) was detached, join it", arg, vp->rank);
-        mthread_join(mctx, NULL);
-    }
-    vp = mthread_get_vp();
-    __mthread_yield(vp);
-}
-
-/* Function for handling threads.  */
-
-static inline void
-__mthread_lib_init(long i)
-{
-    mthread_init_lib(i);
-    virtual_processors[0].state = 1;
-    LOG_INFO("THREAD", "%s", "library started");
-}
-
-void
-mthread_init(void)
-{
-    if (is_mthread_init == 0) {
-        __mthread_lib_init(0);
-        is_mthread_init = 1;
-    }
-}
-
-/* Create a thread with given attributes ATTR (or default attributes
-   if ATTR is NULL), and call function START_ROUTINE with given
-   arguments ARG.  */
-int
-mthread_create(mthread_t *__threadp, const mthread_attr_t __attr, void *(*__start_routine) (void *), void *__arg)
-{
-    if (is_mthread_init == 0) {
-        __mthread_lib_init(0);
-        is_mthread_init = 1;
-    }
-
-    mthread_virtual_processor_t *vp = mthread_get_vp();
-
-    struct mthread_s *mctx = mthread_remove_first(&(joined_list));
-    if (mctx == NULL) {
-        mctx = safe_malloc(sizeof(struct mthread_s));
-        memset(mctx, 0, sizeof(struct mthread_s));
-    }
-    char *stack = mctx->stack ? mctx->stack : safe_malloc(MTHREAD_DEFAULT_STACK);
-
-    mthread_init_thread(mctx);
-
-    if (__attr) {
-        if (__attr & ATTR_DETACHED)
-            mctx->detached = DETACHED;
-        if (__attr & ATTR_DETACHED_FREE)
-            mctx->detached = DETACHED_FREE;
-    }
-
-    LOG_INFO("THREAD INIT", "Create thread %p", (void *) mctx);
-    mctx->arg = __arg;
-    mctx->__start_routine = __start_routine;
-    mthread_mctx_set(mctx, mthread_start_thread, stack, MTHREAD_DEFAULT_STACK, mctx);
-    mthread_insert_last(mctx, &(vp->ready_list));
-
-    if (__threadp)
-        *__threadp = mctx;
-
-    return 0;
-}
-
-/* Obtain the identifier of the current thread.  */
-mthread_t
-mthread_self(void)
-{
-    return (mthread_t) mthread_get_vp()->current;
-}
-
-/* Compare two thread identifiers.  */
-int
-mthread_equal(mthread_t __thread1, mthread_t __thread2)
-{
-    return (__thread1 == __thread2);
-}
-
-/* Terminate calling thread.  */
-void
-mthread_exit(void *__retval)
-{
-    mthread_virtual_processor_t *vp = mthread_get_vp();
-    struct mthread_s *mctx          = (struct mthread_s *) vp->current;
-    mctx->res    = __retval;
-    mctx->status = ZOMBIE;
-    LOG_INFO("THREAD END", "Thread %p exited", (void *) mctx);
-    __mthread_yield(vp);
-}
-
-/* Make calling thread wait for termination of the thread TH.  The
-   exit status of the thread is stored in *THREAD_RETURN, if THREAD_RETURN
-   is not NULL.  */
-int
-mthread_join(mthread_t __th, void **__thread_return)
-{
-    LOG_INFO("THREAD END", "Join thread %p", (void *) __th);
-
-    while (__th->status != ZOMBIE)
-        mthread_yield();
-
-    if (__thread_return != NULL)
-        *__thread_return = (void *)__th->res;
-
-    LOG_INFO("THREAD END", "Thread %p joined", (void *) __th);
-    mthread_insert_last(__th, &(joined_list));
-    return 0;
-}
-
-void
-mthread_yield()
-{
-    mthread_virtual_processor_t *vp = mthread_get_vp();
-    LOG_INFO("THREAD YIELD", "Thread %p yield", (void *) vp->current);
-    __mthread_yield(vp);
-}
diff --git a/src/module/worker.c b/src/module/worker.c
index 995a24b2ae3cca28008e36610892cb7459748d05..35d55aa9f82411b662a3e711a62a411be92f1b6e 100644
--- a/src/module/worker.c
+++ b/src/module/worker.c
@@ -137,3 +137,9 @@ worker_pool_waitall(struct worker_pool *pool)
     while (pool->len)
         sched_yield();
 }
+
+size_t
+worker_pool_get_working_count(struct worker_pool *pool)
+{
+    return pool->thread_working;
+}
diff --git a/src/module/worker.h b/src/module/worker.h
index cc6417f1fb45c0bc1ef9a9e3b166e98d5a6f8879..013f033c26ca7feb1374a0f315aa384fd7517d5f 100644
--- a/src/module/worker.h
+++ b/src/module/worker.h
@@ -24,3 +24,5 @@ void worker_pool_waitall(struct worker_pool *);
 
 /* It is up to the user to free or not the `arg` depending on what he whats */
 int worker_pool_push(struct worker_pool *, worker_function, void *arg);
+
+size_t worker_pool_get_working_count(struct worker_pool *);