From 2270c9ec24491ec7d44bf3d5273bead1d0a873a3 Mon Sep 17 00:00:00 2001
From: Anders Blomdell <anders.blomdell@control.lth.se>
Date: Fri, 28 Jun 2013 15:07:23 +0200
Subject: [PATCH] Major code reorganization. New scheduler abstraction in
 place.

---
 examples/simple/example_decoder.c             |   7 +-
 examples/simple/example_encoder.c             |   7 +-
 examples/twoway/client.c                      |  30 +-
 examples/twoway/decimating.c                  |  40 +-
 examples/twoway/decimating.h                  |   5 +-
 examples/twoway/introspecting.c               | 101 ++-
 examples/twoway/introspecting.h               |   5 +-
 examples/twoway/server.c                      |  30 +-
 lib/c/Makefile                                |   8 +-
 lib/c/labcomm.c                               | 756 +-----------------
 lib/c/labcomm.h                               |  34 +-
 lib/c/labcomm_decoder.c                       | 403 ++++++++++
 lib/c/labcomm_default_error_handler.c         |  24 +
 lib/c/labcomm_default_error_handler.h         |  24 +
 ..._mutex_lock.h => labcomm_default_memory.h} |  11 +-
 lib/c/labcomm_default_scheduler.c             | 109 +++
 lib/c/labcomm_default_scheduler.h             |  24 +
 lib/c/labcomm_dynamic_buffer_writer.c         |   4 +-
 lib/c/labcomm_encoder.c                       | 222 +++++
 lib/c/labcomm_error.h                         |   2 +
 lib/c/labcomm_fd_reader.c                     |   1 -
 lib/c/labcomm_fd_writer.c                     |   4 +-
 lib/c/labcomm_private.h                       |  45 +-
 lib/c/labcomm_pthread_mutex_lock.c            | 114 ---
 lib/c/labcomm_pthread_scheduler.c             |   2 +-
 lib/c/labcomm_signature.h                     |  23 +
 lib/c/labcomm_signature_gnu_ld_tricks.c       |  38 +
 lib/c/test/test_labcomm_generated_encoding.c  |  15 +-
 lib/c/test/test_labcomm_pthread_scheduler.c   |   8 +-
 test/relay_gen_c.py                           |  13 +-
 30 files changed, 1058 insertions(+), 1051 deletions(-)
 create mode 100644 lib/c/labcomm_decoder.c
 create mode 100644 lib/c/labcomm_default_error_handler.c
 create mode 100644 lib/c/labcomm_default_error_handler.h
 rename lib/c/{labcomm_pthread_mutex_lock.h => labcomm_default_memory.h} (75%)
 create mode 100644 lib/c/labcomm_default_scheduler.c
 create mode 100644 lib/c/labcomm_default_scheduler.h
 create mode 100644 lib/c/labcomm_encoder.c
 delete mode 100644 lib/c/labcomm_pthread_mutex_lock.c
 create mode 100644 lib/c/labcomm_signature.h
 create mode 100644 lib/c/labcomm_signature_gnu_ld_tricks.c

diff --git a/examples/simple/example_decoder.c b/examples/simple/example_decoder.c
index 2b1f746..122745d 100644
--- a/examples/simple/example_decoder.c
+++ b/examples/simple/example_decoder.c
@@ -2,6 +2,9 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <labcomm_fd_reader.h>
+#include <labcomm_default_error_handler.h>
+#include <labcomm_default_memory.h>
+#include <labcomm_default_scheduler.h>
 #include "gen/simple.h"
 #include <stdio.h>
 
@@ -58,7 +61,9 @@ int main(int argc, char *argv[]) {
   fd = open(filename, O_RDONLY);
   decoder = labcomm_decoder_new(labcomm_fd_reader_new(
 				  labcomm_default_memory, fd, 1), 
-				NULL, labcomm_default_memory);
+				labcomm_default_error_handler, 
+				labcomm_default_memory,
+				labcomm_default_scheduler);
   if (!decoder) { 
     printf("Failed to allocate decoder %s:%d\n", __FUNCTION__, __LINE__);
     return 1;
diff --git a/examples/simple/example_encoder.c b/examples/simple/example_encoder.c
index 67beb4c..1746942 100644
--- a/examples/simple/example_encoder.c
+++ b/examples/simple/example_encoder.c
@@ -2,6 +2,9 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <labcomm_fd_writer.h>
+#include <labcomm_default_error_handler.h>
+#include <labcomm_default_memory.h>
+#include <labcomm_default_scheduler.h>
 #include "gen/simple.h"
 #include <stdio.h>
 
@@ -14,7 +17,9 @@ int main(int argc, char *argv[]) {
   fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644);
   encoder = labcomm_encoder_new(labcomm_fd_writer_new(
 				  labcomm_default_memory, fd, 1), 
-				NULL, labcomm_default_memory);
+				labcomm_default_error_handler, 
+				labcomm_default_memory,
+				labcomm_default_scheduler);
   labcomm_encoder_register_simple_theTwoInts(encoder);
   labcomm_encoder_register_simple_anotherTwoInts(encoder);
   labcomm_encoder_register_simple_IntString(encoder);
diff --git a/examples/twoway/client.c b/examples/twoway/client.c
index 401a7a5..656a71f 100644
--- a/examples/twoway/client.c
+++ b/examples/twoway/client.c
@@ -33,7 +33,9 @@
 #include <labcomm.h>
 #include <labcomm_fd_reader.h>
 #include <labcomm_fd_writer.h>
-#include <labcomm_pthread_mutex_lock.h>
+#include <labcomm_default_error_handler.h>
+#include <labcomm_default_memory.h>
+#include <labcomm_pthread_scheduler.h>
 #include "decimating.h"
 #include "introspecting.h"
 #include "gen/types.h"
@@ -74,7 +76,7 @@ int main(int argc, char *argv[])
   struct introspecting *introspecting;
   char *hostname;
   int port;
-  struct labcomm_lock *lock;
+  struct labcomm_scheduler *scheduler;
   struct labcomm_decoder *decoder;
   struct labcomm_encoder *encoder;
   int32_t i, j;
@@ -114,29 +116,35 @@ int main(int argc, char *argv[])
   
   nodelay = 1;
   setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay));
-  lock = labcomm_pthread_mutex_lock_new(labcomm_default_memory);
+  scheduler = labcomm_pthread_scheduler_new(labcomm_default_memory);
   decimating = decimating_new(labcomm_fd_reader_new(labcomm_default_memory, 
 						    fd, 1),
 			      labcomm_fd_writer_new(labcomm_default_memory, 
 						    fd, 0),
-			      lock,
-			      labcomm_default_memory);
+			      labcomm_default_error_handler,
+			      labcomm_default_memory,
+			      scheduler);
   if (decimating == NULL) {
     /* Warning: might leak reader and writer at this point */
     goto out;
   }
   introspecting = introspecting_new(decimating->reader,
 				    decimating->writer,
-				    lock,
-				    labcomm_default_memory);
+				    labcomm_default_error_handler,
+				    labcomm_default_memory,
+				    scheduler);
   if (introspecting == NULL) {
     /* Warning: might leak reader and writer at this point */
     goto out;
   }
-  decoder = labcomm_decoder_new(introspecting->reader, lock,
-				labcomm_default_memory);
-  encoder = labcomm_encoder_new(introspecting->writer, lock,
-				labcomm_default_memory);
+  decoder = labcomm_decoder_new(introspecting->reader, 
+				labcomm_default_error_handler,
+				labcomm_default_memory,
+				scheduler);
+  encoder = labcomm_encoder_new(introspecting->writer, 
+				labcomm_default_error_handler,
+				labcomm_default_memory,
+				scheduler);
   pthread_t rdt;
   pthread_create(&rdt, NULL, run_decoder, decoder);  
   labcomm_encoder_register_types_A(encoder);
