Index: libroar/time.c
===================================================================
--- libroar/time.c	(revision 5068)
+++ libroar/time.c	(revision 5075)
@@ -161,8 +161,9 @@
  switch (clock) {
   case ROAR_CLOCK_REALTIME:
-    ROAR_DBG("roar_clock_gettime(rt=%p, clock=(%i)ROAR_CLOCK_REALTIME) = -1", rt, clock);
+    ROAR_DBG("roar_clock_gettime(rt=%p, clock=(%i)ROAR_CLOCK_REALTIME) = ?", rt, clock);
 #ifdef ROAR_HAVE_GETTIMEOFDAY
     if ( gettimeofday(&tv, NULL) == -1 ) {
      roar_err_from_errno();
+     ROAR_DBG("roar_clock_gettime(rt=%p, clock=(%i)ROAR_CLOCK_REALTIME) = -1 //error=%i", rt, clock, roar_error);
      return -1;
     }
@@ -175,7 +176,9 @@
     rt->c_freq = 1000000000LLU;
 #else
+    ROAR_DBG("roar_clock_gettime(rt=%p, clock=(%i)ROAR_CLOCK_REALTIME) = -1 // error=NOTSUP", rt, clock);
     roar_err_set(ROAR_ERROR_NOTSUP);
     return -1;
 #endif
+    ROAR_DBG("roar_clock_gettime(rt=%p, clock=(%i)ROAR_CLOCK_REALTIME) = 0", rt, clock);
     return 0;
    break;
Index: libroar/vs.c
===================================================================
--- libroar/vs.c	(revision 5073)
+++ libroar/vs.c	(revision 5075)
@@ -50,5 +50,4 @@
 #define FLAG_FREE_VOL  0x0010
 #define FLAG_DEF_PAUSE 0x0020
-#define FLAG_ASYNC     0x0040
 #define FLAG_DIR_IN    0x1000
 #define FLAG_DIR_OUT   0x2000
@@ -59,5 +58,5 @@
 #define _seterrse() do { roar_err_from_errno(); _seterr(roar_error); } while(0)
 #define _ckvss(ret) do { if ( vss == NULL ) { _seterr(ROAR_ERROR_INVAL); return (ret); } } while(0)
-#define _ckasync(ret) do { if ( _handle_async(vss, error) == -1 ) { return (ret); } } while(0);
+#define _ckasync(ret) do { if ( _handle_async(vss, error) == -1 ) { return (ret); } } while(0)
 
 struct roar_vs {
@@ -89,4 +88,5 @@
  } latmes;
  struct {
+  int    level;
   size_t lock;
   size_t qlen;
@@ -97,4 +97,53 @@
 
 static int _roar_vs_find_first_prim(roar_vs_t * vss);
+
+static int _send_async_req(roar_vs_t * vss, int cmd, int subcmd, int * error) {
+ struct roar_message mes;
+ uint16_t * data = (uint16_t *) mes.data;
+
+ if ( !vss->async.level ) {
+  _seterr(ROAR_ERROR_INVAL);
+  return -1;
+ }
+
+ if ( vss->async.lock ) {
+  _seterr(ROAR_ERROR_BUSY);
+  return -1;
+ }
+
+ if ( vss->async.qlen == ASYNC_QLEN ) {
+  _seterr(ROAR_ERROR_NOSPC);
+  return -1;
+ }
+
+ memset(&mes, 0, sizeof(mes));
+
+ mes.cmd    = cmd;
+ mes.stream = roar_stream_get_id(&(vss->stream));
+ mes.pos    = 0;
+
+ if ( cmd == ROAR_CMD_GET_STREAM_PARA && subcmd == ROAR_STREAM_PARA_INFO ) {
+  mes.datalen = 4;
+  data[0] = ROAR_HOST2NET16(0); // Version and reserved
+  data[1] = ROAR_HOST2NET16(ROAR_STREAM_PARA_INFO); // stream
+ } else if ( cmd == ROAR_CMD_GET_STREAM ) {
+  mes.datalen = 1;
+  mes.data[0] = mes.stream;
+ } else {
+  _seterr(ROAR_ERROR_NOSYS);
+  return -1;
+ }
+
+ if ( roar_send_message(vss->con, &mes, NULL) == -1 ) {
+  _seterrre();
+  return -1;
+ }
+
+ vss->async.qcmd[vss->async.qlen] = cmd;
+ vss->async.qsubcmd[vss->async.qlen] = subcmd;
+ vss->async.qlen++;
+
+ return 0;
+}
 
 static int _handle_async_req(roar_vs_t * vss, int * error) {
@@ -118,4 +167,6 @@
   vss->async.qsubcmd[i-1] = vss->async.qsubcmd[i];
  }
+
+ //printf("mes.cmd=%i, cmd=%i, subcmd=%i\n", (int)mes.cmd, cmd, subcmd);
 
  if ( mes.cmd == ROAR_CMD_OK ) {
@@ -140,8 +191,14 @@
     break;
    case ROAR_CMD_GET_STREAM:
-     vss->latmes.last_offset = mes.pos; // ha, this is a easy one ;)
+     if ( roar_clock_gettime(&(vss->latmes.last_time), LOCAL_CLOCK) == -1 ) {
+      vss->latmes.last_pos = -1;
+     } else {
+      vss->latmes.last_pos = mes.pos;
+     }
+     //printf("vss->latmes.last_pos=%li, mes.pos=%li\n", (long int)vss->latmes.last_pos, (long int)mes.pos);
     break;
    default:
      ROAR_WARN("_handle_async_req(vss=%p, error=%p): Got unexpected reply for command %i", vss, error, cmd);
+     _seterr(ROAR_ERROR_NOSYS);
     break;
   }
@@ -151,6 +208,5 @@
   free(data);
 
- _seterr(ROAR_ERROR_NOSYS);
- return -1;
+ return 0;
 }
 
@@ -163,4 +219,22 @@
 
  return 0;
+}
+
+static void _check_async(roar_vs_t * vss) {
+ struct roar_vio_select vios;
+ struct roar_vio_selecttv tv = {0, 0};
+
+ if ( !vss->async.qlen )
+  return;
+
+ ROAR_VIO_SELECT_SETVIO(&vios, roar_get_connection_vio2(vss->con), ROAR_VIO_SELECT_READ);
+
+ if ( roar_vio_select(&vios, 1, &tv, NULL) < 1 )
+  return;
+
+ if ( !(vios.eventsa & ROAR_VIO_SELECT_READ) )
+  return;
+
+ _handle_async_req(vss, NULL);
 }
 
