Index: libcfa/src/concurrency/channel.hfa
===================================================================
--- libcfa/src/concurrency/channel.hfa	(revision d5187a0603e2d2c1c0fbac8a65e8639c613b5708)
+++ libcfa/src/concurrency/channel.hfa	(revision 253a78ffaf6f91bf8f04bc8188716a454112fff7)
@@ -350,9 +350,25 @@
     #endif
 
-    // check if we can complete operation. If so race to establish winner in special OR case
-    if ( !node.park_counter && ( count != 0 || !prods`isEmpty || unlikely(closed) ) ) {
-        if ( !__make_select_node_available( node ) ) { // we didn't win the race so give up on registering
-           unlock( mutex_lock );
-           return false;
+    if ( !node.park_counter ) {
+        // are we special case OR and front of cons is also special case OR
+        if ( !unlikely(closed) && !prods`isEmpty && prods`first.clause_status && !prods`first.park_counter ) {
+            if ( !__make_select_node_pending( node ) ) {
+                unlock( mutex_lock );
+                return false;
+            }
+            
+            if ( __handle_waituntil_OR( prods ) ) {
+                __prods_handoff( chan, ret );
+                unlock( mutex_lock );
+                return true;
+            }
+            __make_select_node_unsat( node );
+        }
+        // check if we can complete operation. If so race to establish winner in special OR case
+        if ( count != 0 || !prods`isEmpty || unlikely(closed) ) {
+            if ( !__make_select_node_available( node ) ) { // we didn't win the race so give up on registering
+                unlock( mutex_lock );
+                return false;
+            }
         }
     }
@@ -422,9 +438,26 @@
     #endif
 
-    // check if we can complete operation. If so race to establish winner in special OR case
-    if ( !node.park_counter && ( count != size || !cons`isEmpty || unlikely(closed) ) ) {
-        if ( !__make_select_node_available( node ) ) { // we didn't win the race so give up on registering
-           unlock( mutex_lock );
-           return false;
+    // special OR case handling
+    if ( !node.park_counter ) {
+        // are we special case OR and front of cons is also special case OR
+        if ( !unlikely(closed) && !cons`isEmpty && cons`first.clause_status && !cons`first.park_counter ) {
+            if ( !__make_select_node_pending( node ) ) {
+                unlock( mutex_lock );
+                return false;
+            }
+            
+            if ( __handle_waituntil_OR( cons ) ) {
+                __cons_handoff( chan, elem );
+                unlock( mutex_lock );
+                return true;
+            }
+            __make_select_node_unsat( node );
+        }
+        // check if we can complete operation. If so race to establish winner in special OR case
+        if ( count != size || !cons`isEmpty || unlikely(closed) ) {
+            if ( !__make_select_node_available( node ) ) { // we didn't win the race so give up on registering
+                unlock( mutex_lock );
+                return false;
+            }
         }
     }
Index: libcfa/src/concurrency/select.hfa
===================================================================
--- libcfa/src/concurrency/select.hfa	(revision d5187a0603e2d2c1c0fbac8a65e8639c613b5708)
+++ libcfa/src/concurrency/select.hfa	(revision 253a78ffaf6f91bf8f04bc8188716a454112fff7)
@@ -2,6 +2,8 @@
 
 #include "containers/list.hfa"
+// #include "alarm.hfa"
 #include "stdint.h"
 #include "kernel.hfa"
+#include "time.hfa"
 
 struct select_node;
@@ -9,7 +11,10 @@
 // node status
 static const unsigned long int __SELECT_UNSAT = 0;
-static const unsigned long int __SELECT_SAT = 1;
-static const unsigned long int __SELECT_RUN = 2;
+static const unsigned long int __SELECT_PENDING = 1; // used only by special OR case
+static const unsigned long int __SELECT_SAT = 2;
+static const unsigned long int __SELECT_RUN = 3;
 
+
+// these are used inside the compiler to aid in code generation
 static inline bool __CFA_has_clause_run( unsigned long int status ) { return status == __SELECT_RUN; }
 static inline void __CFA_maybe_park( int * park_counter ) {
@@ -50,8 +55,15 @@
     this.extra = extra;
 }
-
 static inline void ^?{}( select_node & this ) {}
 
+// this is used inside the compiler to aid in code generation
 static inline unsigned long int * __get_clause_status( select_node & s ) { return s.clause_status; }
+
+// this is used inside the compiler to attempt to establish an else clause as a winner in the OR special case race
+static inline bool __select_node_else_race( select_node & this ) with( this ) {
+    unsigned long int cmp_status = __SELECT_UNSAT;
+    return *clause_status == 0 
+            && __atomic_compare_exchange_n( clause_status, &cmp_status, __SELECT_SAT, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST );
+}
 
 //-----------------------------------------------------------------------------
@@ -73,9 +85,27 @@
 };
 
-// this is used inside the compiler to attempt to establish an else clause as a winner in the OR special case race
-static inline bool __select_node_else_race( select_node & this ) with( this ) {
+//=============================================================================================
+// Waituntil Helpers
+//=============================================================================================
+
+// used for the 2-stage avail needed by the special OR case
+static inline bool __mark_select_node( select_node & this, unsigned long int val ) with( this ) {
+    /* paranoid */ verify( park_counter == 0p );
+    /* paranoid */ verify( clause_status != 0p );
+
     unsigned long int cmp_status = __SELECT_UNSAT;
-    return *clause_status == 0 
-            && __atomic_compare_exchange_n( clause_status, &cmp_status, 1, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST );
+    while( !__atomic_compare_exchange_n( clause_status, &cmp_status, val, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) {
+        if ( cmp_status != __SELECT_PENDING ) return false;
+        cmp_status = __SELECT_UNSAT;
+    }
+    return true;
+}
+
+static inline void __make_select_node_unsat( select_node & this ) with( this ) {
+    __atomic_store_n( clause_status, __SELECT_UNSAT, __ATOMIC_SEQ_CST );
+}
+
+static inline bool __make_select_node_pending( select_node & this ) with( this ) {
+    return __mark_select_node( this, __SELECT_PENDING );
 }
 
@@ -83,11 +113,13 @@
 // return true if we want to unpark the thd
 static inline bool __make_select_node_available( select_node & this ) with( this ) {
+    /* paranoid */ verify( clause_status != 0p );
+    if( !park_counter )
+        return __mark_select_node( this, (unsigned long int)&this );
+    // return *clause_status == 0 
+    //     && __atomic_compare_exchange_n( clause_status, &cmp_status, (unsigned long int)&this, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ); // OR specific case where race was won
+
     unsigned long int cmp_status = __SELECT_UNSAT;
 
-    if( !park_counter ) 
-        return *clause_status == 0 
-            && __atomic_compare_exchange_n( clause_status, &cmp_status, (unsigned long int)&this, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ); // OR specific case where race was won
-
-    return *clause_status == 0
+    return *clause_status == 0 // C_TODO might not need a cmp_xchg in non special OR case
         && __atomic_compare_exchange_n( clause_status, &cmp_status, __SELECT_SAT, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) // can maybe just use atomic write
         && !__atomic_add_fetch( park_counter, 1, __ATOMIC_SEQ_CST);
@@ -128,2 +160,3 @@
 }
 
+