diff --git a/examples/twoway/decimating.c b/examples/twoway/decimating.c
index 52b2329..717a8e7 100644
--- a/examples/twoway/decimating.c
+++ b/examples/twoway/decimating.c
@@ -29,8 +29,9 @@
 
 struct decimating_private {
   struct decimating decimating;
+  struct labcomm_error_handler *error;
   struct labcomm_memory *memory;
-  struct labcomm_lock *lock;
+  struct labcomm_scheduler *scheduler;
   int encoder_initialized;
   struct labcomm_reader_action_context reader_action_context;
   struct labcomm_writer_action_context writer_action_context;
@@ -59,19 +60,19 @@ static void set_decimation(
 static int wrap_reader_alloc(
   struct labcomm_reader *r, 
   struct labcomm_reader_action_context *action_context, 
-  struct labcomm_decoder *decoder,
   char *labcomm_version)
 {
   int result;
 
   struct decimating_private *decimating = action_context->context;
   
-  fprintf(stderr, "%s %s\n", __FILE__, __FUNCTION__);
+  fprintf(stderr, "%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
   /* Stash away decoder for later use */
-  result = labcomm_reader_alloc(r, action_context->next, 
-				decoder, labcomm_version);
+  result = labcomm_reader_alloc(r, action_context->next, labcomm_version);
+  fprintf(stderr, "%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
   labcomm_decoder_register_decimating_messages_set_decimation(
-    decoder, set_decimation, decimating);
+    r->decoder, set_decimation, decimating);
+  fprintf(stderr, "%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
   return result;
 }
 
@@ -110,25 +111,26 @@ struct labcomm_reader_action decimating_reader_action = {
   .ioctl = wrap_reader_ioctl
 };
 
-static void register_signatures(struct labcomm_encoder *encoder,
-				void *context)
+static void register_signatures(void *context)
 {
+  struct decimating_private *decimating = context;
+
   labcomm_encoder_register_decimating_messages_set_decimation(
-    encoder);
+    decimating->decimating.writer->encoder);
 }
 
 static int wrap_writer_alloc(
   struct labcomm_writer *w, 
   struct labcomm_writer_action_context *action_context, 
-  struct labcomm_encoder *encoder, char *labcomm_version,
-  labcomm_encoder_enqueue enqueue)
+  char *labcomm_version)
 {
+  struct decimating_private *decimating = action_context->context;
   int result;
 
   fprintf(stderr, "%s %s\n", __FILE__, __FUNCTION__);
-  result = labcomm_writer_alloc(w, action_context->next,
-				encoder, labcomm_version, enqueue);
-  enqueue(encoder, register_signatures, NULL);
+  result = labcomm_writer_alloc(w, action_context->next, labcomm_version);
+  labcomm_scheduler_enqueue(decimating->scheduler, 
+			    0, register_signatures, decimating);
 
   return result;
 }
@@ -164,11 +166,12 @@ struct labcomm_writer_action decimating_writer_action = {
   .ioctl = NULL
 };
 
-extern struct decimating *decimating_new(
+struct decimating *decimating_new(
   struct labcomm_reader *reader,
   struct labcomm_writer *writer,
-  struct labcomm_lock *lock,
-  struct labcomm_memory *memory)
+  struct labcomm_error_handler *error,
+  struct labcomm_memory *memory,
+  struct labcomm_scheduler *scheduler)
 {
   struct decimating_private *result;
 
@@ -193,8 +196,9 @@ extern struct decimating *decimating_new(
   result->decimating.writer = writer;
 
   /* Init other fields */
-  result->lock = lock;
+  result->error = error;
   result->memory = memory;
+  result->scheduler = scheduler;
   LABCOMM_SIGNATURE_ARRAY_INIT(result->decimation, struct decimation);
 
   goto out_ok;
diff --git a/examples/twoway/decimating.h b/examples/twoway/decimating.h
index df926ef..cdfedd7 100644
--- a/examples/twoway/decimating.h
+++ b/examples/twoway/decimating.h
@@ -12,8 +12,9 @@ struct decimating {
 extern struct decimating *decimating_new(
   struct labcomm_reader *reader,
   struct labcomm_writer *writer,
-  struct labcomm_lock *lock,
-  struct labcomm_memory *memory);
+  struct labcomm_error_handler *error,
+  struct labcomm_memory *memory,
+  struct labcomm_scheduler *scheduler);
 
 #define SET_DECIMATION LABCOMM_IOSW('d',0,int)
 
diff --git a/examples/twoway/introspecting.c b/examples/twoway/introspecting.c
index 8123988..cb17246 100644
--- a/examples/twoway/introspecting.c
+++ b/examples/twoway/introspecting.c
@@ -30,13 +30,10 @@
 enum status {unknown, unhandled, unregistered, registered};
 struct introspecting_private {
   struct introspecting introspecting;
-  struct labcomm_lock *lock;
+  struct labcomm_error_handler *error;
   struct labcomm_memory *memory;
+  struct labcomm_scheduler *scheduler;
 
-  struct labcomm_encoder *encoder;
-  int encoder_initialized;
-  struct labcomm_decoder *decoder;
-  int decoder_initialized;
   struct labcomm_reader_action_context reader_action_context;
   struct labcomm_writer_action_context writer_action_context;
   LABCOMM_SIGNATURE_ARRAY_DEF(remote, 
@@ -93,51 +90,60 @@ static void handles_signature(
 static int wrap_reader_alloc(
   struct labcomm_reader *r, 
   struct labcomm_reader_action_context *action_context, 
-  struct labcomm_decoder *decoder,
   char *labcomm_version)
 {
   int result;
   struct introspecting_private *introspecting = action_context->context;
 
   fprintf(stderr, "%s %s\n", __FILE__, __FUNCTION__);
-  /* Stash away decoder for later use */
-  introspecting->decoder = decoder;
-  result = labcomm_reader_alloc(r, action_context->next, 
-				decoder, labcomm_version);
+  result =  labcomm_reader_alloc(r, action_context->next, labcomm_version);
   labcomm_decoder_register_introspecting_messages_handles_signature(
-    introspecting->decoder, handles_signature, introspecting);
-  introspecting->decoder_initialized = 1;
+    introspecting->introspecting.reader->decoder, 
+    handles_signature, introspecting);
   return result;
 }
 
+struct handles_signature {
+  struct introspecting_private *introspecting;
+  int index;
+  struct labcomm_signature *signature;
+};
+
+static void send_handles_signature(void *arg)
+{
+  struct handles_signature *h = arg;
+
+  introspecting_messages_handles_signature handles_signature;
+  handles_signature.index = h->index;
+  handles_signature.name = h->signature->name;
+  handles_signature.signature.n_0 = h->signature->size;
+  handles_signature.signature.a = h->signature->signature;
+  labcomm_encode_introspecting_messages_handles_signature(
+    h->introspecting->introspecting.writer->encoder, &handles_signature);
+}
+
 static int wrap_reader_start(
   struct labcomm_reader *r, 
   struct labcomm_reader_action_context *action_context,
-  int index, struct labcomm_signature *signature,
+  int local_index, int remote_index, struct labcomm_signature *signature,
   void *value)
 {
   struct introspecting_private *introspecting = action_context->context;
-  int result;
   
-  result = labcomm_reader_start(r, action_context->next, index,
-				signature, value);  
   if (value == NULL) {
-    introspecting_messages_handles_signature handles_signature;
+    struct handles_signature *handles_signature;
+
+    handles_signature = labcomm_memory_alloc(introspecting->memory, 1,
+					     sizeof(*handles_signature));
+    handles_signature->introspecting = introspecting;
+    handles_signature->index = local_index;
+    handles_signature->signature = signature;
+    labcomm_scheduler_enqueue(introspecting->scheduler, 
+			      0, send_handles_signature, handles_signature);
 
-    labcomm_lock_acquire(introspecting->lock);
-    while (introspecting->encoder == NULL) {
-      /* Wait for the encoder to become functional */
-      labcomm_lock_wait(introspecting->lock, 1000000);
-    }
-    labcomm_lock_release(introspecting->lock);
-    handles_signature.index = index;
-    handles_signature.name = signature->name;
-    handles_signature.signature.n_0 = signature->size;
-    handles_signature.signature.a = signature->signature;
-    labcomm_encode_introspecting_messages_handles_signature(
-      introspecting->encoder, &handles_signature);
   }
-  return result;
+  return labcomm_reader_start(r, action_context->next, 
+			      local_index, remote_index, signature, value);
 }
 
  void encode_handles_signature(
@@ -167,32 +173,25 @@ struct labcomm_reader_action introspecting_reader_action = {
   .ioctl = NULL
 };
 
-static void register_signatures(struct labcomm_encoder *encoder,
-				void *context)
+static void register_encoder_signatures(void *context)
 {
+  struct introspecting_private *introspecting = context;
+
   labcomm_encoder_register_introspecting_messages_handles_signature(
-    encoder);
+    introspecting->introspecting.writer->encoder);
 }
 
 static int wrap_writer_alloc(
   struct labcomm_writer *w, 
   struct labcomm_writer_action_context *action_context, 
-  struct labcomm_encoder *encoder, char *labcomm_version,
-  labcomm_encoder_enqueue enqueue)
+  char *labcomm_version)
 {
-  int result;
   struct introspecting_private *introspecting = action_context->context;
 
   fprintf(stderr, "%s %s\n", __FILE__, __FUNCTION__);
-  /* Stash away encoder for later use */
-  labcomm_lock_acquire(introspecting->lock);
-  introspecting->encoder = encoder;
-  labcomm_lock_notify(introspecting->lock);
-  labcomm_lock_release(introspecting->lock);
-  result = labcomm_writer_alloc(w, action_context->next,
-				encoder, labcomm_version, enqueue);
-  enqueue(encoder, register_signatures, NULL);
-  return result;
+  labcomm_scheduler_enqueue(introspecting->scheduler, 
+			    0, register_encoder_signatures, introspecting);
+  return labcomm_writer_alloc(w, action_context->next, labcomm_version);
 }
 
 static int wrap_writer_start(
@@ -249,8 +248,9 @@ struct labcomm_writer_action introspecting_writer_action = {
 extern struct introspecting *introspecting_new(
   struct labcomm_reader *reader,
   struct labcomm_writer *writer,
-  struct labcomm_lock *lock,
-  struct labcomm_memory *memory)
+  struct labcomm_error_handler *error,
+  struct labcomm_memory *memory,
+  struct labcomm_scheduler *scheduler)
 {
   struct introspecting_private *result;
 
@@ -275,12 +275,9 @@ extern struct introspecting *introspecting_new(
   result->introspecting.writer = writer;
 
   /* Init other fields */
-  result->lock = lock;
+  result->error = error;
   result->memory = memory;
-  result->encoder = NULL;
-  result->encoder_initialized = 0;
-  result->decoder = NULL;
-  result->decoder_initialized = 0;
+  result->scheduler = scheduler;
   LABCOMM_SIGNATURE_ARRAY_INIT(result->remote, struct remote);
   LABCOMM_SIGNATURE_ARRAY_INIT(result->local, struct local);
 
diff --git a/examples/twoway/introspecting.h b/examples/twoway/introspecting.h
index 7eea00e..894b998 100644
--- a/examples/twoway/introspecting.h
+++ b/examples/twoway/introspecting.h
@@ -36,8 +36,9 @@ struct introspecting {
 extern struct introspecting *introspecting_new(
   struct labcomm_reader *reader,
   struct labcomm_writer *writer,
-  struct labcomm_lock *lock,
-  struct labcomm_memory *memory);
+  struct labcomm_error_handler *error,
+  struct labcomm_memory *memory,
+  struct labcomm_scheduler *scheduler);
 
 #define HAS_SIGNATURE LABCOMM_IOS('i',2)
 
diff --git a/examples/twoway/server.c b/examples/twoway/server.c
index 58a8ae0..66c7c6a 100644
--- a/examples/twoway/server.c
+++ b/examples/twoway/server.c
@@ -27,7 +27,9 @@
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <labcomm_pthread_mutex_lock.h>
+#include <labcomm_default_error_handler.h>
+#include <labcomm_default_memory.h>
+#include <labcomm_pthread_scheduler.h>
 #include <labcomm_fd_reader.h>
 #include <labcomm_fd_writer.h>
 #include "decimating.h"
@@ -89,34 +91,40 @@ static void *run_client(void *arg)
   struct client *client = arg;
   struct decimating *decimating;
   struct introspecting *introspecting;
-  struct labcomm_lock *lock;
+  struct labcomm_scheduler *scheduler;
 
   printf("Client start\n");
   client->A = 0;
   client->B = 0;
-  lock = labcomm_pthread_mutex_lock_new(labcomm_default_memory);
+  scheduler = labcomm_pthread_scheduler_new(labcomm_default_memory);
   decimating = decimating_new(labcomm_fd_reader_new(labcomm_default_memory,
 						    client->fd, 1),
 			      labcomm_fd_writer_new(labcomm_default_memory,
 						    client->fd, 0),
-			      lock,
-			      labcomm_default_memory);
+			      labcomm_default_error_handler,
+			      labcomm_default_memory,
+			      scheduler);
   if (decimating == NULL) {
     /* Warning: might leak reader and writer at this point */
     goto out;
   }
   introspecting = introspecting_new(decimating->reader,
 				    decimating->writer,
-				    lock,
-				    labcomm_default_memory);
+				    labcomm_default_error_handler,
+				    labcomm_default_memory,
+				    scheduler);
   if (introspecting == NULL) {
     /* Warning: might leak reader and writer at this point */
     goto out;
   }
-  client->decoder = labcomm_decoder_new(introspecting->reader, lock,
-					labcomm_default_memory);
-  client->encoder = labcomm_encoder_new(introspecting->writer, lock,
-					labcomm_default_memory);
+  client->decoder = labcomm_decoder_new(introspecting->reader,
+				    labcomm_default_error_handler,
+				    labcomm_default_memory,
+				    scheduler);
+  client->encoder = labcomm_encoder_new(introspecting->writer,
+				    labcomm_default_error_handler,
+				    labcomm_default_memory,
+				    scheduler);
   pthread_t rdt;
   pthread_create(&rdt, NULL, run_decoder, client);  
   labcomm_encoder_register_types_Sum(client->encoder);
diff --git a/lib/c/Makefile b/lib/c/Makefile
index 043eaf0..979b989 100644
--- a/lib/c/Makefile
+++ b/lib/c/Makefile
@@ -7,12 +7,16 @@ LDFLAGS=-L.
 #LDLIBS_TEST=-Tlabcomm.linkscript  -lcunit -llabcomm
 LDLIBS_TEST=-lcunit -llabcomm -Tlabcomm.linkscript -lrt
 
-OBJS=labcomm_memory.o labcomm_default_memory.o \
+OBJS=labcomm_memory.o \
+     labcomm_default_error_handler.o \
+     labcomm_default_memory.o \
+     labcomm_default_scheduler.o \
      labcomm_time.o labcomm_scheduler.o \
+     labcomm_encoder.o labcomm_decoder.o \
      labcomm.o \
      labcomm_dynamic_buffer_writer.o labcomm_fd_reader.o labcomm_fd_writer.o \
      labcomm_pthread_scheduler.o \
-     labcomm_pthread_mutex_lock.o
+     labcomm_signature_gnu_ld_tricks.o
 
 #FIXME: labcomm_mem_reader.o labcomm_mem_writer.o
 LABCOMM_JAR=../../compiler/labComm.jar
diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c
index 582d5aa..1721289 100644
--- a/lib/c/labcomm.c
+++ b/lib/c/labcomm.c
@@ -39,90 +39,6 @@
 
 #define LABCOMM_VERSION "LabComm2013"
 
-struct labcomm_decoder {
-  void *context;
-  struct labcomm_reader *reader;
-  struct labcomm_lock *lock;
-  struct labcomm_memory *memory;
-  labcomm_error_handler_callback on_error;
-  labcomm_handle_new_datatype_callback on_new_datatype;
-  LABCOMM_SIGNATURE_ARRAY_DEF(local_to_remote, int);
-  LABCOMM_SIGNATURE_ARRAY_DEF(remote_to_local, int);
-};
-
-struct labcomm_encoder {
-  void *context;
-  struct labcomm_writer *writer;
-  struct labcomm_lock *lock;
-  struct labcomm_memory *memory;
-  struct labcomm_encoder *is_deferred;
-  int busy;
-  int waiting;
-  struct encoder_alloc_action {
-    struct encoder_alloc_action *next;
-    void (*action)(struct labcomm_encoder *encoder, void *context);
-    void *context;
-  } *alloc_action;
-  labcomm_error_handler_callback on_error;
-  LABCOMM_SIGNATURE_ARRAY_DEF(registered, int);
-};
-
-struct labcomm_sample_entry {
-  struct labcomm_sample_entry *next;
-  int index;
-  struct labcomm_signature *signature;
-  labcomm_decoder_function decoder;
-  labcomm_handler_function handler;
-  labcomm_encoder_function encode;
-  void *context;
-};
-
-extern  struct labcomm_signature labcomm_first_signature;
-extern  struct labcomm_signature labcomm_last_signature;
-
-struct labcomm_encoder_context {
-  struct labcomm_sample_entry *by_section;
-};
-
-struct labcomm_decoder_context {
-  struct labcomm_sample_entry *sample;
-};
-
-/* Lock wrappers */
-#define CONDCALL_lock(lock, ...) lock
-#define CONDCALL(func, ...)					\
-  if (CONDCALL_lock(__VA_ARGS__) &&				\
-      CONDCALL_lock(__VA_ARGS__)->action->func) {		\
-  return CONDCALL_lock(__VA_ARGS__)->action->func(__VA_ARGS__);	\
-  }								\
-  return -ENOSYS;
-
-int labcomm_lock_free(struct labcomm_lock *lock) {
-  CONDCALL(free, lock);
-}
-
-int labcomm_lock_acquire(struct labcomm_lock *lock)
-{
-  CONDCALL(acquire, lock);
-}
-
-int labcomm_lock_release(struct labcomm_lock *lock)
-{
-  CONDCALL(release, lock);
-}
-
-int labcomm_lock_wait(struct labcomm_lock *lock, useconds_t usec){
-  CONDCALL(wait, lock, usec);
-}
-
-int labcomm_lock_notify(struct labcomm_lock *lock)
-{
-  CONDCALL(notify, lock);
-}
-
-#undef CONDCALL
-#undef CONDCALL_lock
-
 /* Unwrapping reader/writer functions */
 #define UNWRAP_ac(rw, ac, ...) ac
 #define UNWRAP(func, ...)	     \
@@ -135,10 +51,9 @@ int labcomm_lock_notify(struct labcomm_lock *lock)
 
 int labcomm_reader_alloc(struct labcomm_reader *r, 
                          struct labcomm_reader_action_context *action_context, 
-                         struct labcomm_decoder *decoder, 
                          char *labcomm_version)
 {
-  UNWRAP(alloc, r, action_context, decoder, labcomm_version);
+  UNWRAP(alloc, r, action_context, labcomm_version);
 }
 
 int labcomm_reader_free(struct labcomm_reader *r, 
@@ -149,10 +64,11 @@ int labcomm_reader_free(struct labcomm_reader *r,
 
 int labcomm_reader_start(struct labcomm_reader *r, 
                          struct labcomm_reader_action_context *action_context,
-			 int index, struct labcomm_signature *signature,
+			 int local_index, int remote_index,
+			 struct labcomm_signature *signature,
 			 void *value)
 {
-  UNWRAP(start, r, action_context, index, signature, value);
+  UNWRAP(start, r, action_context, local_index, remote_index, signature, value);
 }
 
 int labcomm_reader_end(struct labcomm_reader *r, 
@@ -178,11 +94,9 @@ int labcomm_reader_ioctl(struct labcomm_reader *r,
 
 int labcomm_writer_alloc(struct labcomm_writer *w, 
                          struct labcomm_writer_action_context *action_context, 
-                         struct labcomm_encoder *encoder, 
-                         char *labcomm_version,
-			 labcomm_encoder_enqueue enqueue)
+                         char *labcomm_version)
 {
-  UNWRAP(alloc, w, action_context, encoder, labcomm_version, enqueue);
+  UNWRAP(alloc, w, action_context, labcomm_version);
 }
 
 int labcomm_writer_free(struct labcomm_writer *w, 
@@ -225,15 +139,6 @@ int labcomm_writer_ioctl(struct labcomm_writer *w,
 
 
 
-void labcomm_register_error_handler_encoder(struct labcomm_encoder *encoder, labcomm_error_handler_callback callback)
-{
- encoder->on_error = callback; 
-}
-
-void labcomm_register_error_handler_decoder(struct labcomm_decoder *decoder, labcomm_error_handler_callback callback)
-{
- decoder->on_error = callback; 
-}
 
 static const char *labcomm_error_string[] = { 
 #define LABCOMM_ERROR(name, description) description ,
@@ -254,17 +159,6 @@ const char *labcomm_error_get_str(enum labcomm_error error_id)
   return error_str;
 }
 
-void labcomm_decoder_register_new_datatype_handler(struct labcomm_decoder *d, labcomm_handle_new_datatype_callback on_new_datatype)
-{
-	d->on_new_datatype = on_new_datatype;
-}
-
-int on_new_datatype(struct labcomm_decoder *d, struct labcomm_signature *sig)
-{
-  d->on_error(LABCOMM_ERROR_DEC_UNKNOWN_DATATYPE, 4, "%s(): unknown datatype '%s'\n", __FUNCTION__, sig->name);
-	  return 0;
-}
-
 void on_error_fprintf(enum labcomm_error error_id, size_t nbr_va_args, ...)
 {
 #ifndef LABCOMM_NO_STDIO
@@ -291,644 +185,6 @@ void on_error_fprintf(enum labcomm_error error_id, size_t nbr_va_args, ...)
 }
 
 
-static struct labcomm_sample_entry *get_sample_by_signature_address(
-  struct labcomm_sample_entry *head,
-  struct labcomm_signature *signature)
-{
-  struct labcomm_sample_entry *p;
-  for (p = head ; p && p->signature != signature ; p = p->next) {
-
-  }
-  return p;
-}
-
-static struct labcomm_sample_entry *get_sample_by_signature_value(
-  struct labcomm_sample_entry *head,
-  struct labcomm_signature *signature)
-{
-  struct labcomm_sample_entry *p;
-  for (p = head ; p ; p = p->next) {
-    if (p->signature->type == signature->type &&
-	p->signature->size == signature->size &&
-	strcmp(p->signature->name, signature->name) == 0 &&
-	bcmp((void*)p->signature->signature, (void*)signature->signature,
-	     signature->size) == 0) {
-      break;
-    }
-  }
-  return p;
-}
-
-static struct labcomm_sample_entry *get_sample_by_index(
-  struct labcomm_sample_entry *head,
-  int index)
-{
-  struct labcomm_sample_entry *p;
-  for (p = head ; p && p->index != index ; p = p->next) {
-  }
-  return p;
-}
-
-static int get_local_index(
-  struct labcomm_signature *s)
-{
-  int result = -ENOENT;
-
-  if (&labcomm_first_signature <= s && s < &labcomm_last_signature) {
-    result = (int)(s - &labcomm_first_signature) + LABCOMM_USER;
-  }
-  return result;
-}
-
-static int get_encoder_index(
-  struct labcomm_encoder *e,
-  struct labcomm_signature *s)
-{
-  return get_local_index(s);
-}
-
-struct labcomm_encoder *labcomm_encoder_new(
-  struct labcomm_writer *writer,
-  struct labcomm_lock *lock,
-  struct labcomm_memory *memory)
-{
-  struct labcomm_encoder *result;
-
-  result = labcomm_memory_alloc(memory, 0, sizeof(*result));
-  if (result) {
-    struct labcomm_encoder_context *context;
-
-    context = labcomm_memory_alloc(memory, 0, sizeof(*context));
-#ifdef LABCOMM_ENCODER_LINEAR_SEARCH
-    context->sample = NULL;
-    context->index = LABCOMM_USER;
-#else
-    context->by_section = NULL;
-#endif
-    result->context = context;
-    result->writer = writer;
-    result->writer->encoder = result;
-    result->writer->data = NULL;
-    result->writer->data_size = 0;
-    result->writer->count = 0;
-    result->writer->pos = 0;
-    result->writer->error = 0;
-    result->lock = lock;
-    result->memory = memory;
-    result->is_deferred = NULL;
-    result->busy = 0;
-    result->waiting = 0;
-    result->alloc_action = NULL;
-    result->on_error = on_error_fprintf;
-    LABCOMM_SIGNATURE_ARRAY_INIT(result->registered, int);
-  }
-  return result;
-}
-
-static int encoder_enqueue_action(
-  struct labcomm_encoder *encoder, 
-  void (*action)(struct labcomm_encoder *encoder, void *context),
-  void *context)
-{
-  int result;
-  struct encoder_alloc_action *element, **next;
-
-  element = labcomm_memory_alloc(encoder->memory, 0, sizeof(*action));
-  if (element == NULL) {
-    result = -ENOMEM;
-    goto out;
-  }
-  element->next = NULL;
-  element->action = action;
-  element->context = context;
-  for (next = &encoder->alloc_action ; *next ; next = &(*next)->next) {
-  }
-  *next = element;
-  result = 0;
-out:
-  return result;
-}
-
-static struct labcomm_encoder *enter_encoder(struct labcomm_encoder *e)
-{
-  if (e->is_deferred) {
-    return e->is_deferred;
-  } else {
-    labcomm_lock_acquire(e->lock); 
-    e->waiting++;
-    while (e->busy) { labcomm_lock_wait(e->lock, 10000000); }
-    e->busy = 1;
-    labcomm_lock_release(e->lock);
-    
-    if (e->writer->data == NULL) {
-      labcomm_writer_alloc(e->writer,e->writer->action_context,
-			   e, LABCOMM_VERSION, encoder_enqueue_action);
-      if (e->alloc_action) {
-	struct labcomm_encoder deferred;
-	struct encoder_alloc_action *p;
-
-	deferred.is_deferred = e;
-	p = e->alloc_action;
-	e->alloc_action = NULL;
-	while (p) {
-	  struct encoder_alloc_action *tmp;
-
-	  p->action(&deferred, p->context);
-	  tmp = p;
-	  p = p->next;
-	  labcomm_memory_free(e->memory, 1, tmp);
-	}
-      }
-    }
-  }
-  return e;
-}
-static void leave_encoder(struct labcomm_encoder *e)
-{
-  if (!e->is_deferred) {
-    labcomm_lock_acquire(e->lock); {
-      e->busy = 0;
-      e->waiting--;
-      if (e->waiting) {
-	labcomm_lock_notify(e->lock);
-      }
-    } labcomm_lock_release(e->lock);
-  }
-}
-
-int labcomm_internal_encoder_register(
-  struct labcomm_encoder *encoder,
-  struct labcomm_signature *signature,
-  labcomm_encoder_function encode)
-{
-  int result = -EINVAL;
-  struct labcomm_encoder *e;
-  int index;
-
-  e = enter_encoder(encoder);
-  index = get_encoder_index(e, signature);
-  if (signature->type == LABCOMM_SAMPLE) {
-    if (index > 0) {
-      int *registered = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, e->registered, 
-						    int, index);
-      if (! *registered) {
-	int err;
-	
-	*registered = 1;	
-	err = labcomm_writer_start(e->writer, e->writer->action_context, 
-				   index, signature, NULL);
-	if (err == -EALREADY) {
-	  result = 0;
-	} else if (err != 0) {
-	  result = err;
-	} else if (err == 0) {
-	  int i;
-
-	  labcomm_write_packed32(e->writer, signature->type);
-	  labcomm_write_packed32(e->writer, index);
-	  labcomm_write_string(e->writer, signature->name);
-	  for (i = 0 ; i < signature->size ; i++) {
-	    if (e->writer->pos >= e->writer->count) {
-	      labcomm_writer_flush(e->writer, e->writer->action_context);
-	    }
-	    e->writer->data[e->writer->pos] = signature->signature[i];
-	    e->writer->pos++;
-	  }
-	  labcomm_writer_end(e->writer, e->writer->action_context);
-	  result = e->writer->error;
-	}
-      }
-    }
-  }
-  leave_encoder(encoder);
-  return result;
-}
-
-int labcomm_internal_encode(
-  struct labcomm_encoder *encoder,
-  struct labcomm_signature *signature,
-  labcomm_encoder_function encode,
-  void *value)
-{
-  int result;
-  struct labcomm_encoder *e;
-  int index;
-
-  e = enter_encoder(encoder);
-  index = get_encoder_index(e, signature);
-  result = labcomm_writer_start(e->writer, e->writer->action_context, 
-				index, signature, value);
-  if (result == -EALREADY) { result = 0; goto no_end; }
-  if (result != 0) { goto out; }
-  result = labcomm_write_packed32(e->writer, index);
-  if (result != 0) { goto out; }
-  result = encode(e->writer, value);
-out:
-  labcomm_writer_end(e->writer, e->writer->action_context);
-no_end:
-  leave_encoder(encoder);
-  return result;
-}
-
-void labcomm_encoder_free(struct labcomm_encoder* e)
-{
-  struct labcomm_encoder_context *context;
-  struct labcomm_memory * memory = e->memory;
-
-  context = (struct labcomm_encoder_context *) e->context;
-  labcomm_writer_free(e->writer, e->writer->action_context);
-  LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, e->registered, int);
-
-#ifdef LABCOMM_ENCODER_LINEAR_SEARCH
-  struct labcomm_sample_entry *entry = context->sample;
-  struct labcomm_sample_entry *entry_next;
-  while (entry != NULL) {
-    entry_next = entry->next;
-    labcomm_memory_free(memory, 0, entry);
-    entry = entry_next;
-  }
-#else
-  labcomm_memory_free(memory, 0, context->by_section);
-#endif
-  labcomm_memory_free(memory, 0, e->context);
-  labcomm_memory_free(memory, 0, e);
-}
-
-int labcomm_encoder_ioctl(struct labcomm_encoder *encoder, 
-			  uint32_t action,
-			  ...)
-{
-  int result;
-  va_list va;
-    
-  if (LABCOMM_IOC_SIG(action) != LABCOMM_IOC_NOSIG) {
-    result = -EINVAL;
-    goto out;
-  }
-    
-  va_start(va, action);
-  result = labcomm_writer_ioctl(encoder->writer, 
-			       encoder->writer->action_context,
-			       0, NULL, action, va);
-  va_end(va);
-
-out:
-  return result;
-}
-
-static int writer_ioctl(struct labcomm_writer *writer,
-			uint32_t action,
-			...)
-{
-  int result;
-  va_list va;
-
-  if (LABCOMM_IOC_SIG(action) != LABCOMM_IOC_NOSIG) {
-    result = -EINVAL;
-    goto out;
-  }
-  
-  va_start(va, action);
-  result = labcomm_writer_ioctl(writer, writer->action_context, 
-				0, NULL, action, va);
-  va_end(va);
-out:
-  return result;
-}
-
-int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder, 
-				   struct labcomm_signature *signature,
-				   uint32_t action, va_list va)
-{
-  int result = -ENOTSUP;
-  
-  result = labcomm_writer_ioctl(encoder->writer, 
-				encoder->writer->action_context, 
-				-1, signature, action, va);
-  return result;
-}
-
-static void collect_flat_signature(
-  struct labcomm_decoder *decoder,
-  struct labcomm_writer *writer)
-{
-  int type = labcomm_read_packed32(decoder->reader); 
-  if (type >= LABCOMM_USER) {
-    decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3,
-			"Implement %s ... (1) for type 0x%x\n", __FUNCTION__, type);
-  } else {
-    labcomm_write_packed32(writer, type); 
-    switch (type) {
-      case LABCOMM_ARRAY: {
-	int dimensions, i;
-
-	dimensions = labcomm_read_packed32(decoder->reader);
-	labcomm_write_packed32(writer, dimensions);
-	for (i = 0 ; i < dimensions ; i++) {
-	  int n = labcomm_read_packed32(decoder->reader);
-	  labcomm_write_packed32(writer, n);
-	}
-	collect_flat_signature(decoder, writer);
-      } break;
-      case LABCOMM_STRUCT: {
-	int fields, i;
-
-	fields = labcomm_read_packed32(decoder->reader); 
-	labcomm_write_packed32(writer, fields); 
-	for (i = 0 ; i < fields ; i++) {
-	  char *name = labcomm_read_string(decoder->reader);
-	  labcomm_write_string(writer, name);
-	  labcomm_memory_free(decoder->memory, 1, name);
-	  collect_flat_signature(decoder, writer);
-	}
-      } break;
-      case LABCOMM_BOOLEAN:
-      case LABCOMM_BYTE:
-      case LABCOMM_SHORT:
-      case LABCOMM_INT:
-      case LABCOMM_LONG:
-      case LABCOMM_FLOAT:
-      case LABCOMM_DOUBLE:
-      case LABCOMM_STRING: {
-      } break;
-      default: {
-        decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3,
-				"Implement %s (2) for type 0x%x...\n", __FUNCTION__, type);
-      } break;
-    }
-  }
-}
-
-struct labcomm_decoder *labcomm_decoder_new(
-  struct labcomm_reader *reader,
-  struct labcomm_lock *lock,
-  struct labcomm_memory *memory)
-{
-  struct labcomm_decoder *result;
-
-  result = labcomm_memory_alloc(memory, 0, sizeof(*result));
-  if (result) {
-    struct labcomm_decoder_context *context;
-
-    context = labcomm_memory_alloc(memory, 0, sizeof(*context));
-    context->sample = 0;
-    result->context = context;
-    result->reader = reader;
-    result->reader->decoder = result;
-    result->reader->data = 0;
-    result->reader->data_size = 0;
-    result->reader->count = 0;
-    result->reader->pos = 0;
-    result->reader->error = 0;
-    result->lock = lock;
-    result->memory = memory;
-    result->on_error = on_error_fprintf;
-    result->on_new_datatype = on_new_datatype;
-    LABCOMM_SIGNATURE_ARRAY_INIT(result->local_to_remote, int);
-    LABCOMM_SIGNATURE_ARRAY_INIT(result->remote_to_local, int);
-  }
-  return result;
-}
-
-int labcomm_internal_decoder_register(
-  struct labcomm_decoder *d,
-  struct labcomm_signature *signature,
-  labcomm_decoder_function type_decoder,
-  labcomm_handler_function handler,
-  void *handler_context)
-{
-  struct labcomm_decoder_context *context = d->context;
-  int index;
-  
-  index = get_local_index(signature);
-  if (index >= 0) {
-    struct labcomm_sample_entry *sample;
-
-    labcomm_reader_start(d->reader, d->reader->action_context,
-			 index, signature,
-			 NULL);
-    labcomm_reader_end(d->reader, d->reader->action_context);
-    sample = get_sample_by_signature_address(context->sample,
-					     signature);
-    if (!sample) {
-      sample = labcomm_memory_alloc(d->memory, 0, sizeof(*sample));
-      sample->next = context->sample;
-      context->sample = sample;
-      sample->index = 0;
-      sample->signature = signature;
-    }
-    sample->decoder = type_decoder;
-    sample->handler = handler;
-    sample->context = handler_context;
-  }
-  return 0;
-}
-
-static int decode_typedef_or_sample(struct labcomm_decoder *d, int kind)
-{
-  int result;
-  struct labcomm_decoder_context *context = d->context;
-
-  /* TODO: should the labcomm_dynamic_buffer_writer be 
-     a permanent part of labcomm_decoder? */
-  struct labcomm_writer_action_context action_context = {
-    .next = NULL,
-    .action = labcomm_dynamic_buffer_writer_action,
-    .context = NULL
-  };
-  struct labcomm_writer writer = {
-    .action_context = &action_context,
-    .memory = d->memory,
-    .data = NULL,
-    .data_size = 0,
-    .count = 0,
-    .pos = 0,
-    .error = 0,
-  };
-  struct labcomm_signature signature;
-  struct labcomm_sample_entry *entry = NULL;
-  int remote_index, err;
-      
-  labcomm_writer_alloc(&writer, writer.action_context, NULL, "", NULL);
-  labcomm_writer_start(&writer, writer.action_context, 0, NULL, NULL);
-  remote_index = labcomm_read_packed32(d->reader); //int
-  signature.name = labcomm_read_string(d->reader);
-  signature.type = kind;
-  collect_flat_signature(d, &writer);
-  labcomm_writer_end(&writer, writer.action_context);
-  err = writer_ioctl(&writer, 
-		     LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN,
-		     &signature.size);
-  if (err < 0) {
-    printf("Failed to get size: %s\n", strerror(-err));
-    result = -ENOENT;
-    goto free_signature_name;
-  }
-  err = writer_ioctl(&writer, 
-		     LABCOMM_IOCTL_WRITER_GET_BYTE_POINTER,
-		     &signature.signature);
-  if (err < 0) {
-    printf("Failed to get pointer: %s\n", strerror(-err));
-    result = -ENOENT;
-    goto free_signature_name;
-  }
-  entry = get_sample_by_signature_value(context->sample, &signature);
-  if (! entry) {
-    /* Unknown datatype, bail out */
-    d->on_new_datatype(d, &signature);
-    result = -ENOENT;
-  } else if (entry->index && entry->index != remote_index) {
-    d->on_error(LABCOMM_ERROR_DEC_INDEX_MISMATCH, 5, 
-		"%s(): index mismatch '%s' (id=0x%x != 0x%x)\n", 
-		__FUNCTION__, signature.name, entry->index, remote_index);
-    result = -ENOENT;
-  } else {
-    int local_index;
-    int *local_to_remote, *remote_to_local;
-    // TODO unnessesary, since entry->index == index in above if statement
-    entry->index = remote_index;
-    local_index = get_local_index(entry->signature);
-    local_to_remote = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-						  d->local_to_remote, int,
-						  local_index);
-    *local_to_remote = remote_index;
-    remote_to_local = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-						  d->remote_to_local, int,
-						  remote_index);
-    *remote_to_local = local_index;
-    result = remote_index;
-  }
-free_signature_name:
-  labcomm_memory_free(d->memory, 0, signature.name);
-  labcomm_writer_free(&writer, writer.action_context);
-  if (!entry) {
-    // No handler for found type, bail out (after cleanup)
-    result = -ENOENT;
-  }
-  return result;
-}
-
-struct call_handler_context {
-  struct labcomm_sample_entry *entry;
-  struct labcomm_reader *reader;
-};
-
-static void call_handler(void *value, void *context)
-{
-  struct call_handler_context *wrap = context;
-
-  labcomm_reader_start(wrap->reader, wrap->reader->action_context,
-		       wrap->entry->index, wrap->entry->signature,
-		       value);
-  wrap->entry->handler(value, wrap->entry->context);
-  labcomm_reader_end(wrap->reader, wrap->reader->action_context);
-}
-
-int labcomm_decoder_decode_one(struct labcomm_decoder *d)
-{
-  int result, index;
-  struct labcomm_decoder_context *context = d->context;
-  
-  if (d->reader->data == NULL) {
-    result = labcomm_reader_alloc(d->reader, d->reader->action_context,
-				  d, LABCOMM_VERSION);
-    if (result <= 0) {
-      goto out;
-    }
-  }
-  index = labcomm_read_packed32(d->reader);
-  if (d->reader->error < 0) {
-    result = d->reader->error;
-    goto out;
-  }
-  if (index == LABCOMM_TYPEDEF || index == LABCOMM_SAMPLE) {
-    result = decode_typedef_or_sample(d, index); 
-  } else {
-    struct labcomm_sample_entry *entry;
-    
-    entry = get_sample_by_index(context->sample, index);
-    if (!entry) {
-      // printf("Error: %s: type not found (id=0x%x)\n",
-      //__FUNCTION__, result);
-      d->on_error(LABCOMM_ERROR_DEC_TYPE_NOT_FOUND, 3, 
-		  "%s(): type not found (id=0x%x)\n", 
-		  __FUNCTION__, index);
-      result = -ENOENT;
-    } else {
-      struct call_handler_context wrap = {
-	.entry = entry,
-	.reader = d->reader
-      };
-      entry->decoder(d->reader, call_handler, &wrap);
-      result = index;
-    }
-  }
-out:
-  return result;
-}
-
-void labcomm_decoder_run(struct labcomm_decoder *d)
-{
-  while (labcomm_decoder_decode_one(d) > 0) {
-  }
-}
-
-void labcomm_decoder_free(struct labcomm_decoder* d)
-{
-  struct labcomm_decoder_context *context = (struct labcomm_decoder_context *) d->context;
-  struct labcomm_sample_entry *entry = context->sample;
-  struct labcomm_sample_entry *entry_next;
-  struct labcomm_memory *memory = d->memory;
-
-  labcomm_reader_free(d->reader, d->reader->action_context);
-  LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->local_to_remote, int);
-  LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->remote_to_local, int);
-  while (entry != NULL) {
-    entry_next = entry->next;
-    labcomm_memory_free(memory, 0, entry);
-    entry = entry_next;
-  }
-
-  labcomm_memory_free(memory, 0, d->context);
-  labcomm_memory_free(memory, 0, d);
-}
-
-int labcomm_decoder_ioctl(struct labcomm_decoder *decoder, 
-			  uint32_t action,
-			  ...)
-{
-  int result;  
-  va_list va;
-    
-  va_start(va, action);
-  result = labcomm_reader_ioctl(decoder->reader, 
-				decoder->reader->action_context,
-				0, NULL, action, va);
-  va_end(va);
-  return result;
-}
-
-int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder, 
-				   struct labcomm_signature *signature,
-				   uint32_t action, va_list va)
-{
-  int result;
-  int local_index, *remote_index;
-
-  local_index = get_local_index(signature);
-  remote_index = LABCOMM_SIGNATURE_ARRAY_REF(decoder->memory,
-					     decoder->local_to_remote, int,
-					     local_index);
-  if (*remote_index == 0) {
-    result = -EAGAIN;
-  } else {
-    result = labcomm_reader_ioctl(decoder->reader, 
-				  decoder->reader->action_context,
-				  *remote_index, signature, 
-				  action, va);
-  }
-  return result;
-}
 
 #if 0
 static void dump(void *p, int size, int first, int last)
diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h
index e4d3fc8..12df1a2 100644
--- a/lib/c/labcomm.h
+++ b/lib/c/labcomm.h
@@ -26,7 +26,8 @@
 #include <stdarg.h>
 #include <stdint.h>
 #include <unistd.h>
-#include <labcomm_error.h>
+#include "labcomm_error.h"
+#include "labcomm_scheduler.h"
 
 /* Forward declaration */
 struct labcomm_encoder;
@@ -79,21 +80,6 @@ typedef int (*labcomm_handle_new_datatype_callback)(
 void labcomm_decoder_register_new_datatype_handler(struct labcomm_decoder *d,
 		labcomm_handle_new_datatype_callback on_new_datatype);
 
-/*
- * Locking support (optional), if not used only a single thread
- * may access an encoder or decoder at the same time.
- */
-struct labcomm_lock;
-
-int labcomm_lock_free(struct labcomm_lock *lock);
-int labcomm_lock_acquire(struct labcomm_lock *lock);
-int labcomm_lock_release(struct labcomm_lock *lock);
-int labcomm_lock_wait(struct labcomm_lock *lock, useconds_t usec);
-int labcomm_lock_notify(struct labcomm_lock *lock);
-int labcomm_lock_sleep_epoch(struct labcomm_lock *lock);
-int labcomm_lock_sleep_add(struct labcomm_lock *lock, useconds_t usec);
-int labcomm_lock_sleep(struct labcomm_lock *lock);
-
 /*
  * Dynamic memory handling
  *   lifetime == 0     memory that will live for as long as the 
@@ -109,8 +95,6 @@ void *labcomm_memory_realloc(struct labcomm_memory *m, int lifetime,
 			     void *ptr, size_t size);
 void labcomm_memory_free(struct labcomm_memory *m, int lifetime, void *ptr);
 
-extern struct labcomm_memory *labcomm_default_memory;
-
 /*
  * Decoder
  */
@@ -118,14 +102,15 @@ struct labcomm_reader;
 
 struct labcomm_decoder *labcomm_decoder_new(
   struct labcomm_reader *reader,
-  struct labcomm_lock *lock,
-  struct labcomm_memory *memory);
+  struct labcomm_error_handler *error,
+  struct labcomm_memory *memory,
+  struct labcomm_scheduler *scheduler);
+void labcomm_decoder_free(
+  struct labcomm_decoder *decoder);
 int labcomm_decoder_decode_one(
   struct labcomm_decoder *decoder);
 void labcomm_decoder_run(
   struct labcomm_decoder *decoder);
-void labcomm_decoder_free(
-  struct labcomm_decoder *decoder);
 
 /* See labcomm_ioctl.h for predefined ioctl_action values */
 int labcomm_decoder_ioctl(struct labcomm_decoder *decoder, 
@@ -139,8 +124,9 @@ struct labcomm_writer;
 
 struct labcomm_encoder *labcomm_encoder_new(
   struct labcomm_writer *writer,
-  struct labcomm_lock *lock,
-  struct labcomm_memory *memory);
+  struct labcomm_error_handler *error,
+  struct labcomm_memory *memory,
+  struct labcomm_scheduler *scheduler);
 void labcomm_encoder_free(
   struct labcomm_encoder *encoder);
 
diff --git a/lib/c/labcomm_decoder.c b/lib/c/labcomm_decoder.c
new file mode 100644
index 0000000..175a382
--- /dev/null
+++ b/lib/c/labcomm_decoder.c
@@ -0,0 +1,403 @@
+/*
+  labcomm_decoder.c -- runtime for handling decoding of labcomm samples.
+
+  Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This file is part of LabComm.
+
+  LabComm is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LabComm is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#define LABCOMM_VERSION "LabComm2013"
+
+#include <errno.h>
+#include "labcomm.h"
+#include "labcomm_private.h"
+#include "labcomm_signature.h"
+#include "labcomm_ioctl.h"
+#include "labcomm_dynamic_buffer_writer.h"
+
+struct sample_entry {
+  int remote_index;
+  struct labcomm_signature *signature;
+  labcomm_decoder_function decode;
+  labcomm_handler_function handler;
+  void *context;
+};
+
+struct labcomm_decoder {
+  struct labcomm_reader *reader;
+  struct labcomm_error_handler *error;
+  struct labcomm_memory *memory;
+  struct labcomm_scheduler *scheduler;
+  labcomm_error_handler_callback on_error;
+  labcomm_handle_new_datatype_callback on_new_datatype;
+  LABCOMM_SIGNATURE_ARRAY_DEF(local, struct sample_entry);
+  LABCOMM_SIGNATURE_ARRAY_DEF(remote_to_local, int);
+};
+
+struct labcomm_decoder *labcomm_decoder_new(
+  struct labcomm_reader *reader,
+  struct labcomm_error_handler *error,
+  struct labcomm_memory *memory,
+  struct labcomm_scheduler *scheduler)
+{
+  struct labcomm_decoder *result;
+
+  result = labcomm_memory_alloc(memory, 0, sizeof(*result));
+  if (result) {
+    result->reader = reader;
+    result->reader->decoder = result;
+    result->reader->data = 0;
+    result->reader->data_size = 0;
+    result->reader->count = 0;
+    result->reader->pos = 0;
+    result->reader->error = 0;
+    result->error = error;
+    result->memory = memory;
+    result->scheduler = scheduler;
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->local, struct sample_entry);
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->remote_to_local, int);
+  }
+  return result;
+}
+
+void labcomm_decoder_free(struct labcomm_decoder* d)
+{
+  struct labcomm_memory *memory = d->memory;
+
+  labcomm_reader_free(d->reader, d->reader->action_context);
+  LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->local, struct sample_entry);
+  LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->remote_to_local, int);
+  labcomm_memory_free(memory, 0, d);
+}
+
+static void collect_flat_signature(
+  struct labcomm_decoder *decoder,
+  struct labcomm_writer *writer)
+{
+  int type = labcomm_read_packed32(decoder->reader); 
+  if (type >= LABCOMM_USER) {
+    decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3,
+			"Implement %s ... (1) for type 0x%x\n", __FUNCTION__, type);
+  } else {
+    labcomm_write_packed32(writer, type); 
+    switch (type) {
+      case LABCOMM_ARRAY: {
+	int dimensions, i;
+
+	dimensions = labcomm_read_packed32(decoder->reader);
+	labcomm_write_packed32(writer, dimensions);
+	for (i = 0 ; i < dimensions ; i++) {
+	  int n = labcomm_read_packed32(decoder->reader);
+	  labcomm_write_packed32(writer, n);
+	}
+	collect_flat_signature(decoder, writer);
+      } break;
+      case LABCOMM_STRUCT: {
+	int fields, i;
+
+	fields = labcomm_read_packed32(decoder->reader); 
+	labcomm_write_packed32(writer, fields); 
+	for (i = 0 ; i < fields ; i++) {
+	  char *name = labcomm_read_string(decoder->reader);
+	  labcomm_write_string(writer, name);
+	  labcomm_memory_free(decoder->memory, 1, name);
+	  collect_flat_signature(decoder, writer);
+	}
+      } break;
+      case LABCOMM_BOOLEAN:
+      case LABCOMM_BYTE:
+      case LABCOMM_SHORT:
+      case LABCOMM_INT:
+      case LABCOMM_LONG:
+      case LABCOMM_FLOAT:
+      case LABCOMM_DOUBLE:
+      case LABCOMM_STRING: {
+      } break;
+      default: {
+        decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3,
+				"Implement %s (2) for type 0x%x...\n", __FUNCTION__, type);
+      } break;
+    }
+  }
+}
+
+static int writer_ioctl(struct labcomm_writer *writer,
+			uint32_t action,
+			...)
+{
+  int result;
+  va_list va;
+
+  if (LABCOMM_IOC_SIG(action) != LABCOMM_IOC_NOSIG) {
+    result = -EINVAL;
+    goto out;
+  }
+  
+  va_start(va, action);
+  result = labcomm_writer_ioctl(writer, writer->action_context, 
+				0, NULL, action, va);
+  va_end(va);
+out:
+  return result;
+}
+
+static int decode_typedef_or_sample(struct labcomm_decoder *d, int kind)
+{
+  int result;
+
+  /* TODO: should the labcomm_dynamic_buffer_writer be 
+     a permanent part of labcomm_decoder? */
+  struct labcomm_writer_action_context action_context = {
+    .next = NULL,
+    .action = labcomm_dynamic_buffer_writer_action,
+    .context = NULL
+  };
+  struct labcomm_writer writer = {
+    .action_context = &action_context,
+    .memory = d->memory,
+    .data = NULL,
+    .data_size = 0,
+    .count = 0,
+    .pos = 0,
+    .error = 0,
+  };
+  struct labcomm_signature signature;
+  int remote_index, err;
+      
+  labcomm_writer_alloc(&writer, writer.action_context, "");
+  labcomm_writer_start(&writer, writer.action_context, 0, NULL, NULL);
+  remote_index = labcomm_read_packed32(d->reader); //int
+  signature.name = labcomm_read_string(d->reader);
+  signature.type = kind;
+  collect_flat_signature(d, &writer);
+  labcomm_writer_end(&writer, writer.action_context);
+  err = writer_ioctl(&writer, 
+		     LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN,
+		     &signature.size);
+  if (err < 0) {
+    fprintf(stderr, "Failed to get size: %s\n", strerror(-err));
+    result = -ENOENT;
+    goto free_signature_name;
+  }
+  err = writer_ioctl(&writer, 
+		     LABCOMM_IOCTL_WRITER_GET_BYTE_POINTER,
+		     &signature.signature);
+  if (err < 0) {
+    fprintf(stderr, "Failed to get pointer: %s\n", strerror(-err));
+    result = -ENOENT;
+    goto free_signature_name;
+  }
+  {
+    int i;
+
+    labcomm_scheduler_data_lock(d->scheduler);
+    LABCOMM_SIGNATURE_ARRAY_FOREACH(d->local, struct sample_entry, i) {
+      struct sample_entry *s;
+      int *remote_to_local;
+      
+      result = -ENOENT;
+      s = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, 
+				      d->local,  struct sample_entry, i);
+      if (s->signature &&
+	  s->signature->type == signature.type &&
+	  s->signature->size == signature.size &&
+	  strcmp(s->signature->name, signature.name) == 0 &&
+	  bcmp((void*)s->signature->signature, (void*)signature.signature,
+	       signature.size) == 0) {
+	s->remote_index = remote_index;
+	remote_to_local = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
+						      d->remote_to_local, int,
+						      remote_index);
+	*remote_to_local = i;
+	result = remote_index;
+	break;
+      }
+    }
+    labcomm_scheduler_data_unlock(d->scheduler);
+  }
+#if 0
+  if (! entry) {
+    /* Unknown datatype, bail out */
+    d->on_new_datatype(d, &signature);
+    result = -ENOENT;
+  } else if (entry->index && entry->index != remote_index) {
+    d->on_error(LABCOMM_ERROR_DEC_INDEX_MISMATCH, 5, 
+		"%s(): index mismatch '%s' (id=0x%x != 0x%x)\n", 
+		__FUNCTION__, signature.name, entry->index, remote_index);
+    result = -ENOENT;
+#endif
+free_signature_name:
+  labcomm_memory_free(d->memory, 0, signature.name);
+  labcomm_writer_free(&writer, writer.action_context);
+  return result;
+}
+
+struct call_handler_context {
+  struct labcomm_reader *reader;
+  int local_index;
+  int remote_index;
+  struct labcomm_signature *signature;
+  labcomm_handler_function handler;
+  void *context;
+};
+
+static void call_handler(void *value, void *context)
+{
+  struct call_handler_context *wrap = context;
+
+  labcomm_reader_start(wrap->reader, wrap->reader->action_context,
+		       wrap->local_index, wrap->remote_index, wrap->signature,
+		       value);
+  wrap->handler(value, wrap->context);
+  labcomm_reader_end(wrap->reader, wrap->reader->action_context);
+}
+
+static void reader_alloc(struct labcomm_reader *reader)
+{
+  if (reader->data == NULL) {
+    labcomm_reader_alloc(reader, reader->action_context,
+			 LABCOMM_VERSION);
+  }
+}
+
+int labcomm_decoder_decode_one(struct labcomm_decoder *d)
+{
+  int result, remote_index;
+
+  reader_alloc(d->reader);
+  remote_index = labcomm_read_packed32(d->reader);
+  if (d->reader->error < 0) {
+    result = d->reader->error;
+    goto out;
+  }
+  if (remote_index == LABCOMM_TYPEDEF || remote_index == LABCOMM_SAMPLE) {
+    result = decode_typedef_or_sample(d, remote_index); 
+  } else {
+    int *local_index;
+    struct call_handler_context wrap = {
+      .reader = d->reader,
+      .remote_index = remote_index,
+      .signature = NULL,
+      .handler = NULL,
+      .context = NULL,
+    };
+    labcomm_decoder_function do_decode = NULL;
+
+    labcomm_scheduler_data_lock(d->scheduler);
+    local_index = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
+					      d->remote_to_local, int,
+					      remote_index);
+    if (*local_index != 0) {
+      struct sample_entry *entry;
+
+      entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
+					  d->local, struct sample_entry,
+					  *local_index);
+      wrap.local_index = *local_index;
+      wrap.signature = entry->signature;
+      wrap.handler = entry->handler;
+      wrap.context = entry->context;
+      do_decode = entry->decode;
+      result = *local_index;
+    }
+    labcomm_scheduler_data_unlock(d->scheduler);
+    if (do_decode) {
+      do_decode(d->reader, call_handler, &wrap);
+    } else {
+      result = -ENOENT;
+    }
+  }
+out:
+  return result;
+}
+
+void labcomm_decoder_run(struct labcomm_decoder *d)
+{
+  while (labcomm_decoder_decode_one(d) > 0) {
+  }
+}
+
+int labcomm_decoder_ioctl(struct labcomm_decoder *d, 
+			  uint32_t action,
+			  ...)
+{
+  int result;  
+  va_list va;
+    
+  va_start(va, action);
+  result = labcomm_reader_ioctl(d->reader, 
+				d->reader->action_context,
+				0, NULL, action, va);
+  va_end(va);
+  return result;
+}
+
+int labcomm_internal_decoder_ioctl(struct labcomm_decoder *d, 
+				   struct labcomm_signature *signature,
+				   uint32_t action, va_list va)
+{
+  int result;
+  int local_index, remote_index;
+
+  local_index = labcomm_signature_local_index(signature);
+  labcomm_scheduler_data_lock(d->scheduler);
+  remote_index = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
+					     d->local,
+					     struct sample_entry,
+					     local_index)->remote_index;
+  labcomm_scheduler_data_unlock(d->scheduler);
+  if (remote_index == 0) {
+    result = -EAGAIN;
+  } else {
+    result = labcomm_reader_ioctl(d->reader, d->reader->action_context,
+				  remote_index, signature, action, va);
+  }
+  return result;
+}
+
+int labcomm_internal_decoder_register(
+  struct labcomm_decoder *d,
+  struct labcomm_signature *signature,
+  labcomm_decoder_function decode, 
+  labcomm_handler_function handler,
+  void *context)
+{
+  int local_index;
+  struct sample_entry *entry;
+ 
+  reader_alloc(d->reader);
+  local_index = labcomm_signature_local_index(signature);
+  if (local_index <= 0) { goto out; }
+  labcomm_reader_start(d->reader, d->reader->action_context,
+		       local_index, 0, signature,
+		       NULL);
+  labcomm_reader_end(d->reader, d->reader->action_context);
+
+  labcomm_scheduler_data_lock(d->scheduler);
+  entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
+				      d->local, struct sample_entry,
+				      local_index);
+  if (entry == NULL) { local_index = -ENOMEM; goto unlock; }
+  entry->remote_index = 0;
+  entry->signature = signature;
+  entry->decode = decode;
+  entry->handler = handler;
+  entry->context = context;
+unlock:
+  labcomm_scheduler_data_unlock(d->scheduler);
+out:
+  return local_index;
+}
+
diff --git a/lib/c/labcomm_default_error_handler.c b/lib/c/labcomm_default_error_handler.c
new file mode 100644
index 0000000..61e04dd
--- /dev/null
+++ b/lib/c/labcomm_default_error_handler.c
@@ -0,0 +1,24 @@
+/*
+  test_default_error_handler.c -- LabComm default error handler
+
+  Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This file is part of LabComm.
+
+  LabComm is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LabComm is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "labcomm.h"
+
+struct labcomm_error_handler *labcomm_default_error_handler = NULL;
diff --git a/lib/c/labcomm_default_error_handler.h b/lib/c/labcomm_default_error_handler.h
new file mode 100644
index 0000000..4cd642a
--- /dev/null
+++ b/lib/c/labcomm_default_error_handler.h
@@ -0,0 +1,24 @@
+/*
+  test_default_error_handler.h -- LabComm default error handler
+
+  Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This file is part of LabComm.
+
+  LabComm is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LabComm is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "labcomm.h"
+
+extern struct labcomm_error_handler *labcomm_default_error_handler;
diff --git a/lib/c/labcomm_pthread_mutex_lock.h b/lib/c/labcomm_default_memory.h
similarity index 75%
rename from lib/c/labcomm_pthread_mutex_lock.h
rename to lib/c/labcomm_default_memory.h
index e67b16a..0911209 100644
--- a/lib/c/labcomm_pthread_mutex_lock.h
+++ b/lib/c/labcomm_default_memory.h
@@ -1,5 +1,5 @@
 /*
-  labcomm_pthread_mutex_lock.h -- a labcomm_lock on top of pthread_mutex.
+  test_default_memory.h -- LabComm default memory allocator
 
   Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -19,12 +19,9 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _LABCOMM_PTHREAD_MUTEX_LOCK_H_
-#define _LABCOMM_PTHREAD_MUTEX_LOCK_H_
-
+#include <stdlib.h>
 #include "labcomm.h"
+#include "labcomm_private.h"
 
-struct labcomm_lock *labcomm_pthread_mutex_lock_new(
-  struct labcomm_memory *memory);
+extern struct labcomm_memory *labcomm_default_memory;
 
-#endif
diff --git a/lib/c/labcomm_default_scheduler.c b/lib/c/labcomm_default_scheduler.c
new file mode 100644
index 0000000..cbc4640
--- /dev/null
+++ b/lib/c/labcomm_default_scheduler.c
@@ -0,0 +1,109 @@
+/*
+  test_default_scheduler.c -- LabComm default scheduler
+
+  Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This file is part of LabComm.
+
+  LabComm is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LabComm is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "labcomm_default_scheduler.h"
+#include "labcomm_scheduler.h"
+#include "labcomm_scheduler_private.h"
+
+static int scheduler_free(struct labcomm_scheduler *s)
+{
+  fprintf(stderr, "%s:%d %s %s", __FILE__, __LINE__, __FUNCTION__,
+	  "not implemented");
+  exit(1);
+  return 0;
+}
+ 
+static int scheduler_writer_lock(struct labcomm_scheduler *s)
+{
+  return 0;
+}
+ 
+static int scheduler_writer_unlock(struct labcomm_scheduler *s)
+{
+  return 0;
+}
+
+static int scheduler_data_lock(struct labcomm_scheduler *s)
+{
+  return 0;
+}
+ 
+static int scheduler_data_unlock(struct labcomm_scheduler *s)
+{
+  return 0;
+}
+
+static struct labcomm_time *scheduler_now(struct labcomm_scheduler *s)
+{
+  fprintf(stderr, "%s:%d %s %s", __FILE__, __LINE__, __FUNCTION__,
+	  "not implemented");
+  exit(1);
+  return NULL;
+}
+ 
+static int scheduler_sleep(struct labcomm_scheduler *s,
+			   struct labcomm_time *t)
+{
+  fprintf(stderr, "%s:%d %s %s", __FILE__, __LINE__, __FUNCTION__,
+	  "not implemented");
+  exit(1);
+  return 0;
+}
+
+static int scheduler_wakeup(struct labcomm_scheduler *s)
+{
+  fprintf(stderr, "%s:%d %s %s", __FILE__, __LINE__, __FUNCTION__,
+	  "not implemented");
+  exit(1);
+  return 0;
+}
+
+static int scheduler_enqueue(struct labcomm_scheduler *s,
+			     useconds_t delay,
+			     void (*deferred)(void *context),
+			     void *context)
+{
+  fprintf(stderr, "%s:%d %s %s", __FILE__, __LINE__, __FUNCTION__,
+	  "not implemented");
+  exit(1);
+  return 0;
+}
+
+static const struct labcomm_scheduler_action scheduler_action = {
+  .free = scheduler_free,
+  .writer_lock = scheduler_writer_lock,
+  .writer_unlock = scheduler_writer_unlock,
+  .data_lock = scheduler_data_lock,
+  .data_unlock = scheduler_data_unlock,
+  .now = scheduler_now,
+  .sleep = scheduler_sleep,
+  .wakeup = scheduler_wakeup,
+  .enqueue = scheduler_enqueue  
+};
+
+static struct labcomm_scheduler scheduler = {
+  .action = &scheduler_action,
+  .context = NULL
+};
+
+struct labcomm_scheduler *labcomm_default_scheduler = &scheduler;
diff --git a/lib/c/labcomm_default_scheduler.h b/lib/c/labcomm_default_scheduler.h
new file mode 100644
index 0000000..923ea20
--- /dev/null
+++ b/lib/c/labcomm_default_scheduler.h
@@ -0,0 +1,24 @@
+/*
+  test_default_scheduler.h -- LabComm default scheduler
+
+  Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This file is part of LabComm.
+
+  LabComm is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LabComm is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "labcomm.h"
+
+extern struct labcomm_scheduler *labcomm_default_scheduler;
diff --git a/lib/c/labcomm_dynamic_buffer_writer.c b/lib/c/labcomm_dynamic_buffer_writer.c
index fb61f23..3a7425d 100644
--- a/lib/c/labcomm_dynamic_buffer_writer.c
+++ b/lib/c/labcomm_dynamic_buffer_writer.c
@@ -29,9 +29,7 @@
 
 static int dyn_alloc(struct labcomm_writer *w, 
 		     struct labcomm_writer_action_context *action_context,
-		     struct labcomm_encoder *encoder,
-		     char *labcomm_version,
-		     labcomm_encoder_enqueue enqueue)
+		     char *labcomm_version)
 {
   w->data_size = 1000;
   w->count = w->data_size;
diff --git a/lib/c/labcomm_encoder.c b/lib/c/labcomm_encoder.c
new file mode 100644
index 0000000..ba02ff1
--- /dev/null
+++ b/lib/c/labcomm_encoder.c
@@ -0,0 +1,222 @@
+/*
+  labcomm_encoder.c -- handling encoding of labcomm samples.
+
+  Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This file is part of LabComm.
+
+  LabComm is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LabComm is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#define LABCOMM_VERSION "LabComm2013"
+
+#include <errno.h>
+#include "labcomm.h"
+#include "labcomm_signature.h"
+#include "labcomm_private.h"
+#include "labcomm_ioctl.h"
+
+struct labcomm_encoder {
+  struct labcomm_writer *writer;
+  struct labcomm_error_handler *error;
+  struct labcomm_memory *memory;
+  struct labcomm_scheduler *scheduler;
+  LABCOMM_SIGNATURE_ARRAY_DEF(registered, int);
+};
+
+struct labcomm_encoder *labcomm_encoder_new(
+  struct labcomm_writer *writer,
+  struct labcomm_error_handler *error,
+  struct labcomm_memory *memory,
+  struct labcomm_scheduler *scheduler)
+{
+  struct labcomm_encoder *result;
+
+  result = labcomm_memory_alloc(memory, 0, sizeof(*result));
+  if (result) {
+    result->writer = writer;
+    result->writer->encoder = result;
+    result->writer->data = NULL;
+    result->writer->data_size = 0;
+    result->writer->count = 0;
+    result->writer->pos = 0;
+    result->writer->error = 0;
+    result->error = error;
+    result->memory = memory;
+    result->scheduler = scheduler;
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->registered, int);
+  }
+  return result;
+}
+
+void labcomm_encoder_free(struct labcomm_encoder* e)
+{
+  struct labcomm_memory *memory = e->memory;
+
+  labcomm_writer_free(e->writer, e->writer->action_context);
+  LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, e->registered, int);
+  labcomm_memory_free(memory, 0, e);
+}
+
+int labcomm_internal_encoder_register(
+  struct labcomm_encoder *e,
+  struct labcomm_signature *signature,
+  labcomm_encoder_function encode)
+{
+  int result = -EINVAL;
+  int index, *done, err, i;
+
+  index = labcomm_signature_local_index(signature);
+  labcomm_scheduler_writer_lock(e->scheduler);
+  if (e->writer->data == NULL) {
+    labcomm_writer_alloc(e->writer,e->writer->action_context, LABCOMM_VERSION);
+  }
+  if (signature->type != LABCOMM_SAMPLE) { goto out; }
+  if (index <= 0) { goto out; }
+  done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, e->registered, int, index);
+  if (*done) { goto out; }
+  *done = 1;	
+  err = labcomm_writer_start(e->writer, e->writer->action_context, 
+			     index, signature, NULL);
+  if (err == -EALREADY) { result = 0; goto out; }
+  if (err != 0) { result = err; goto out; }
+  labcomm_write_packed32(e->writer, signature->type);
+  labcomm_write_packed32(e->writer, index);
+  labcomm_write_string(e->writer, signature->name);
+  for (i = 0 ; i < signature->size ; i++) {
+    if (e->writer->pos >= e->writer->count) {
+      labcomm_writer_flush(e->writer, e->writer->action_context);
+    }
+    e->writer->data[e->writer->pos] = signature->signature[i];
+    e->writer->pos++;
+  }
+  labcomm_writer_end(e->writer, e->writer->action_context);
+  result = e->writer->error;
+out:
+  labcomm_scheduler_writer_unlock(e->scheduler);
+  return result;
+}
+
+int labcomm_internal_encode(
+  struct labcomm_encoder *e,
+  struct labcomm_signature *signature,
+  labcomm_encoder_function encode,
+  void *value)
+{
+  int result;
+  int index;
+
+  index = labcomm_signature_local_index(signature);
+  labcomm_scheduler_writer_lock(e->scheduler);
+  if (e->writer->data == NULL) {
+    labcomm_writer_alloc(e->writer,e->writer->action_context, LABCOMM_VERSION);
+  }
+  result = labcomm_writer_start(e->writer, e->writer->action_context, 
+				index, signature, value);
+  if (result == -EALREADY) { result = 0; goto no_end; }
+  if (result != 0) { goto out; }
+  result = labcomm_write_packed32(e->writer, index);
+  if (result != 0) { goto out; }
+  result = encode(e->writer, value);
+out:
+  labcomm_writer_end(e->writer, e->writer->action_context);
+no_end:
+  labcomm_scheduler_writer_unlock(e->scheduler);
+  return result;
+}
+
+int labcomm_encoder_ioctl(struct labcomm_encoder *encoder, 
+			  uint32_t action,
+			  ...)
+{
+  int result;
+  va_list va;
+  
+  if (LABCOMM_IOC_SIG(action) != LABCOMM_IOC_NOSIG) {
+    result = -EINVAL;
+    goto out;
+  }
+  
+  va_start(va, action);
+  result = labcomm_writer_ioctl(encoder->writer, 
+			       encoder->writer->action_context,
+			       0, NULL, action, va);
+  va_end(va);
+
+out:
+  return result;
+}
+
+int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder, 
+				   struct labcomm_signature *signature,
+				   uint32_t action, va_list va)
+{
+  int result = -ENOTSUP;
+  
+  result = labcomm_writer_ioctl(encoder->writer, 
+				encoder->writer->action_context, 
+				-1, signature, action, va);
+  return result;
+}
+
+
+
+#if 0
+static struct labcomm_encoder *enter_encoder(struct labcomm_encoder *e)
+{
+  if (e->is_deferred) {
+    return e->is_deferred;
+  } else {
+    labcomm_lock_acquire(e->lock); 
+    e->waiting++;
+    while (e->busy) { labcomm_lock_wait(e->lock, 10000000); }
+    e->busy = 1;
+    labcomm_lock_release(e->lock);
+    
+    if (e->writer->data == NULL) {
+      labcomm_writer_alloc(e->writer,e->writer->action_context,
+			   e, LABCOMM_VERSION, encoder_enqueue_action);
+      if (e->alloc_action) {
+	struct labcomm_encoder deferred;
+	struct encoder_alloc_action *p;
+
+	deferred.is_deferred = e;
+	p = e->alloc_action;
+	e->alloc_action = NULL;
+	while (p) {
+	  struct encoder_alloc_action *tmp;
+
+	  p->action(&deferred, p->context);
+	  tmp = p;
+	  p = p->next;
+	  labcomm_memory_free(e->memory, 1, tmp);
+	}
+      }
+    }
+  }
+  return e;
+}
+static void leave_encoder(struct labcomm_encoder *e)
+{
+  if (!e->is_deferred) {
+    labcomm_lock_acquire(e->lock); {
+      e->busy = 0;
+      e->waiting--;
+      if (e->waiting) {
+	labcomm_lock_notify(e->lock);
+      }
+    } labcomm_lock_release(e->lock);
+  }
+}
+
+#endif
diff --git a/lib/c/labcomm_error.h b/lib/c/labcomm_error.h
index 79f4647..d83cd61 100644
--- a/lib/c/labcomm_error.h
+++ b/lib/c/labcomm_error.h
@@ -7,6 +7,8 @@ enum labcomm_error {
 #undef LABCOMM_ERROR
 };
 
+struct labcomm_error_handler;
+
 #endif
 
 #ifdef LABCOMM_ERROR
diff --git a/lib/c/labcomm_fd_reader.c b/lib/c/labcomm_fd_reader.c
index 6cae2ae..e397c84 100644
--- a/lib/c/labcomm_fd_reader.c
+++ b/lib/c/labcomm_fd_reader.c
@@ -37,7 +37,6 @@ struct labcomm_fd_reader {
 
 static int fd_alloc(struct labcomm_reader *r,
 		    struct labcomm_reader_action_context *action_context, 
-		    struct labcomm_decoder *decoder,
 		    char *version)
 {
   int result = 0;
diff --git a/lib/c/labcomm_fd_writer.c b/lib/c/labcomm_fd_writer.c
index d21e047..acf6934 100644
--- a/lib/c/labcomm_fd_writer.c
+++ b/lib/c/labcomm_fd_writer.c
@@ -41,9 +41,7 @@ static int fd_flush(struct labcomm_writer *w,
 
 static int fd_alloc(struct labcomm_writer *w, 
 		    struct labcomm_writer_action_context *action_context, 
-		    struct labcomm_encoder *encoder,
-		    char *version,
-		    labcomm_encoder_enqueue enqueue)
+		    char *version)
 {
   w->data = labcomm_memory_alloc(w->memory, 0, BUFFER_SIZE);
   if (! w->data) {
diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h
index a19ec2a..e953f02 100644
--- a/lib/c/labcomm_private.h
+++ b/lib/c/labcomm_private.h
@@ -67,25 +67,6 @@
 #define LABCOMM_DECLARE_SIGNATURE(name) \
   struct labcomm_signature __attribute__((section("labcomm"),aligned(1))) name 
 
-/*
- * Semi private lock declarations
- */
-struct labcomm_lock;
-
-struct labcomm_lock_action {
-  int (*free)(struct labcomm_lock *lock);
-  int (*acquire)(struct labcomm_lock *lock);
-  int (*release)(struct labcomm_lock *lock);
-  int (*wait)(struct labcomm_lock *lock, useconds_t usec);
-  int (*notify)(struct labcomm_lock *lock);
-};
-
-struct labcomm_lock {
-  const struct labcomm_lock_action *action;
-  struct labcomm_memory *memory;
-  void *context;
-};
-
 /*
  * Semi private dynamic memory declarations
  */
