Index: src/Concurrency/Waitfor.cc
===================================================================
--- src/Concurrency/Waitfor.cc	(revision a2dbad1018db72ea030403b45b0a7e85d157136e)
+++ src/Concurrency/Waitfor.cc	(revision aaa4f93bb24090911402658ab4712faeadc90a06)
@@ -126,7 +126,9 @@
 
 		ObjectDecl * declare( unsigned long count, CompoundStmt * stmt );
+		ObjectDecl * declareFlag( CompoundStmt * stmt );
+		Statement  * makeSetter( ObjectDecl * flag );
 		ObjectDecl * declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt );
-		void         init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt );
-		Expression * init_timeout( Expression *& time, Expression *& time_cond, bool has_else, Expression *& else_cond, CompoundStmt * stmt );
+		void         init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, Statement * settter, CompoundStmt * stmt );
+		Expression * init_timeout( Expression *& time, Expression *& time_cond, bool has_else, Expression *& else_cond, Statement * settter, CompoundStmt * stmt );
 		Expression * call(size_t count, ObjectDecl * acceptables, Expression * timeout, CompoundStmt * stmt);
 		void         choose( WaitForStmt * waitfor, Expression  * result, CompoundStmt * stmt );
@@ -140,4 +142,5 @@
 	  private:
 	  	FunctionDecl        * decl_waitfor    = nullptr;
+	  	StructDecl          * decl_mask       = nullptr;
 		StructDecl          * decl_acceptable = nullptr;
 		StructDecl          * decl_monitor    = nullptr;
@@ -145,8 +148,10 @@
 		static std::unique_ptr< Type > generic_func;
 
+		UniqueName namer_acc = "__acceptables_"s;
+		UniqueName namer_idx = "__index_"s;
+		UniqueName namer_flg = "__do_run_"s;
+		UniqueName namer_msk = "__mask_"s;
 		UniqueName namer_mon = "__monitors_"s;
-		UniqueName namer_acc = "__acceptables_"s;
 		UniqueName namer_tim = "__timeout_"s;
-		UniqueName namer_ret = "__return_"s;
 	};
 
@@ -239,4 +244,8 @@
 			decl_acceptable = decl;
 		}
+		else if( decl->name == "__waitfor_mask_t" ) {
+			assert( !decl_mask );
+			decl_mask = decl;
+		}
 		else if( decl->name == "monitor_desc" ) {
 			assert( !decl_monitor );
@@ -246,13 +255,15 @@
 
 	Statement * GenerateWaitForPass::postmutate( WaitForStmt * waitfor ) {
-		if( !decl_monitor || !decl_acceptable ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor );
+		if( !decl_monitor || !decl_acceptable || !decl_mask ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor );
 
 		CompoundStmt * stmt = new CompoundStmt( noLabels );
 
 		ObjectDecl * acceptables = declare( waitfor->clauses.size(), stmt );
+		ObjectDecl * flag        = declareFlag( stmt );
+		Statement  * setter      = makeSetter( flag );
 
 		int index = 0;
 		for( auto & clause : waitfor->clauses ) {
-			init( acceptables, index, clause, stmt );
+			init( acceptables, index, clause, setter, stmt );
 
 			index++;
@@ -264,10 +275,19 @@
 			waitfor->orelse .statement,
 			waitfor->orelse .condition,
+			setter,
 			stmt
 		);
 
-		Expression * result = call( waitfor->clauses.size(), acceptables, timeout, stmt );
-
-		choose( waitfor, result, stmt );
+		CompoundStmt * compound = new CompoundStmt( noLabels );
+		stmt->push_back( new IfStmt(
+			noLabels,
+			safeCond( new VariableExpr( flag ) ),
+			compound,
+			nullptr
+		));
+
+		Expression * result = call( waitfor->clauses.size(), acceptables, timeout, compound );
+
+		choose( waitfor, result, compound );
 
 		return stmt;
@@ -293,5 +313,49 @@
 		stmt->push_back( new DeclStmt( noLabels, acceptables) );
 
+		UntypedExpr * set = new UntypedExpr(
+			new NameExpr( "__builtin_memset" ),
+			{
+				new VariableExpr( acceptables ),
+				new ConstantExpr( Constant::from_int( 0 ) ),
+				new SizeofExpr( new VariableExpr( acceptables ) )
+			}
+		);
+
+		Expression * resolved_set = ResolvExpr::findVoidExpression( set, indexer );
+		delete set;
+
+		stmt->push_back( new ExprStmt( noLabels, resolved_set ) );
+
 		return acceptables;
+	}
+
+	ObjectDecl * GenerateWaitForPass::declareFlag( CompoundStmt * stmt ) {
+		ObjectDecl * flag = ObjectDecl::newObject(
+			namer_flg.newName(),
+			new BasicType(
+				noQualifiers,
+				BasicType::Bool
+			),
+			new SingleInit( new ConstantExpr( Constant::from_ulong( 0 ) ) )
+		);
+
+		stmt->push_back( new DeclStmt( noLabels, flag) );
+
+		return flag;
+	}
+
+	Statement * GenerateWaitForPass::makeSetter( ObjectDecl * flag ) {
+		Expression * untyped = new UntypedExpr(
+			new NameExpr( "?=?" ),
+			{
+				new VariableExpr( flag ),
+				new ConstantExpr( Constant::from_ulong( 1 ) )
+			}
+		);
+
+		Expression * expr = ResolvExpr::findVoidExpression( untyped, indexer );
+		delete untyped;
+
+		return new ExprStmt( noLabels, expr );
 	}
 
@@ -341,20 +405,20 @@
 	}
 
