diff --git a/epicardium/modules/stream.c b/epicardium/modules/stream.c
index 561c398ab4ddba54d0ce81c5476ddcbcbca96d82..b39e0c1df68c93cd4f59f1fd9818454a3b98b585 100644
--- a/epicardium/modules/stream.c
+++ b/epicardium/modules/stream.c
@@ -1,18 +1,32 @@
 #include <string.h>
 
+#include "FreeRTOS.h"
+#include "semphr.h"
+
 #include "epicardium.h"
 #include "stream.h"
 
+/* Internal buffer of registered streams */
 static struct stream_info *stream_table[SD_MAX];
 
+/* Lock for modifying the stream info table */
+static StaticSemaphore_t stream_table_lock_data;
+static SemaphoreHandle_t stream_table_lock;
+
 int stream_init()
 {
 	memset(stream_table, 0x00, sizeof(stream_table));
+	stream_table_lock =
+		xSemaphoreCreateMutexStatic(&stream_table_lock_data);
 	return 0;
 }
 
 int stream_register(int sd, struct stream_info *stream)
 {
+	if (xSemaphoreTake(stream_table_lock, STREAM_MUTEX_WAIT) != pdTRUE) {
+		return -EBUSY;
+	}
+
 	if (sd < 0 || sd >= SD_MAX) {
 		return -EINVAL;
 	}
@@ -23,11 +37,17 @@ int stream_register(int sd, struct stream_info *stream)
 	}
 
 	stream_table[sd] = stream;
+
+	xSemaphoreGive(stream_table_lock);
 	return 0;
 }
 
 int stream_deregister(int sd, struct stream_info *stream)
 {
+	if (xSemaphoreTake(stream_table_lock, STREAM_MUTEX_WAIT) != pdTRUE) {
+		return -EBUSY;
+	}
+
 	if (sd < 0 || sd >= SD_MAX) {
 		return -EINVAL;
 	}
@@ -38,11 +58,22 @@ int stream_deregister(int sd, struct stream_info *stream)
 	}
 
 	stream_table[sd] = NULL;
+
+	xSemaphoreGive(stream_table_lock);
 	return 0;
 }
 
 int epic_stream_read(int sd, void *buf, size_t count)
 {
+	/*
+	 * TODO: In theory, multiple reads on different streams can happen
+	 * simulaneously.  I don't know what the most efficient implementation
+	 * of this would look like.
+	 */
+	if (xSemaphoreTake(stream_table_lock, STREAM_MUTEX_WAIT) != pdTRUE) {
+		return -EBUSY;
+	}
+
 	if (sd < 0 || sd >= SD_MAX) {
 		return -EBADF;
 	}
@@ -72,5 +103,6 @@ int epic_stream_read(int sd, void *buf, size_t count)
 		}
 	}
 
+	xSemaphoreGive(stream_table_lock);
 	return i / stream->item_size;
 }
diff --git a/epicardium/modules/stream.h b/epicardium/modules/stream.h
index 622aee4017cf6b8524153809a537b30f19ee2c83..5bce8d56ed29414a06fdaa90d0b83fbe7a4fca32 100644
--- a/epicardium/modules/stream.h
+++ b/epicardium/modules/stream.h
@@ -7,6 +7,9 @@
 #include "FreeRTOS.h"
 #include "queue.h"
 
+/* Time to wait for the descriptor table lock to become available */
+#define STREAM_MUTEX_WAIT pdMS_TO_TICKS(100)
+
 /**
  * **Stream Descriptors**:
  *