diff --git a/inc/common/macro.h b/inc/common/macro.h
index 1ba00aa134172feef27e329bad2c29a9d6d0e674..da56e358042a2cbb3ce8579e1ac7fffdf0ef58d9 100644
--- a/inc/common/macro.h
+++ b/inc/common/macro.h
@@ -75,6 +75,9 @@
 #define SELF_EXECUTABLE_FREEBSD         "/proc/curproc/file"
 #define SELF_EXECUTABLE_SOLARIS         "/proc/self/path/a.out"
 
+#define LKT_ENV_RESTART                 "__LKT_RESTART"
+#define LKT_ENV_CURRENT                 "__LKT_CURRENT"
+
 #define LKT_MAX_SQLITE_STATEMENT        1024
 #define PROTECTED_DATABASE              "disk"
 
diff --git a/inc/common/queue.h b/inc/common/queue.h
new file mode 100644
index 0000000000000000000000000000000000000000..fc3809ae205af4aa4dc43fa1eaf6491f13bbde95
--- /dev/null
+++ b/inc/common/queue.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <pthread.h>
+#include <common/common.h>
+
+enum lkt_event_type {
+    lkt_event_null      = 0,            /* NULL         */
+    lkt_event_play_pos  = (1 << 1),     /* size_t       */
+    lkt_event_play_file = (1 << 2),     /* const char*  */
+} type;
+
+#define lkt_event_play (lkt_event_play_pos | lkt_event_play_file)
+
+typedef struct {
+    unsigned int type;
+    void *attr;
+} lkt_event;
+
+struct queue {
+    pthread_mutex_t lock;
+
+    volatile lkt_event *contents;
+    volatile size_t size;
+    volatile size_t last;
+
+    volatile int available;
+};
+
+int lkt_queue_new(struct queue *);
+void lkt_queue_free(struct queue *);
+
+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);
diff --git a/inc/lektor/config.inc b/inc/lektor/config.def
similarity index 100%
rename from inc/lektor/config.inc
rename to inc/lektor/config.def
diff --git a/inc/lektor/config.h b/inc/lektor/config.h
index 22c200b1ef6d88e7d6794ce6c179b2c5eb722746..5746e7b73103e19c4bede54429414962e1974d49 100644
--- a/inc/lektor/config.h
+++ b/inc/lektor/config.h
@@ -12,7 +12,7 @@ struct lkt_state;
 #define value(key, val)     key " = " val "\n"
 #define value_opt(key, val) value(key, val)
 static const char *const lkt_default_config_file =
-#include <lektor/config.inc>
+#include <lektor/config.def>
     ;
 #undef value
 #undef value_opt
@@ -35,3 +35,7 @@ int config_new(volatile sqlite3 *db, const char *conf);
 
 /* Prints the default config file. */
 void config_default(FILE *output);
+
+/* Manipulate Environment Variables */
+#define env_set(var, val)   setenv(var, val, 1)
+#define env_get             getenv
diff --git a/inc/lektor/module/module_sdl2.h b/inc/lektor/module/module_sdl2.h
index cdd608ebecf25ed502611897671e74eedef08bd8..30dea5744268769565c646d7a85343082ca9c18e 100644
--- a/inc/lektor/module/module_sdl2.h
+++ b/inc/lektor/module/module_sdl2.h
@@ -17,7 +17,6 @@ int load_sdl2(void *mod, struct lkt_state *srv, void *handle);
 bool module_sdl2_new(struct lkt_win *const win);
 void module_sdl2_close(struct lkt_win *const win);
 void module_sdl2_free(struct lkt_win *const win);
-void module_sdl2_attach(struct lkt_win *const win, void *server);
 
 bool module_sdl2_toggle_pause(struct lkt_win *const win);
 bool module_sdl2_load_file(struct lkt_win *const win, const char *filepath);