-	void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt ) {
+	void GenerateWaitForPass::init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, Statement * setter, CompoundStmt * stmt ) {
 
 		ObjectDecl * monitors = declMon( clause, stmt );
 
 		Type * fptr_t = new PointerType( noQualifiers, new FunctionType( noQualifiers, true ) );
-
-		CompoundStmt * compound = new CompoundStmt( noLabels );
-		compound->push_back( makeAccStatement( acceptables, index, "is_dtor" , detectIsDtor( clause.target.function )                                    , indexer ) );
-		compound->push_back( makeAccStatement( acceptables, index, "func"    , new CastExpr( clause.target.function, fptr_t )                            , indexer ) );
-		compound->push_back( makeAccStatement( acceptables, index, "monitors", new VariableExpr( monitors )                                              , indexer ) );
-		compound->push_back( makeAccStatement( acceptables, index, "count"   , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ), indexer ) );
 
 		stmt->push_back( new IfStmt(
 			noLabels,
 			safeCond( clause.condition ),
-			compound,
+			new CompoundStmt({
+				makeAccStatement( acceptables, index, "is_dtor", detectIsDtor( clause.target.function )                                    , indexer ),
+				makeAccStatement( acceptables, index, "func"   , new CastExpr( clause.target.function, fptr_t )                            , indexer ),
+				makeAccStatement( acceptables, index, "list"   , new VariableExpr( monitors )                                              , indexer ),
+				makeAccStatement( acceptables, index, "size"   , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ), indexer ),
+				setter->clone()
+			}),
 			nullptr
 		));
@@ -370,4 +434,5 @@
 		bool has_else,
 		Expression *& else_cond,
+		Statement * setter,
 		CompoundStmt * stmt
 	) {
@@ -389,11 +454,14 @@
 				noLabels,
 				safeCond( time_cond ),
-				new ExprStmt(
-					noLabels,
-					makeOpAssign(
-						new VariableExpr( timeout ),
-						time
-					)
-				),
+				new CompoundStmt({
+					new ExprStmt(
+						noLabels,
+						makeOpAssign(
+							new VariableExpr( timeout ),
+							time
+						)
+					),
+					setter->clone()
+				}),
 				nullptr
 			));
@@ -406,11 +474,14 @@
 				noLabels,
 				safeCond( else_cond ),
-				new ExprStmt(
-					noLabels,
-					makeOpAssign(
-						new VariableExpr( timeout ),
-						new ConstantExpr( Constant::from_ulong( 0 ) )
-					)
-				),
+				new CompoundStmt({
+					new ExprStmt(
+						noLabels,
+						makeOpAssign(
+							new VariableExpr( timeout ),
+							new ConstantExpr( Constant::from_ulong( 0 ) )
+						)
+					),
+					setter->clone()
+				}),
 				nullptr
 			));
@@ -418,4 +489,6 @@
 			else_cond = nullptr;
 		}