@@ -122,7 +103,7 @@ struct labcomm_reader_action {
   */
   int (*alloc)(struct labcomm_reader *r, 
 	       struct labcomm_reader_action_context *action_context, 
-	       struct labcomm_decoder *decoder, char *labcomm_version);
+	       char *labcomm_version);
   /* 'free' returns the resources claimed by 'alloc' and might have other
      reader specific side-effects as well.
 
@@ -137,7 +118,8 @@ struct labcomm_reader_action {
    */
   int (*start)(struct labcomm_reader *r, 
 	       struct labcomm_reader_action_context *action_context,
-	       int index, struct labcomm_signature *signature,
+	       int local_index, int remote_index,
+	       struct labcomm_signature *signature,
 	       void *value);
   int (*end)(struct labcomm_reader *r, 
 	     struct labcomm_reader_action_context *action_context);
@@ -169,13 +151,13 @@ struct labcomm_reader {
 
 int labcomm_reader_alloc(struct labcomm_reader *r, 
 			 struct labcomm_reader_action_context *action_context, 
-			 struct labcomm_decoder *decoder, 
 			 char *labcomm_version);
 int labcomm_reader_free(struct labcomm_reader *r, 
 			struct labcomm_reader_action_context *action_context);
 int labcomm_reader_start(struct labcomm_reader *r, 
 			 struct labcomm_reader_action_context *action_context,
-			 int index, struct labcomm_signature *signature,
+			 int local_index, int remote_index,
+			 struct labcomm_signature *signature,
 			 void *value);
 int labcomm_reader_end(struct labcomm_reader *r, 
 		       struct labcomm_reader_action_context *action_context);
@@ -286,21 +268,14 @@ static inline char *labcomm_read_string(struct labcomm_reader *r)
 /*
  * Semi private encoder declarations
  */
-typedef int (*labcomm_encoder_function)(
-  struct labcomm_writer *,
-  void *value);
-typedef int (*labcomm_encoder_enqueue)(
-  struct labcomm_encoder *encoder, 
-  void (*action)(struct labcomm_encoder *encoder, 
-		 void *context),
-  void *context);
+typedef int (*labcomm_encoder_function)(struct labcomm_writer *,
+					void *value);
 struct labcomm_writer_action_context;
 
 struct labcomm_writer_action {
   int (*alloc)(struct labcomm_writer *w, 
 	       struct labcomm_writer_action_context *action_context, 
-	       struct labcomm_encoder *encoder, char *labcomm_version,
-	       labcomm_encoder_enqueue enqueue);
+	       char *labcomm_version);
   int (*free)(struct labcomm_writer *w, 
 	      struct labcomm_writer_action_context *action_context);
   /* 'start' is called right before a sample is to be sent. In the 
@@ -346,9 +321,7 @@ struct labcomm_writer {
 
 int labcomm_writer_alloc(struct labcomm_writer *w, 
 			 struct labcomm_writer_action_context *action_context, 
-			 struct labcomm_encoder *encoder, 
-			 char *labcomm_version,
-			 labcomm_encoder_enqueue enqueue);
+			 char *labcomm_version);
 int labcomm_writer_free(struct labcomm_writer *w, 
 			struct labcomm_writer_action_context *action_context);
 int labcomm_writer_start(struct labcomm_writer *w, 
diff --git a/lib/c/labcomm_pthread_mutex_lock.c b/lib/c/labcomm_pthread_mutex_lock.c
deleted file mode 100644
index 548a3e6..0000000
--- a/lib/c/labcomm_pthread_mutex_lock.c
+++ /dev/null
@@ -1,114 +0,0 @@
-#include <errno.h>
-#include <pthread.h>
-#include "labcomm.h"
-#include "labcomm_private.h"
-
-struct labcomm_pthread_mutex_lock {
-  struct labcomm_lock lock;
-  
-  pthread_mutex_t mutex;
-  pthread_cond_t cond;
-};
-
-int do_free(struct labcomm_lock *l)
-{
-  struct labcomm_pthread_mutex_lock *lock = l->context;
-  struct labcomm_memory *memory = l->memory; 
- 
-  pthread_cond_destroy(&lock->cond);
-  pthread_mutex_destroy(&lock->mutex);
-  labcomm_memory_free(memory, 0, lock);
-  return 0;
-}
-
-int do_acquire(struct labcomm_lock *l)
-{
-  struct labcomm_pthread_mutex_lock *lock = l->context;
-  
-  if (pthread_mutex_lock(&lock->mutex) != 0) {
-    return -errno;
-  }
-  return 0;
-}
-
-int do_release(struct labcomm_lock *l)
-{
-  struct labcomm_pthread_mutex_lock *lock = l->context;
-  
-  if (pthread_mutex_unlock(&lock->mutex) != 0) {
-    return -errno;
-  }
-  return 0;
-}
-
-int do_wait(struct labcomm_lock *l, useconds_t usec)
-{
-  struct labcomm_pthread_mutex_lock *lock = l->context;
-  
-  if (usec <= 0) {
-    if (pthread_cond_wait(&lock->cond, &lock->mutex) != 0) {
-      return -errno;
-    }
-  } else {
-    struct timespec abstime;
-    time_t sec = usec / 1000000;
-    long nsec = (usec % 1000000) * 1000;
-
-    clock_gettime(CLOCK_REALTIME, &abstime);
-    abstime.tv_nsec += nsec;
-    abstime.tv_sec += sec + abstime.tv_nsec / 1000000000;
-    abstime.tv_nsec %= 1000000000;
-    if (pthread_cond_timedwait(&lock->cond, &lock->mutex, &abstime) != 0) {
-      return -errno;
-    }
-  }
-  return 0;
-}
-
-int do_notify(struct labcomm_lock *l)
-{
-  struct labcomm_pthread_mutex_lock *lock = l->context;
-  if (pthread_cond_broadcast(&lock->cond) != 0) {
-    return -errno;
-  }
-  return 0;
-}
-
-static struct labcomm_lock_action action = {
-  .free = do_free,
-  .acquire = do_acquire,
-  .release = do_release,
-  .wait = do_wait,
-  .notify = do_notify
-};
-
-struct labcomm_lock *labcomm_pthread_mutex_lock_new(
-  struct labcomm_memory *memory)
-{
-  struct labcomm_lock *result = NULL;
-  struct labcomm_pthread_mutex_lock *lock;
-
-  lock = labcomm_memory_alloc(memory, 0, sizeof(*lock));
-  if (lock == NULL) {
-    goto out;
-  }
-  if (pthread_mutex_init(&lock->mutex, NULL) != 0) {
-    goto free_lock;
-  }
-  if (pthread_cond_init(&lock->cond, NULL) != 0) {
-    goto destroy_mutex;
-  }
-  lock->lock.memory = memory;
-  lock->lock.action = &action;
-  lock->lock.context = lock;
-  result = &lock->lock;
-  goto out;
-destroy_mutex:
-  pthread_mutex_destroy(&lock->mutex);
-free_lock:
-  labcomm_memory_free(memory, 0, lock);
-out:
-  return result;
-
-}
-
diff --git a/lib/c/labcomm_pthread_scheduler.c b/lib/c/labcomm_pthread_scheduler.c
index 8092367..52ebed5 100644
--- a/lib/c/labcomm_pthread_scheduler.c
+++ b/lib/c/labcomm_pthread_scheduler.c
@@ -324,7 +324,7 @@ out:
   return result;
 }
 
-const struct labcomm_scheduler_action scheduler_action = {
+static const struct labcomm_scheduler_action scheduler_action = {
   .free = scheduler_free,
   .writer_lock = scheduler_writer_lock,
   .writer_unlock = scheduler_writer_unlock,
diff --git a/lib/c/labcomm_signature.h b/lib/c/labcomm_signature.h
new file mode 100644
index 0000000..d68c579
--- /dev/null
+++ b/lib/c/labcomm_signature.h
@@ -0,0 +1,23 @@
+/*
+  labcomm_signature.h -- signature handling.
+
+  Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This file is part of LabComm.
+
+  LabComm is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LabComm is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "labcomm.h"
+int labcomm_signature_local_index(struct labcomm_signature *s);
diff --git a/lib/c/labcomm_signature_gnu_ld_tricks.c b/lib/c/labcomm_signature_gnu_ld_tricks.c
new file mode 100644
index 0000000..7ce21ee
--- /dev/null
+++ b/lib/c/labcomm_signature_gnu_ld_tricks.c
@@ -0,0 +1,38 @@
+/*
+  labcomm_signature_gnu_ld_tricks.h -- signature handling.
+
+  Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This file is part of LabComm.
+
+  LabComm is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LabComm is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <errno.h>
+#include "labcomm.h"
+#include "labcomm_signature.h"
+#include "labcomm_private.h"
+
+extern struct labcomm_signature labcomm_first_signature;
+extern struct labcomm_signature labcomm_last_signature;
+
+int labcomm_signature_local_index(struct labcomm_signature *s)
+{
+  int result = -ENOENT;
+  
+  if (&labcomm_first_signature <= s && s < &labcomm_last_signature) {
+    result = (int)(s - &labcomm_first_signature) + LABCOMM_USER;
+  }
+  return result;
+}
diff --git a/lib/c/test/test_labcomm_generated_encoding.c b/lib/c/test/test_labcomm_generated_encoding.c
index bf81d0b..79aeb43 100644
--- a/lib/c/test/test_labcomm_generated_encoding.c
+++ b/lib/c/test/test_labcomm_generated_encoding.c
@@ -24,6 +24,9 @@
 #include <string.h>
 #include <errno.h>
 #include "labcomm_private.h"
+#include "labcomm_default_error_handler.h"
+#include "labcomm_default_memory.h"
+#include "labcomm_pthread_scheduler.h"
 #include "test/gen/generated_encoding.h"
 
 #define IOCTL_WRITER_ASSERT_BYTES 4096
@@ -35,9 +38,7 @@ struct labcomm_writer *writer;
 static int buf_writer_alloc(
   struct labcomm_writer *w, 
   struct labcomm_writer_action_context *action_context,
-  struct labcomm_encoder *encoder,
-  char *labcomm_version,
-  labcomm_encoder_enqueue enqueue)
+  char *labcomm_version)
 {
   writer = w; /* Hack */
   w->data_size = sizeof(buffer);
@@ -181,9 +182,11 @@ int main(void)
   generated_encoding_V V;
   generated_encoding_B B = 1;
 
-  struct labcomm_encoder *encoder = labcomm_encoder_new(&buffer_writer, 
-							NULL,
-							labcomm_default_memory);
+  struct labcomm_encoder *encoder = labcomm_encoder_new(
+    &buffer_writer, 
+    labcomm_default_error_handler,
+    labcomm_default_memory,
+    labcomm_pthread_scheduler_new(labcomm_default_memory));
 
   labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
   labcomm_encoder_register_generated_encoding_V(encoder);
diff --git a/lib/c/test/test_labcomm_pthread_scheduler.c b/lib/c/test/test_labcomm_pthread_scheduler.c
index 2070967..718293d 100644
--- a/lib/c/test/test_labcomm_pthread_scheduler.c
+++ b/lib/c/test/test_labcomm_pthread_scheduler.c
@@ -22,9 +22,11 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include "labcomm_default_memory.h"
 #include "labcomm_scheduler.h"
 #include "labcomm_pthread_scheduler.h"
 
+#define TICK 100000
 struct func_arg {
   struct labcomm_scheduler *scheduler;
   int i;
@@ -50,7 +52,7 @@ void enqueue(struct labcomm_scheduler *scheduler,
     
     tmp->scheduler = scheduler;
     tmp->i = i;
-    labcomm_scheduler_enqueue(scheduler, i*1000000, func, tmp);
+    labcomm_scheduler_enqueue(scheduler, i*TICK, func, tmp);
   }
 }
 
@@ -69,10 +71,10 @@ int main(int argc, char *argv[])
     
     tmp->scheduler = scheduler;
     tmp->i = 999;
-    labcomm_scheduler_enqueue(scheduler, 6000000, func, tmp);
+    labcomm_scheduler_enqueue(scheduler, 6*TICK, func, tmp);
   }
   time = labcomm_scheduler_now(scheduler);