diff --git a/inc/lektor/net.h b/inc/lektor/net.h
index e7d244bb356414064b60588d5479ff8a87fd0998..e9985dfc49d267bc0ff314e1f099954e08da16d8 100644
--- a/inc/lektor/net.h
+++ b/inc/lektor/net.h
@@ -1,6 +1,7 @@
 #pragma once
 
 #include <common/common.h>
+#include <common/queue.h>
 #include <lektor/mkv.h>
 #include <lektor/config.h>
 #include <lektor/window.h>
@@ -73,6 +74,7 @@ struct lkt_state {
     size_t fds_max;
     char host[HOST_NAME_MAX];
     char port[INI_MAX_LINE_LEN];
+    struct queue queue;
 
     volatile sqlite3 *db;
     const char *kara_prefix;
@@ -84,6 +86,8 @@ struct lkt_state {
     struct lkt_win win;
 };
 
+void lkt_set_event_available(struct lkt_state *srv, enum lkt_event_type type);
+
 /* Send a message to the connected client. */
 void lkt_state_send(struct lkt_state *srv, size_t c, struct lkt_message *msg);
 
diff --git a/inc/lektor/reg.h b/inc/lektor/reg.h
index d156b68b67261a28e7fe0361bada4720f1668f26..50049e703f5da7e27fd324c65586af08b08a0ff3 100644
--- a/inc/lektor/reg.h
+++ b/inc/lektor/reg.h
@@ -6,14 +6,15 @@ struct lkt_state;
    with a name that can be generated or red from a config file. */
 struct module_reg {
     const char *name;
-    int (*func)(void *, struct lkt_state *, void *);
+    void (*func)(void);
 };
 
 extern struct module_reg *reg;
 
-#define REG_BEGIN(reg)  struct module_reg reg[] = {
-#define REG_ADD(__func) { .name = #__func,  .func = __func  },
-#define REG_END()       { .name = NULL,     .func = NULL    } };
+#define REG_BEGIN(reg)          struct module_reg reg[] = {
+#define REG_ADD(__f)            { .name = #__f,  .func = (void(*)(void)) __f    },
+#define REG_ADD_NAMED(__n, __f) { .name = __n,   .func = (void(*)(void)) __f    },
+#define REG_END()               { .name = NULL,  .func = NULL                   } };
 
 /* If handle is NULL, file is unused and the reg is red. Otherwise,
    we use dlfcn to search for the symbol which is returned. If *handle
diff --git a/meson.build b/meson.build
index d3a1af2027754a1fab4de39f63da1c8dec346157..9d2322971f33735e289aff57c7ddd71b860f017b 100644
--- a/meson.build
+++ b/meson.build
@@ -13,6 +13,7 @@ project( 'lektor'
        )
 
 libdl   = meson.get_compiler('c').find_library('dl')
+librt   = meson.get_compiler('c').find_library('rt')
 dep_x11 = dependency('x11',  required: false)
 dep_mpv = dependency('mpv',  required: false)
 dep_sdl = dependency('sdl2', required: false)
@@ -54,6 +55,7 @@ mthread_sources = [ 'src/mthread/mthread.c'
 ## Common files
 common_sources = [ 'src/common.c'
                  , 'src/stack.c'
+                 , 'src/queue.c'
                  , 'src/bufferfd.c'
                  ]
 
@@ -95,6 +97,8 @@ core_deps = [ dependency('sqlite3', version: '>= 3.31.0')
             , dependency('libcurl', required: true)
             , dependency('json-c',  required: true)
             , dependency('threads', required: true)
+            , librt
+            , libdl
             ]
 
 manpath = custom_target( 'manpath'
@@ -116,7 +120,7 @@ lib = both_libraries( 'lektor'
                     , xxd.process('src/database/memory.sql')
                     , manpath
                     , include_directories: includes
-                    , dependencies: [ core_deps, libdl, common_deps ] )
+                    , dependencies: [ core_deps, common_deps ] )
 
 if get_option('static_liblektor')
   bin_deps = [ declare_dependency( link_with: lib.get_static_lib(), include_directories: includes) ]
diff --git a/src/commands.c b/src/commands.c
index 9ad34084ef1317c2dadf1b3ef0b0e2488e2a49b6..d2db41c8adccebea328565ec7007798edc2e0c18 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -23,12 +23,28 @@ inline bool
 command_restart(struct lkt_state *srv, size_t c)
 {
     const char *const argv[] = { executable_name, NULL };
+    struct lkt_queue_state sta = {0};
     RETURN_UNLESS(lkt_client_auth(srv, c, false), "Failed to authentificate user", false);
     if (!executable_name) {
         LOG_ERROR_SCT("GENERAL", "%s", "Can't restart if the executable path was not found at start-up");
         return false;
     }
     close(srv->fds[0].fd);
+    database_queue_state(srv->db, &sta);
+    lkt_queue_free(&srv->queue);
+    env_set(LKT_ENV_RESTART, "1");
+    int len = long_length(LONG_MAX);
+    if (len > 0) {
+        char *pos = calloc(len, sizeof(char));
+        if (pos) {
+            safe_snprintf(pos, len, "%d", sta.current);
+            env_set(LKT_ENV_CURRENT, pos);
+            free(pos);
+        } else
+            LOG_WARN_SCT("GENERAL", "Failed to malloc, don't set %s to %d",
+                         LKT_ENV_CURRENT, sta.current);
+    } else
+        env_set(LKT_ENV_CURRENT, "NULL");
     database_close_all();
     execv(executable_name, (char *const *) argv);
     LOG_ERROR_SCT("GENERAL", "%s", "Failed to exec lektor or OS not supported");
@@ -74,6 +90,7 @@ command_kill(struct lkt_state *srv, size_t c)
     RETURN_UNLESS(lkt_client_auth(srv, c, false), "Failed to authentificate user", false);
     LOG_INFO_SCT("GENERAL", "%s", "Stopping lektord");
     close(srv->fds[0].fd);
+    lkt_queue_free(&srv->queue);
     database_close_all();
     exit(EXIT_SUCCESS);
 }
diff --git a/src/database/config.c b/src/database/config.c
index 3c53210f002ebe7e7df6482d3965777adc944654..098377b2abd0cf7b80b51fb37b1211d9417cddf9 100644
--- a/src/database/config.c
+++ b/src/database/config.c
@@ -171,7 +171,7 @@ database_validate_conf(volatile sqlite3 *db)
                       section);                                               \
         return false;                                                         \
     }
-#include <lektor/config.inc>
+#include <lektor/config.def>
 #undef section
 #undef value
 #undef value_opt
diff --git a/src/database/open.c b/src/database/open.c
index 6cc01a60cfb485142881b78f45942a949334db73..9e06bc940daee6fb6a13f0142f02b2edefe5d02d 100644
--- a/src/database/open.c
+++ b/src/database/open.c
@@ -55,7 +55,7 @@ database_close_all(void)
 }
 
 static inline void
-__inc(volatile sqlite3 *db, const char *name)
+__inc(volatile sqlite3 *db, const char *name, bool check)
 {
     SQLITE_EXEC(db, "UPDATE misc SET opened = (SELECT opened + 1 FROM misc);",
                 error);
@@ -63,23 +63,22 @@ __inc(volatile sqlite3 *db, const char *name)
     if (!atexited) {
         atexited = 1;
         if (stack_new(&db_stack))
-            goto out_of_memory;
+            exit(EXIT_FAILURE);
     }
 
     struct named_db *item = malloc(sizeof(struct named_db));
     if (!item)
-        goto out_of_memory;
+        exit(EXIT_FAILURE);
     item->name = strdup(name);
     item->db   = db;
     if (stack_push(&db_stack, item))
-        goto out_of_memory;
+        exit(EXIT_FAILURE);
     return;
 error:
     LOG_ERROR_SCT("DB", "%s", "Database already in use");
-    exit(EXIT_FAILURE);
-out_of_memory:
-    LOG_ERROR_SCT("DB", "%s", "Out of memory");
-    exit(EXIT_FAILURE);
+    if (check)
+        exit(EXIT_FAILURE);
+    __dec(db, name);
 }
 
 int
@@ -192,8 +191,7 @@ retry:
         goto init;
     if (!__check_schema(db))
         goto init;
-    if (check)
-        __inc(db, PROTECTED_DATABASE);
+    __inc(db, PROTECTED_DATABASE, check);
     return true;
 
     /* Need init */
diff --git a/src/main/server.c b/src/main/server.c
index e13c0d1cc537faf8610c70f5c54c43c477f98fdb..29ff8e20e029f50753716296f4585e2fe13fa5c6 100644
--- a/src/main/server.c
+++ b/src/main/server.c
@@ -7,6 +7,7 @@
 #include <lektor/reg.h>
 #include <lektor/database.h>
 #include <mthread/mthread.h>
+#include <lektor/commands.h>
 
 #include <assert.h>
 #include <signal.h>
@@ -67,6 +68,8 @@ main(int argc, char *argv[])
 normal_launch:
     LOG_INFO_SCT("GENERAL", "Lektor launched by user %s (shell: %s, home: %s)",
                  pw->pw_name, pw->pw_shell, pw->pw_dir);
+    if (env_get(LKT_ENV_RESTART))
+        LOG_INFO_SCT("GENERAL", "%s", "Lektord has been restarted");
     reg_set(server_reg);
     mthread_init();
     pthread_create(&th, NULL, mthread_main, NULL);
@@ -76,10 +79,15 @@ normal_launch:
     executable_name = exe;
 
     /* Init the server */
-    struct lkt_state srv;
     char *db_path   = safe_malloc(PATH_MAX * sizeof(char));
     char *kara_dir  = safe_malloc(PATH_MAX * sizeof(char));
-    memset(&srv, 0, sizeof(struct lkt_state));
+    struct lkt_state srv = {
+        .kara_prefix = kara_dir,
+    };
+    if (lkt_queue_new(&srv.queue)) {
+        LOG_ERROR_SCT("INIT", "%s", "Faield to create server queue");
+        exit(EXIT_FAILURE);
+    }
 
     /* Initialize the system. */
     if (!database_new(&srv.db)) {
@@ -114,11 +122,20 @@ normal_launch:
     srv.kara_prefix = kara_dir;
 
     database_config_queue_default(srv.db);
-    if (autoclear)
+    if (!env_get(LKT_ENV_RESTART) && autoclear)
         database_queue_clear(srv.db);
 
     RETURN_IF(load_module_by_name(&srv, "player", &srv.win),  "Can't load module player", 3);
     RETURN_IF(load_module_by_name(&srv, "repo",   &srv.repo), "Can't load module repo", 3);
+
+    /* Get ENV */
+    /* Not working -> race condition with player module */
+    char *env_current = env_get(LKT_ENV_CURRENT);
+    if (env_current && env_current[0] && !STR_MATCH(env_current, "NULL")) {
+        LOG_INFO_SCT("INIT", "Restart playback from %s", env_current);
+        lkt_queue_send(&srv.queue, lkt_event_play_pos, (void *) (size_t) strtol(env_current, NULL, 0));
+    }
+
     lkt_listen(&srv);
     return EXIT_FAILURE;
 }
diff --git a/src/module/module_sdl2.c b/src/module/module_sdl2.c
index e2f75ec4dad88d46a1334a7c2ae185d37f1829ff..120ce9680049c67fbfb8cbe5eb9ca60c16131cd0 100644
--- a/src/module/module_sdl2.c
+++ b/src/module/module_sdl2.c
@@ -6,6 +6,7 @@
 #include <lektor/module/mpv.h>
 #include <mthread/mthread.h>
 #include <lektor/thread.h>
+#include <lektor/reg.h>
 
 #include <sched.h>
 #include <assert.h>
@@ -165,8 +166,10 @@ loop:
         break;
 
     case SDL_WINDOWEVENT:
-        if (event.window.event == SDL_WINDOWEVENT_EXPOSED)
+        if (event.window.event == SDL_WINDOWEVENT_EXPOSED) {
+            lkt_set_event_available(win->srv, lkt_event_play);
             redraw = 1;
+        }
         break;
 
     case SDL_KEYUP:
@@ -405,3 +408,15 @@ module_sdl2_handle_events(struct lkt_win *const win, volatile sqlite3 *db,
     UNUSED(win, db, mpd_idle_events);
     return true;
 }
+
+REG_BEGIN(sdl2_reg)
+REG_ADD_NAMED("new",    module_sdl2_new)
+REG_ADD_NAMED("free",   module_sdl2_free)
+REG_ADD_NAMED("handle", module_sdl2_handle_events)
+REG_ADD(module_sdl2_close)
+REG_ADD(module_sdl2_toggle_pause)
+REG_ADD(module_sdl2_load_file)
+REG_ADD(module_sdl2_set_volume)
+REG_ADD(module_sdl2_get_duration)
+REG_ADD(module_sdl2_get_elapsed)
+REG_END()
diff --git a/src/module/module_x11.c b/src/module/module_x11.c
index d9231806ea682d52f5f3d3984b9c9b2b5990618a..9c10b1f480e556035f16fbd84ee1662eb5bd2390 100644
--- a/src/module/module_x11.c
+++ b/src/module/module_x11.c
@@ -5,6 +5,7 @@
 #include <lektor/module/mpv.h>
 #include <lektor/database.h>
 #include <lektor/commands.h>
+#include <lektor/reg.h>
 
 #include <string.h>
 #include <unistd.h>
@@ -276,3 +277,15 @@ module_x11_handle_events(struct lkt_win *const win, volatile sqlite3 *db,
            ! lmpv_handle(win, xwin->mpv, db, mpd_idle_events,
                          &xwin->mpv_time_pos, &xwin->mpv_duration);
 }
+
+REG_BEGIN(x11_reg)
+REG_ADD_NAMED("new",    module_x11_new)
+REG_ADD_NAMED("free",   module_x11_free)
+REG_ADD_NAMED("handle", module_x11_handle_events)
+REG_ADD(module_x11_close)
+REG_ADD(module_x11_toggle_pause)
+REG_ADD(module_x11_load_file)
+REG_ADD(module_x11_set_volume)
+REG_ADD(module_x11_get_duration)
+REG_ADD(module_x11_get_elapsed)
+REG_END()
diff --git a/src/net/listen.c b/src/net/listen.c
index 37d1cbe38b34d83dbcaca97953d4277f0b17ad47..332edcb229a82606b6354ad2e181ab00fc7037f2 100644
--- a/src/net/listen.c
+++ b/src/net/listen.c
@@ -1,6 +1,7 @@
 #define _POSIX_C_SOURCE 200809L
 
 #include <common/common.h>
+#include <common/queue.h>
 #include <lektor/commands.h>
 #include <lektor/database.h>
 #include <lektor/net.h>
@@ -49,6 +50,12 @@ struct lkt_client {
     int continuation;
 };
 
+void
+lkt_set_event_available(struct lkt_state *srv, enum lkt_event_type type)
+{
+    lkt_queue_make_available(&srv->queue, type);
+}
+
 static inline bool
 lkt_close_client(struct lkt_state *srv, size_t c)
 {
@@ -713,6 +720,30 @@ lkt_client_auth(struct lkt_state *srv, size_t c, bool set)
     return srv->clients[c - 1].authentificated |= set;
 }
 
+static inline void
+handle_queue_events(struct lkt_state *srv)
+{
+    lkt_event evt;
+    char *string = calloc(BUFFER_MAX, sizeof(char));
+    if (!string)
+        return;
+redo:
+    evt = lkt_queue_handle(&srv->queue);
+
+    switch (evt.type) {
+    case lkt_event_play_pos:
+        safe_snprintf(string, BUFFER_MAX, "%ld", (size_t) evt.attr);
+        command_play(srv->db, &srv->win, &string, &srv->mpd_idle_events);
+        break;
+
+    case lkt_event_null:
+    default:
+        free(string);
+        return;
+    }
+    goto redo;
+}
+
 void
 lkt_listen(struct lkt_state *srv)
 {
@@ -727,11 +758,13 @@ lkt_listen(struct lkt_state *srv)
     srv->fds[0].events = POLLIN;
     srv->fds_len = 1;
 
+    /* Listen */
     for (;;) {
         if (handle_network_events(srv) < 0)
             break;
         if (handle_idle_events(srv) < 0)
             break;
         srv->win.handle_events(&srv->win, srv->db, &srv->mpd_idle_events);
+        handle_queue_events(srv);
     }
 }
diff --git a/src/queue.c b/src/queue.c
new file mode 100644
index 0000000000000000000000000000000000000000..c872e1f43f88ef9e4e22b3ca97e58f37b616cd5e
--- /dev/null
+++ b/src/queue.c
@@ -0,0 +1,93 @@
+#define _POSIX_C_SOURCE 200809L
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include <common/common.h>
+#include <common/queue.h>
+#include <pthread.h>
+
+int
+lkt_queue_new(struct queue *ret)
+{
+    if (!ret)
+        return 1;
+
+    pthread_mutex_t mxt = PTHREAD_MUTEX_INITIALIZER;
+    struct queue _ret = {
+        .contents = malloc(LKT_DEFAULT_LIST_SIZE * sizeof(lkt_event)),
+        .size = LKT_DEFAULT_LIST_SIZE,
+        .last = 0,
+        .available = 0,
+        .lock = mxt,
+    };
+
+    if (_ret.contents == NULL)
+        return 1;
+
+    *ret = _ret;
+    return 0;
+}
+
+void
+lkt_queue_free(struct queue *queue)
+{
+    pthread_mutex_lock(&queue->lock);
+    if (queue && queue->contents)
+        free((void *) queue->contents);
+    pthread_mutex_unlock(&queue->lock);
+}
+
+void
+lkt_queue_send(struct queue *queue, enum lkt_event_type _type, void *_attr)
+{
+    pthread_mutex_lock(&queue->lock);
+    if (!queue)
+        goto end;
+
+    volatile lkt_event *new;
+    if (queue->size == queue->last) {
+        new = realloc((void *) queue->contents, queue->size * 2 * sizeof(lkt_event));
+
+        if (NULL == new)
+            goto end;
+
+        queue->contents = new;
+        queue->size *= 2;
+    }
+
+    lkt_event evt = {
+        .type = _type,
+        .attr = _attr,
+    };
+    queue->contents[(queue->last)++] = evt;
+end:
+    pthread_mutex_unlock(&queue->lock);
+}
+
+lkt_event
+lkt_queue_handle(struct queue *queue)
+{
+    pthread_mutex_lock(&queue->lock);
+    lkt_event ret = {0};
+
+    if (!queue || !queue->last ||
+        !(queue->contents[0].type & queue->available))
+        goto end;
+
+    ret = queue->contents[0];
+    memmove((void *) queue->contents, (void *) (queue->contents + 1), --(queue->last));
+end:
+    pthread_mutex_unlock(&queue->lock);
+    return ret;
+}
+
+void
+lkt_queue_make_available(struct queue *queue, enum lkt_event_type type)
+{
+    pthread_mutex_lock(&queue->lock);
+    queue->available |= type;
+    pthread_mutex_unlock(&queue->lock);
+}