@@ -869,4 +943,6 @@
  }
 
+ _check_async(vss);
+
  if ( wait == ROAR_VS_WAIT ) {
   return roar_vs_latency(vss, backend, error);
@@ -922,4 +998,13 @@
 
   return lag;
+ } else if ( wait == ROAR_VS_ASYNC ) {
+  if ( _send_async_req(vss, ROAR_CMD_GET_STREAM, -1, error) == -1 )
+   return 0;
+/*
+  if ( _send_async_req(vss, ROAR_CMD_GET_STREAM_PARA, ROAR_STREAM_PARA_INFO, error) == -1 )
+   return 0;
+*/
+  _seterr(ROAR_ERROR_NODATA);
+  return 0;
  }
 
@@ -1605,4 +1690,35 @@
     *(int*)argp = vss->flags & FLAG_DEF_PAUSE ? ROAR_VS_TRUE : ROAR_VS_FALSE;
    break;
+  case ROAR_VS_CMD_SET_ASYNC:
+    vss->async.level = *(int*)argp;
+   break;
+  case ROAR_VS_CMD_GET_ASYNC:
+    *(int*)argp = vss->async.level;
+   break;
+  case ROAR_VS_CMD_LOCK_ASYNC:
+    _ckasync(-1);
+    if ( argp == NULL ) {
+     vss->async.lock++;
+    } else {
+     vss->async.lock -= *(int*)argp;
+    }
+   break;
+  case ROAR_VS_CMD_UNLOCK_ASYNC:
+    if ( argp == NULL ) {
+     if ( !vss->async.lock ) {
+      _seterr(ROAR_ERROR_LOSTSYNC);
+      return -1;
+     } else {
+      vss->async.lock--;
+     }
+    } else {
+     if ( vss->async.lock < (size_t)*(int*)argp ) {
+      _seterr(ROAR_ERROR_LOSTSYNC);
+      return -1;
+     } else {
+      vss->async.lock -= *(int*)argp;
+     }
+    }
+   break;
 // use ifndef here so warnings of unhandled enum values will be shown in DEBUG mode.
 #ifndef DEBUG
