diff --git a/main/devicestate.c b/main/devicestate.c
index aba6159b44937e9279f77695c342489e696dd6dd..400d655f63ce3a200c13f6ae6b47ab048f40321b 100644
--- a/main/devicestate.c
+++ b/main/devicestate.c
@@ -214,6 +214,7 @@ static pthread_t change_thread = AST_PTHREADT_NULL;
 
 /*! \brief Flag for the queue */
 static ast_cond_t change_pending;
+static volatile int shuttingdown;
 
 struct stasis_subscription *devstate_message_sub;
 
@@ -548,7 +549,7 @@ static void *do_devstate_changes(void *data)
 {
 	struct state_change *next, *current;
 
-	for (;;) {
+	while (!shuttingdown) {
 		/* This basically pops off any state change entries, resets the list back to NULL, unlocks, and processes each state change */
 		AST_LIST_LOCK(&state_changes);
 		if (AST_LIST_EMPTY(&state_changes))
@@ -626,6 +627,18 @@ static void devstate_change_cb(void *data, struct stasis_subscription *sub, stru
 		device_state->cachable, NULL);
 }
 
+static void device_state_engine_cleanup(void)
+{
+	shuttingdown = 1;
+	AST_LIST_LOCK(&state_changes);
+	ast_cond_signal(&change_pending);
+	AST_LIST_UNLOCK(&state_changes);
+
+	if (change_thread != AST_PTHREADT_NULL) {
+		pthread_join(change_thread, NULL);
+	}
+}
+
 /*! \brief Initialize the device state engine in separate thread */
 int ast_device_state_engine_init(void)
 {
@@ -634,6 +647,7 @@ int ast_device_state_engine_init(void)
 		ast_log(LOG_ERROR, "Unable to start device state change thread.\n");
 		return -1;
 	}
+	ast_register_cleanup(device_state_engine_cleanup);
 
 	return 0;
 }