diff --git a/examples/simple/example_decoder.c b/examples/simple/example_decoder.c
index c34e19b3b5d60c680ce21c928ed4510684886d95..4eac10df2f2146a3fc7174a460e79a6906ca6d00 100644
--- a/examples/simple/example_decoder.c
+++ b/examples/simple/example_decoder.c
@@ -56,7 +56,7 @@ int main(int argc, char *argv[]) {
   char *filename = argv[1];
   printf("C decoder reading from %s\n", filename);
   fd = open(filename, O_RDONLY);
-  decoder = labcomm_decoder_new(labcomm_fd_reader, &fd);
+  decoder = labcomm_decoder_new(labcomm_fd_reader, &fd, NULL, NULL);
   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 4a6e98b2e0d5a2212d995dfcde6b4d78eac00063..afb0cc2b28c5b292ff2bbb93d79ccbe56e8ee2bd 100644
--- a/examples/simple/example_encoder.c
+++ b/examples/simple/example_encoder.c
@@ -12,7 +12,7 @@ int main(int argc, char *argv[]) {
   char *filename = argv[1];
   printf("C encoder writing to %s\n", filename);
   fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644);
-  encoder = labcomm_encoder_new(labcomm_fd_writer, &fd);
+  encoder = labcomm_encoder_new(labcomm_fd_writer, &fd, NULL, NULL);
   labcomm_encoder_register_simple_theTwoInts(encoder);
   labcomm_encoder_register_simple_anotherTwoInts(encoder);
   labcomm_encoder_register_simple_IntString(encoder);
diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c
index c717a69606ff14cf82f4ea412c95bcb2ef1ed208..260b3c6748640be932a71addecb7ff3f22c3966c 100644
--- a/lib/c/labcomm.c
+++ b/lib/c/labcomm.c
@@ -381,8 +381,10 @@ no_end:
 }
 
 labcomm_encoder_t *labcomm_encoder_new(
-  const struct labcomm_writer_action action,
-  void *writer_context)
+  const struct labcomm_writer_action writer,
+  void *writer_context,
+  const struct labcomm_lock_action *lock,
+  void *lock_context)
 {
   labcomm_encoder_t *result = malloc(sizeof(labcomm_encoder_t));
   if (result) {
@@ -396,13 +398,15 @@ labcomm_encoder_t *labcomm_encoder_new(
     context->by_section = NULL;
 #endif
     result->context = context;
-    result->writer.context = writer_context;
     result->writer.data = 0;
     result->writer.data_size = 0;
     result->writer.count = 0;
     result->writer.pos = 0;
     result->writer.error = 0;
-    result->writer.action = action;
+    result->writer.action = writer;
+    result->writer.context = writer_context;
+    result->lock.action = lock;
+    result->lock.context = lock_context;
     result->writer.on_error = on_error_fprintf;
     result->do_register = do_encoder_register;
     result->do_encode = do_encode;
@@ -584,7 +588,7 @@ static int do_decode_one(labcomm_decoder_t *d)
 	/* TODO: should the labcomm_dynamic_buffer_writer be 
 	   a permanent part of labcomm_decoder? */
 	labcomm_encoder_t *e = labcomm_encoder_new(
-	  labcomm_dynamic_buffer_writer, NULL);
+	  labcomm_dynamic_buffer_writer, NULL, NULL, NULL);
 	labcomm_signature_t signature;
 	labcomm_sample_entry_t *entry = NULL;
 	int index, err;
@@ -650,8 +654,10 @@ static int do_decode_one(labcomm_decoder_t *d)
 }
 
 labcomm_decoder_t *labcomm_decoder_new(
-  const struct labcomm_reader_action action,
-  void *reader_context)
+  const struct labcomm_reader_action reader,
+  void *reader_context,
+  const struct labcomm_lock_action *lock,
+  void *lock_context)
 {
   labcomm_decoder_t *result = malloc(sizeof(labcomm_decoder_t));
   if (result) {
@@ -659,13 +665,15 @@ labcomm_decoder_t *labcomm_decoder_new(
       (labcomm_decoder_context_t*)malloc(sizeof(labcomm_decoder_context_t));
     context->sample = 0;
     result->context = context;
-    result->reader.context = reader_context;
     result->reader.data = 0;
     result->reader.data_size = 0;
     result->reader.count = 0;
     result->reader.pos = 0;
-    result->reader.action = action;
+    result->reader.action = reader;
+    result->reader.context = reader_context;
     result->reader.on_error = on_error_fprintf;
+    result->lock.action = lock;
+    result->lock.context = lock_context;
     result->do_register = do_decoder_register;
     result->do_decode_one = do_decode_one;
     result->on_error = on_error_fprintf;
diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h
index ec4f9f84e3ff79c7eda500f22d9f847b4ba17567..c3d8a46530d87fb70af0b5819f41e23156a26c28 100644
--- a/lib/c/labcomm.h
+++ b/lib/c/labcomm.h
@@ -76,6 +76,18 @@ 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)
+ */
+
+struct labcomm_lock_action {
+  int (*alloc)(void *context);
+  int (*free)(void *context);
+  int (*read_lock)(void *context);
+  int (*read_unlock)(void *context);
+  int (*write_lock)(void *context);
+  int (*write_unlock)(void *context);
+};
 
 /*
  * Decoder
@@ -84,12 +96,12 @@ void labcomm_decoder_register_new_datatype_handler(struct labcomm_decoder *d,
 struct labcomm_reader;
 
 struct labcomm_reader_action {
-  int (*alloc)(struct labcomm_reader *, char *labcomm_version);
-  int (*free)(struct labcomm_reader *);
-  int (*start)(struct labcomm_reader *);
-  int (*end)(struct labcomm_reader *);
-  int (*fill)(struct labcomm_reader *); 
-  int (*ioctl)(struct labcomm_reader *, int, labcomm_signature_t *, va_list);
+  int (*alloc)(struct labcomm_reader *r, char *labcomm_version);
+  int (*free)(struct labcomm_reader *r);
+  int (*start)(struct labcomm_reader *r);
+  int (*end)(struct labcomm_reader *r);
+  int (*fill)(struct labcomm_reader *r); 
+  int (*ioctl)(struct labcomm_reader *r, int, labcomm_signature_t *, va_list);
 };
 
 typedef struct labcomm_reader {
@@ -104,8 +116,10 @@ typedef struct labcomm_reader {
 }  labcomm_reader_t;
 
 struct labcomm_decoder *labcomm_decoder_new(
-  const struct labcomm_reader_action action,
-  void *reader_context);
+  const struct labcomm_reader_action reader,
+  void *reader_context,
+  const struct labcomm_lock_action *lock,
+  void *lock_context);
 int labcomm_decoder_decode_one(
   struct labcomm_decoder *decoder);
 void labcomm_decoder_run(
@@ -148,8 +162,10 @@ typedef struct labcomm_writer {
 } labcomm_writer_t;
 
 struct labcomm_encoder *labcomm_encoder_new(
-  const struct labcomm_writer_action action,
-  void *writer_context);
+  const struct labcomm_writer_action writer,
+  void *writer_context,
+  const struct labcomm_lock_action *lock,
+  void *lock_context);
 void labcomm_encoder_free(
   struct labcomm_encoder *encoder);
 
diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h
index 7d0cda83d3fecbb79356a5c5032a77082fec3c51..4a669967d6bde0829a0e0c801a77ea2aad44842e 100644
--- a/lib/c/labcomm_private.h
+++ b/lib/c/labcomm_private.h
@@ -57,6 +57,10 @@ typedef void (*labcomm_decoder_typecast_t)(
 typedef struct labcomm_decoder {
   void *context;
   labcomm_reader_t reader;
+  struct {
+    void *context;
+    const struct labcomm_lock_action *action;
+  } lock;
   void (*do_register)(struct labcomm_decoder *, 
 		      labcomm_signature_t *, 
 		      labcomm_decoder_typecast_t,
@@ -187,6 +191,10 @@ typedef int (*labcomm_encoder_function)(
 typedef struct labcomm_encoder {
   void *context;
   labcomm_writer_t writer;
+  struct {
+    void *context;
+    const struct labcomm_lock_action *action;
+  } lock;
   void (*do_register)(struct labcomm_encoder *encoder, 
 		      labcomm_signature_t *signature,
 		      labcomm_encoder_function encode);
diff --git a/lib/c/test/test_labcomm_basic_type_encoding.c b/lib/c/test/test_labcomm_basic_type_encoding.c
index dd8d65090e7443310f3ce1f2c624e2a1e55be192..f042051c9849c7f8d5942acaaf1c1206d502ff89 100644
--- a/lib/c/test/test_labcomm_basic_type_encoding.c
+++ b/lib/c/test/test_labcomm_basic_type_encoding.c
@@ -17,6 +17,7 @@ static labcomm_encoder_t encoder = {
     .action = { NULL, NULL, NULL, NULL, NULL, NULL },
     .on_error = NULL,
   },
+  .lock = { NULL, NULL },
   .do_register = NULL,
   .do_encode = NULL,
   .on_error = NULL,
@@ -33,6 +34,7 @@ static labcomm_decoder_t decoder = {
     .action = { NULL, NULL, NULL, NULL, NULL, NULL },
     .on_error = NULL,
   },
+  .lock = { NULL, NULL },
   .do_register = NULL,
   .on_error = NULL,
 };
diff --git a/lib/c/test/test_labcomm_generated_encoding.c b/lib/c/test/test_labcomm_generated_encoding.c
index 615fcea1efbb3040b44effce91a74c580f662b93..7a86a8d0759b7ab5d29c9bb6ca2f6407cf7ccb07 100644
--- a/lib/c/test/test_labcomm_generated_encoding.c
+++ b/lib/c/test/test_labcomm_generated_encoding.c
@@ -132,7 +132,8 @@ int main(void)
   generated_encoding_V V;
   generated_encoding_B B = 1;
 
-  labcomm_encoder_t *encoder = labcomm_encoder_new(buffer_writer, buffer);
+  labcomm_encoder_t *encoder = labcomm_encoder_new(buffer_writer, buffer,
+						   NULL, NULL);
 
   labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
   labcomm_encoder_register_generated_encoding_V(encoder);
diff --git a/test/relay_gen_c.py b/test/relay_gen_c.py
index a898d20338dcdd05e23939b8d4b44116b5f1d9ed..72978045dda49ac6d29f27cd68b844576bae6c72 100755
--- a/test/relay_gen_c.py
+++ b/test/relay_gen_c.py
@@ -50,8 +50,8 @@ if __name__ == '__main__':
       |  if (in < 0) { return 1; }
       |  out = open(argv[2], O_WRONLY);
       |  if (out < 0) { return 1; }
-      |  e = labcomm_encoder_new(labcomm_fd_writer, &out);
-      |  d = labcomm_decoder_new(labcomm_fd_reader, &in);
+      |  e = labcomm_encoder_new(labcomm_fd_writer, &out, NULL, NULL);
+      |  d = labcomm_decoder_new(labcomm_fd_reader, &in, NULL, NULL);
     """))
     for func,arg in sample:
         result.extend(split_match('^[^|]*\|(.*)$', """