-  labcomm_time_add_usec(time, 12*1000000);
+  labcomm_time_add_usec(time, 12*TICK);
   labcomm_scheduler_sleep(scheduler, NULL);
   labcomm_scheduler_sleep(scheduler, time);
 
diff --git a/test/relay_gen_c.py b/test/relay_gen_c.py
index 30a081a..6f4da2c 100755
--- a/test/relay_gen_c.py
+++ b/test/relay_gen_c.py
@@ -27,6 +27,9 @@ if __name__ == '__main__':
       |#include <sys/stat.h>
       |#include <fcntl.h>
       |#include <labcomm.h>
+      |#include <labcomm_default_error_handler.h>
+      |#include <labcomm_default_memory.h>
+      |#include <labcomm_default_scheduler.h>
       |#include <labcomm_fd_reader.h>
       |#include <labcomm_fd_writer.h>
       |#include "c_code.h"
@@ -52,10 +55,14 @@ if __name__ == '__main__':
       |  if (out < 0) { return 1; }
       |  e = labcomm_encoder_new(labcomm_fd_writer_new(
       |                              labcomm_default_memory, out, 1), 
-      |                           NULL, labcomm_default_memory);
+      |                           labcomm_default_error_handler,
+      |                           labcomm_default_memory,
+      |                           labcomm_default_scheduler);
       |  d = labcomm_decoder_new(labcomm_fd_reader_new(
-      |                               labcomm_default_memory, in, 1), 
-      |                          NULL, labcomm_default_memory);
+      |                              labcomm_default_memory, in, 1), 
+      |                           labcomm_default_error_handler,
+      |                           labcomm_default_memory,
+      |                           labcomm_default_scheduler);
     """))
     for func,arg in sample:
         result.extend(split_match('^[^|]*\|(.*)$', """
-- 
GitLab