Index: src/libcfa/concurrency/monitor.c
===================================================================
--- src/libcfa/concurrency/monitor.c	(revision 310e5b7a73ac432e83f04a8d32b171a31ac8c68f)
+++ src/libcfa/concurrency/monitor.c	(revision b18830e160544a32e0d1b1ea1100232bf1c4545d)
@@ -25,5 +25,5 @@
 static inline void set_owner( monitor_desc * this, thread_desc * owner );
 static inline thread_desc * next_thread( monitor_desc * this );
-static inline int is_accepted( thread_desc * owner, monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() );
+static inline int is_accepted( thread_desc * owner, monitor_desc * this, const __monitor_group & monitors );
 
 static inline void lock_all( spinlock ** locks, unsigned short count );
@@ -42,5 +42,9 @@
 static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val );
 
-static inline thread_desc * search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count );
+static inline [thread_desc *, int] search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count );
+
+static inline short count_max( short acc_count, __acceptable_t * acceptables );
+static inline short aggregate( monitor_desc ** storage, short count, __acceptable_t * acceptables );
+static inline void  set_mask ( monitor_desc ** storage, short count, __acceptable_t * acceptables, short acc_count );
 
 //-----------------------------------------------------------------------------
@@ -68,5 +72,7 @@
 extern "C" {
 	// Enter single monitor
-	static void __enter_monitor_desc( monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() ) {
+	static void __enter_monitor_desc( const __monitor_group & group ) {
+		monitor_desc * this = group.list[0];
+
 		// Lock the monitor spinlock, lock_yield to reduce contention
 		lock_yield( &this->lock DEBUG_CTX2 );
@@ -89,5 +95,5 @@
 			LIB_DEBUG_PRINT_SAFE("Kernel :  mon already owned \n");
 		}
-		else if( (this->accepted_index = is_accepted( thrd, this, group, group_cnt, func)) >= 0 ) {
+		else if( (this->accepted_index = is_accepted( thrd, this, group)) >= 0 ) {
 			// Some one was waiting for us, enter
 			set_owner( this, thrd );
@@ -146,5 +152,5 @@
 	// Should never return
 	void __leave_thread_monitor( thread_desc * thrd ) {
-		monitor_desc * this = &thrd->mon;
+		monitor_desc * this = &thrd->self_mon;
 
 		// Lock the monitor now
@@ -153,5 +159,5 @@
 		disable_interrupts();
 
-		thrd->cor.state = Halted;
+		thrd->self_cor.state = Halted;
 
 		verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion );
@@ -178,7 +184,7 @@
 // Enter multiple monitor
 // relies on the monitor array being sorted
-static inline void enter(monitor_desc ** monitors, int count, void (*func)() ) {
-	for(int i = 0; i < count; i++) {
-		__enter_monitor_desc( monitors[i], monitors, count, func );
+static inline void enter( __monitor_group monitors ) {
+	for(int i = 0; i < monitors.size; i++) {
+		__enter_monitor_desc( monitors );
 	}
 }
@@ -203,15 +209,16 @@
 
 	// Save previous thread context
-	this.prev_mntrs = this_thread->current_monitors;
-	this.prev_count = this_thread->current_monitor_count;
-	this.prev_func  = this_thread->current_monitor_func;
+	this.prev_mntrs = this_thread->monitors.list;
+	this.prev_count = this_thread->monitors.size;
+	this.prev_func  = this_thread->monitors.func;
 
 	// Update thread context (needed for conditions)
-	this_thread->current_monitors      = m;
-	this_thread->current_monitor_count = count;
-	this_thread->current_monitor_func  = func;
+	this_thread->monitors.list = m;
+	this_thread->monitors.size = count;
+	this_thread->monitors.func = func;
 
 	// Enter the monitors in order
-	enter( this.m, this.count, func );
+	__monitor_group group = {this.m, this.count, func};
+	enter( group );
 }
 
@@ -223,7 +230,7 @@
 
 	// Restore thread context
-	this_thread->current_monitors      = this.prev_mntrs;
-	this_thread->current_monitor_count = this.prev_count;
-	this_thread->current_monitor_func  = this.prev_func;
+	this_thread->monitors.list = this.prev_mntrs;
+	this_thread->monitors.size = this.prev_count;
+	this_thread->monitors.func = this.prev_func;
 }
 
@@ -315,11 +322,11 @@
 	LIB_DEBUG_DO(
 		thread_desc * this_thrd = this_thread;
-		if ( this->monitor_count != this_thrd->current_monitor_count ) {
-			abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->current_monitor_count );
+		if ( this->monitor_count != this_thrd->monitors.size ) {
+			abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->monitors.size );
 		}
 
 		for(int i = 0; i < this->monitor_count; i++) {
-			if ( this->monitors[i] != this_thrd->current_monitors[i] ) {
-				abortf( "Signal on condition %p made with different monitor, expected %p got %i", this, this->monitors[i], this_thrd->current_monitors[i] );
+			if ( this->monitors[i] != this_thrd->monitors.list[i] ) {
+				abortf( "Signal on condition %p made with different monitor, expected %p got %i", this, this->monitors[i], this_thrd->monitors.list[i] );
 			}
 		}
@@ -397,40 +404,66 @@
 
 //-----------------------------------------------------------------------------
-// Internal scheduling
-int __waitfor_internal( unsigned short acc_count, __acceptable_t * acceptables ) {
-	thread_desc * thrd = this_thread;
+// External scheduling
+// cases to handle :
+// 	- target already there :
+// 		block and wake
+// 	- dtor already there
+// 		put thread on signaller stack
+// 	- non-blocking
+// 		return else
+// 	- timeout
+// 		return timeout
+// 	- block
+// 		setup mask
+// 		block
+int __waitfor_internal( unsigned short acc_count, __acceptable_t * acceptables, int duration ) {
+	// This statment doesn't have a contiguous list of monitors...
+	// Create one!
+	short max = count_max( acc_count, acceptables );
+	monitor_desc * mon_storage[max];
+	short actual_count = aggregate( mon_storage, acc_count, acceptables );
 
 	// Create storage for monitor context
-	monitor_ctx( acceptables->monitors, acceptables->count );
+	monitor_ctx( mon_storage, actual_count );
 
 	// Lock all monitors (aggregates the lock them as well)
 	lock_all( monitors, locks, count );
 
-	// Create the node specific to this wait operation
-	wait_ctx_primed( thrd, 0 );
-
-	// Check if the entry queue
-	thread_desc * next = search_entry_queue( acceptables, acc_count, monitors, count );
-
-	LIB_DEBUG_PRINT_SAFE("Owner(s) :");
-	for(int i = 0; i < count; i++) {
-		LIB_DEBUG_PRINT_SAFE(" %p", monitors[i]->owner );
-	}
-	LIB_DEBUG_PRINT_SAFE("\n");
-
-	LIB_DEBUG_PRINT_SAFE("Passing mon to %p\n", next);
-
-	if( !next ) {
-		// Update acceptables on the current monitors
-		for(int i = 0; i < count; i++) {
-			monitors[i]->acceptables = acceptables;
-			monitors[i]->acceptable_count = acc_count;
-		}
-	}
-	else {
-		for(int i = 0; i < count; i++) {
-			set_owner( monitors[i], next );
-		}
-	}
+	{
+		// Check if the entry queue
+		thread_desc * next;
+		int index;
+		[next, index] = search_entry_queue( acceptables, acc_count, monitors, count );
+
+		if( next ) {
+			if( acceptables[index].is_dtor ) {
+				#warning case not implemented
+			}
+			else {
+				save_recursion( monitors, recursions, count );
+
+				// Everything is ready to go to sleep
+				BlockInternal( locks, count, &next, 1 );
+
+
+				//WE WOKE UP
+
+
+				//We are back, restore the owners and recursions
+				lock_all( locks, count );
+				restore_recursion( monitors, recursions, count );
+				unlock_all( locks, count );
+			}
+
+			return index;
+		}
+	}
+
+
+	if( duration == 0 ) return -1;
+
+	set_mask( monitors, count, acceptables, acc_count );
+
+	verifyf( duration < 0, "Timeout on waitfor statments not supported yet.");
 
 
@@ -439,5 +472,5 @@
 
 	// Everything is ready to go to sleep
-	BlockInternal( locks, count, &next, next ? 1 : 0 );
+	BlockInternal( locks, count );
 
 
@@ -485,40 +518,4 @@
 }
 
-static inline int is_accepted( thread_desc * owner, monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() ) {
-	__acceptable_t* accs = this->acceptables; // Optim
-	int acc_cnt = this->acceptable_count;
-
-	// Check if there are any acceptable functions
-	if( !accs ) return -1;
-
-	// If this isn't the first monitor to test this, there is no reason to repeat the test.
-	if( this != group[0] ) return group[0]->accepted_index;
-
-	// For all acceptable functions check if this is the current function.
-	OUT_LOOP:
-	for( int i = 0; i < acc_cnt; i++ ) {
-		__acceptable_t * acc = &accs[i];
-
-		// if function matches, check the monitors
-		if( acc->func == func ) {
-
-			// If the group count is different then it can't be a match
-			if( acc->count != group_cnt ) return -1;
-
-			// Check that all the monitors match
-			for( int j = 0; j < group_cnt; j++ ) {
-				// If not a match, check next function
-				if( acc->monitors[j] != group[j] ) continue OUT_LOOP;
-			}
-
-			// It's a complete match, accept the call
-			return i;
-		}
-	}
-
-	// No function matched
-	return -1;
-}
-
 static inline void init( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ) {
 	for(int i = 0; i < count; i++) {
@@ -607,10 +604,10 @@
 	if( !this->monitors ) {
 		// LIB_DEBUG_PRINT_SAFE("Branding\n");
-		assertf( thrd->current_monitors != NULL, "No current monitor to brand condition %p", thrd->current_monitors );
-		this->monitor_count = thrd->current_monitor_count;
+		assertf( thrd->monitors.list != NULL, "No current monitor to brand condition %p", thrd->monitors.list );
+		this->monitor_count = thrd->monitors.size;
 
 		this->monitors = malloc( this->monitor_count * sizeof( *this->monitors ) );
 		for( int i = 0; i < this->monitor_count; i++ ) {
-			this->monitors[i] = thrd->current_monitors[i];
+			this->monitors[i] = thrd->monitors.list[i];
 		}
 	}
@@ -628,14 +625,26 @@
 }
 
-
-static inline bool match( __acceptable_t * acc, thread_desc * thrd ) {
-	verify( thrd );
-	verify( acc );
-	if( acc->func != thrd->current_monitor_func ) return false;
-
-	return true;
-}
-
-static inline thread_desc * search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count ) {
+static inline int is_accepted( thread_desc * owner, monitor_desc * this, const __monitor_group & group ) {
+	__acceptable_t* accs = this->acceptables; // Optim
+	int acc_cnt = this->acceptable_count;
+
+	// Check if there are any acceptable functions
+	if( !accs ) return -1;
+
+	// If this isn't the first monitor to test this, there is no reason to repeat the test.
+	if( this != group[0] ) return group[0]->accepted_index;
+
+	// For all acceptable functions check if this is the current function.
+	for( int i = 0; i < acc_cnt; i++ ) {
+		__acceptable_t * acc = &accs[i];
+
+		if( acc->monitors == group ) return i;
+	}
+
+	// No function matched
+	return -1;
+}
+
+static inline [thread_desc *, int] search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count ) {
 
 	__thread_queue_t * entry_queue = &monitors[0]->entry_queue;
@@ -647,18 +656,42 @@
 	{
 		// For each acceptable check if it matches
+		int i;
 		__acceptable_t * acc_end = acceptables + acc_count;
-		for( __acceptable_t * acc_it = acceptables; acc_it != acc_end; acc_it++ ) {
+		for( __acceptable_t * acc_it = acceptables; acc_it != acc_end; acc_it++, i++ ) {
 			// Check if we have a match
-			if( match( acc_it, *thrd_it ) ) {
+			if( acc_it->monitors == (*thrd_it)->monitors ) {
 
 				// If we have a match return it
 				// after removeing it from the entry queue
-				return remove( entry_queue, thrd_it );
+				return [remove( entry_queue, thrd_it ), i];
 			}
 		}
 	}
 
-	return NULL;
-}
+	return [0, -1];
+}
+
+static inline short count_max( short acc_count, __acceptable_t * acceptables ) {
+	short max = 0;
+	for( int i = 0; i < acc_count; i++ ) {
+		max += acceptables[i].monitors.size;
+	}
+	return max;
+}
+
+static inline short aggregate( monitor_desc ** storage, short count, __acceptable_t * acceptables ) {
+	#warning function not implemented
+	return 0;
+}
+
+static inline void set_mask( monitor_desc ** storage, short count, __acceptable_t * acceptables, short acc_count ) {
+	for(int i = 0; i < count; i++) {
+		storage[i]->acceptables      = acceptables;
+		storage[i]->acceptable_count = acc_count;
+		storage[i]->accepted_index   = -1;
+	}
+}
+
+
 void ?{}( __condition_blocked_queue_t & this ) {
 	this.head = NULL;
