Index: src/libcfa/concurrency/monitor
===================================================================
--- src/libcfa/concurrency/monitor	(revision 8f61052caa02aef0a7d305cd2d13e1c5bc75cabc)
+++ src/libcfa/concurrency/monitor	(revision 2ab67b9735bea8d47248cfb229dae71aca39af2e)
@@ -59,4 +59,5 @@
 	unsigned short count;				//Number of criterions in the criteria
 	__condition_node_t * next;			//Intrusive linked list Next field
+	uintptr_t user_info;				//Custom user info accessible before signalling
 };
 
@@ -85,6 +86,9 @@
 }
 
-void wait( condition * this );
-void signal( condition * this );
-void signal_block( condition * this );
+void wait( condition * this, uintptr_t user_info = 0 );
+bool signal( condition * this );
+bool signal_block( condition * this );
+static inline bool is_empty( condition * this ) { return !this->blocked.head; }
+uintptr_t front( condition * this );
+
 #endif //MONITOR_H
Index: src/libcfa/concurrency/monitor.c
===================================================================
--- src/libcfa/concurrency/monitor.c	(revision 8f61052caa02aef0a7d305cd2d13e1c5bc75cabc)
+++ src/libcfa/concurrency/monitor.c	(revision 2ab67b9735bea8d47248cfb229dae71aca39af2e)
@@ -137,12 +137,28 @@
 }
 
-void debug_break() __attribute__(( noinline ))
-{
-	
+void ?{}(__condition_node_t * this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info ) {
+	this->waiting_thread = waiting_thread;
+	this->count = count;
+	this->next = NULL;
+	this->user_info = user_info;
+}
+
+void ?{}(__condition_criterion_t * this ) {
+	this->ready  = false;
+	this->target = NULL;
+	this->owner  = NULL;
+	this->next   = NULL;
+}
+
+void ?{}(__condition_criterion_t * this, monitor_desc * target, __condition_node_t * owner ) {
+	this->ready  = false;
+	this->target = target;
+	this->owner  = owner;
+	this->next   = NULL;
 }
 
 //-----------------------------------------------------------------------------
 // Internal scheduling
-void wait( condition * this ) {
+void wait( condition * this, uintptr_t user_info = 0 ) {
 	LIB_DEBUG_PRINT_SAFE("Waiting\n");
 
@@ -160,15 +176,9 @@
 	LIB_DEBUG_PRINT_SAFE("count %i\n", count);
 
-	__condition_node_t waiter;
-	waiter.waiting_thread = this_thread();
-	waiter.count = count;
-	waiter.next = NULL;
+	__condition_node_t waiter = { this_thread(), count, user_info };
 
 	__condition_criterion_t criteria[count];
 	for(int i = 0; i < count; i++) {
-		criteria[i].ready  = false;
-		criteria[i].target = this->monitors[i];
-		criteria[i].owner  = &waiter;
-		criteria[i].next   = NULL;
+		(&criteria[i]){ this->monitors[i], &waiter };
 		LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
 	}
@@ -202,5 +212,4 @@
 	ScheduleInternal( locks, count, threads, thread_count );
 
-	debug_break();
 	//WE WOKE UP
 
@@ -212,8 +221,8 @@
 }
 
-void signal( condition * this ) {
-	if( !this->blocked.head ) {
+bool signal( condition * this ) {
+	if( is_empty( this ) ) {
 		LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
-		return;
+		return false;
 	}
 
@@ -257,10 +266,12 @@
 	//Release
 	unlock_all( this->monitors, count );
-}
-
-void signal_block( condition * this ) {
+
+	return true;
+}
+
+bool signal_block( condition * this ) {
 	if( !this->blocked.head ) {
 		LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
-		return;
+		return false;
 	}
 
@@ -276,16 +287,10 @@
 
 	//create creteria
-	__condition_node_t waiter;
-	waiter.waiting_thread = this_thread();
-	waiter.count = count;
-	waiter.next = NULL;
+	__condition_node_t waiter = { this_thread(), count, 0 };
 
 	__condition_criterion_t criteria[count];
 	for(int i = 0; i < count; i++) {
+		(&criteria[i]){ this->monitors[i], &waiter };
 		LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
-		criteria[i].ready  = false;
-		criteria[i].owner  = &waiter;
-		criteria[i].next   = NULL;
-		criteria[i].target = this->monitors[i];
 		push( &criteria[i].target->signal_stack, &criteria[i] );
 	}
@@ -303,10 +308,8 @@
 
 	LIB_DEBUG_PRINT_SAFE( "Waiting on signal block\n" );
-	debug_break();
 
 	//Everything is ready to go to sleep
 	ScheduleInternal( locks, count, &signallee, 1 );
 
-	debug_break();
 	LIB_DEBUG_PRINT_SAFE( "Back from signal block\n" );
 
@@ -315,4 +318,16 @@
 	restore_recursion( this->monitors, recursions, count );
 	unlock_all( locks, count );
+
+	return true;
+}
+
+uintptr_t front( condition * this ) {
+	LIB_DEBUG_DO(
+		if( is_empty(this) ) {
+			abortf( "Attempt to access user data on an empty condition.\n"
+                    "Possible cause is not checking if the condition is empty before reading stored data." );
+		}
+	);
+	return this->blocked.head->user_info;
 }
 