+
+		delete setter;
 
 		return new VariableExpr( timeout );
@@ -428,25 +501,53 @@
 		CompoundStmt * stmt
 	) {
-		ObjectDecl * decl = ObjectDecl::newObject(
-			namer_ret.newName(),
+		ObjectDecl * index = ObjectDecl::newObject(
+			namer_idx.newName(),
 			new BasicType(
 				noQualifiers,
-				BasicType::LongLongUnsignedInt
+				BasicType::ShortSignedInt
 			),
 			new SingleInit(
-				new UntypedExpr(
-					VariableExpr::functionPointer( decl_waitfor ),
-					{
-						new ConstantExpr( Constant::from_ulong( count ) ),
-						new VariableExpr( acceptables ),
-						timeout
-					}
-				)
+				new ConstantExpr( Constant::from_int( -1 ) )
 			)
 		);
 
-		stmt->push_back( new DeclStmt( noLabels, decl ) );
-
-		return new VariableExpr( decl );
+		stmt->push_back( new DeclStmt( noLabels, index ) );
+
+		ObjectDecl * mask = ObjectDecl::newObject(
+			namer_msk.newName(),
+			new StructInstType(
+				noQualifiers,
+				decl_mask
+			),
+			new ListInit({
+				new SingleInit( new AddressExpr( new VariableExpr( index ) ) ),
+				new SingleInit( new VariableExpr( acceptables ) ),
+				new SingleInit( new ConstantExpr( Constant::from_ulong( count ) ) )
+			})
+		);
+
+		stmt->push_back( new DeclStmt( noLabels, mask ) );
+
+		stmt->push_back( new ExprStmt(
+			noLabels,
+			new ApplicationExpr(
+				VariableExpr::functionPointer( decl_waitfor ),
+				{
+					new CastExpr(
+						new VariableExpr( mask ),
+						new ReferenceType(
+							noQualifiers,
+							new StructInstType(
+								noQualifiers,
+								decl_mask
+							)
+						)
+					),
+					timeout
+				}
+			)
+		));
+
+		return new VariableExpr( index );
 	}
 
Index: src/libcfa/concurrency/monitor
===================================================================
--- src/libcfa/concurrency/monitor	(revision a2dbad1018db72ea030403b45b0a7e85d157136e)
+++ src/libcfa/concurrency/monitor	(revision aaa4f93bb24090911402658ab4712faeadc90a06)
@@ -105,5 +105,5 @@
 
 struct __acceptable_t {
-	__monitor_group_t monitors;
+	__monitor_group_t;
 	bool is_dtor;
 };
Index: src/libcfa/concurrency/monitor.c
===================================================================
--- src/libcfa/concurrency/monitor.c	(revision a2dbad1018db72ea030403b45b0a7e85d157136e)
+++ src/libcfa/concurrency/monitor.c	(revision aaa4f93bb24090911402658ab4712faeadc90a06)
@@ -280,9 +280,4 @@
 	lock_all( monitors, locks, count );
 
-	// DON'T unlock, ask the kernel to do it
-
-	// Save monitor state
-	save_recursion( monitors, recursions, count );
-
 	// Find the next thread(s) to run
 	unsigned short thread_count = 0;
@@ -297,4 +292,7 @@
 		thread_count = insert_unique( threads, thread_count, new_owner );
 	}
+
+	// Save monitor state
+	save_recursion( monitors, recursions, count );
 
 	// Everything is ready to go to sleep
@@ -634,5 +632,5 @@
 	// For all acceptable functions check if this is the current function.
 	for( short i = 0; i < count; i++, it++ ) {
-		if( it->monitors == group ) {
+		if( *it == group ) {
 			*this->mask.accepted = i;
 			return true;
@@ -658,5 +656,5 @@
 		for( __acceptable_t * it = mask.clauses; it != end; it++, i++ ) {
 			// Check if we have a match
-			if( it->monitors == (*thrd_it)->monitors ) {
+			if( *it == (*thrd_it)->monitors ) {
 
 				// If we have a match return it
@@ -673,5 +671,5 @@
 	short max = 0;
 	for( int i = 0; i < mask.size; i++ ) {
-		max += mask.clauses[i].monitors.size;
+		max += mask.clauses[i].size;
 	}
 	return max;
