Index: libcfa/src/concurrency/coroutine.cfa
===================================================================
--- libcfa/src/concurrency/coroutine.cfa	(revision 113d785d478f1c0f6f9919409f7ef21040acaa47)
+++ libcfa/src/concurrency/coroutine.cfa	(revision 1c01c5836c12d14d4c519d76550c0381bc562aaf)
@@ -47,4 +47,45 @@
 
 //-----------------------------------------------------------------------------
+FORALL_DATA_INSTANCE(CoroutineCancelled,
+		(dtype coroutine_t | sized(coroutine_t)), (coroutine_t))
+
+struct __cfaehm_node {
+	struct _Unwind_Exception unwind_exception;
+	struct __cfaehm_node * next;
+	int handler_index;
+};
+
+forall(dtype T)
+void mark_exception(CoroutineCancelled(T) *) {}
+
+forall(dtype T | sized(T))
+void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src) {
+	dst->the_coroutine = src->the_coroutine;
+	dst->the_exception = src->the_exception;
+}
+
+forall(dtype T)
+const char * msg(CoroutineCancelled(T) *) {
+	return "CoroutineCancelled(...)";
+}
+
+// This code should not be inlined. It is the error path on resume.
+forall(dtype T | is_coroutine(T))
+void __cfaehm_cancelled_coroutine( T & cor, $coroutine * desc ) {
+	verify( desc->cancellation );
+	desc->state = Cancelled;
+	exception_t * except = (exception_t *)(1 + (__cfaehm_node *)desc->cancellation);
+
+	CoroutineCancelled(T) except;
+	except.the_coroutine = &cor;
+	except.the_exception = except;
+	throwResume except;
+
+	except->virtual_table->free( except );
+	free( desc->cancellation );
+	desc->cancellation = 0p;
+}
+
+//-----------------------------------------------------------------------------
 // Global state variables
 
@@ -180,4 +221,6 @@
 	this->storage->limit = storage;
 	this->storage->base  = (void*)((intptr_t)storage + size);
+	this->storage->exception_context.top_resume = 0p;
+	this->storage->exception_context.current_exception = 0p;
 	__attribute__((may_alias)) intptr_t * istorage = (intptr_t*)&this->storage;
 	*istorage |= userStack ? 0x1 : 0x0;
Index: libcfa/src/concurrency/coroutine.hfa
===================================================================
--- libcfa/src/concurrency/coroutine.hfa	(revision 113d785d478f1c0f6f9919409f7ef21040acaa47)
+++ libcfa/src/concurrency/coroutine.hfa	(revision 1c01c5836c12d14d4c519d76550c0381bc562aaf)
@@ -18,4 +18,23 @@
 #include <assert.h>
 #include "invoke.h"
+#include "../exception.hfa"
+
+//-----------------------------------------------------------------------------
+// Exception thrown from resume when a coroutine stack is cancelled.
+// Should not have to be be sized (see trac #196).
+FORALL_DATA_EXCEPTION(CoroutineCancelled,
+		(dtype coroutine_t | sized(coroutine_t)), (coroutine_t)) (
+	coroutine_t * the_coroutine;
+	exception_t * the_exception;
+);
+
+forall(dtype T)
+void mark_exception(CoroutineCancelled(T) *);
+
+forall(dtype T | sized(T))
+void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src);
+
+forall(dtype T)
+const char * msg(CoroutineCancelled(T) *);
 
 //-----------------------------------------------------------------------------
@@ -23,7 +42,9 @@
 // Anything that implements this trait can be resumed.
 // Anything that is resumed is a coroutine.
-trait is_coroutine(dtype T) {
-      void main(T & this);
-      $coroutine * get_coroutine(T & this);
+trait is_coroutine(dtype T | sized(T)
+		| is_resumption_exception(CoroutineCancelled(T))
+		| VTABLE_ASSERTION(CoroutineCancelled, (T))) {
+	void main(T & this);
+	$coroutine * get_coroutine(T & this);
 };
 
@@ -112,4 +133,7 @@
 	}
 }
+
+forall(dtype T | is_coroutine(T))
+void __cfaehm_cancelled_coroutine( T & cor, $coroutine * desc );
 
 // Resume implementation inlined for performance
@@ -145,4 +169,7 @@
 	// always done for performance testing
 	$ctx_switch( src, dst );
+	if ( unlikely(dst->cancellation) ) {
+		__cfaehm_cancelled_coroutine( cor, dst );
+	}
 
 	return cor;
Index: libcfa/src/concurrency/exception.cfa
===================================================================
--- libcfa/src/concurrency/exception.cfa	(revision 113d785d478f1c0f6f9919409f7ef21040acaa47)
+++ libcfa/src/concurrency/exception.cfa	(revision 1c01c5836c12d14d4c519d76550c0381bc562aaf)
@@ -57,5 +57,8 @@
 
 STOP_AT_END_FUNCTION(coroutine_cancelstop,
-	// TODO: Instead pass information to the last resumer.
+	struct $coroutine * src = ($coroutine *)stop_param;
+	struct $coroutine * dst = src->last;
+
+	$ctx_switch( src, dst );
 	abort();
 )
Index: libcfa/src/concurrency/exception.hfa
===================================================================
--- libcfa/src/concurrency/exception.hfa	(revision 113d785d478f1c0f6f9919409f7ef21040acaa47)
+++ libcfa/src/concurrency/exception.hfa	(revision 1c01c5836c12d14d4c519d76550c0381bc562aaf)
@@ -18,11 +18,11 @@
 #include "bits/defs.hfa"
 #include "invoke.h"
-struct _Unwind_Exception;
-
-// It must also be usable as a C header file.
 
 #ifdef __cforall
 extern "C" {
+
+#define HIDE_EXPORTS
 #endif
+#include "unwind.h"
 
 struct exception_context_t * this_exception_context(void) OPTIONAL_THREAD;
@@ -32,4 +32,5 @@
 
 #ifdef __cforall
+#undef HIDE_EXPORTS
 }
 #endif
Index: libcfa/src/concurrency/invoke.h
===================================================================
--- libcfa/src/concurrency/invoke.h	(revision 113d785d478f1c0f6f9919409f7ef21040acaa47)
+++ libcfa/src/concurrency/invoke.h	(revision 1c01c5836c12d14d4c519d76550c0381bc562aaf)
@@ -68,5 +68,5 @@
 	};
 
-	enum __Coroutine_State { Halted, Start, Primed, Blocked, Ready, Active };
+	enum __Coroutine_State { Halted, Start, Primed, Blocked, Ready, Active, Cancelled };
 
 	struct $coroutine {
Index: libcfa/src/exception.h
===================================================================
--- libcfa/src/exception.h	(revision 113d785d478f1c0f6f9919409f7ef21040acaa47)
+++ libcfa/src/exception.h	(revision 1c01c5836c12d14d4c519d76550c0381bc562aaf)
@@ -76,22 +76,22 @@
 // implemented in the .c file either so they all have to be inline.
 
-trait is_exception(dtype T) {
+trait is_exception(dtype exceptT) {
 	/* The first field must be a pointer to a virtual table.
 	 * That virtual table must be a decendent of the base exception virtual tab$
 	 */
-	void mark_exception(T *);
+	void mark_exception(exceptT *);
 	// This is never used and should be a no-op.
 };
 
-trait is_termination_exception(dtype T | is_exception(T)) {
-	void defaultTerminationHandler(T &);
+trait is_termination_exception(dtype exceptT | is_exception(exceptT)) {
+	void defaultTerminationHandler(exceptT &);
 };
 
-trait is_resumption_exception(dtype T | is_exception(T)) {
-	void defaultResumptionHandler(T &);
+trait is_resumption_exception(dtype exceptT | is_exception(exceptT)) {
+	void defaultResumptionHandler(exceptT &);
 };
 
-forall(dtype T | is_termination_exception(T))
-static inline void $throw(T & except) {
+forall(dtype exceptT | is_termination_exception(exceptT))
+static inline void $throw(exceptT & except) {
 	__cfaehm_throw_terminate(
 		(exception_t *)&except,
@@ -100,6 +100,6 @@
 }
 
-forall(dtype T | is_resumption_exception(T))
-static inline void $throwResume(T & except) {
+forall(dtype exceptT | is_resumption_exception(exceptT))
+static inline void $throwResume(exceptT & except) {
 	__cfaehm_throw_resume(
 		(exception_t *)&except,
@@ -108,16 +108,16 @@
 }
 
-forall(dtype T | is_exception(T))
-static inline void cancel_stack(T & except) __attribute__((noreturn)) {
+forall(dtype exceptT | is_exception(exceptT))
+static inline void cancel_stack(exceptT & except) __attribute__((noreturn)) {
 	__cfaehm_cancel_stack( (exception_t *)&except );
 }
 
-forall(dtype T | is_exception(T))
-static inline void defaultTerminationHandler(T & except) {
+forall(dtype exceptT | is_exception(exceptT))
+static inline void defaultTerminationHandler(exceptT & except) {
 	return cancel_stack( except );
 }
 
-forall(dtype T | is_exception(T))
-static inline void defaultResumptionHandler(T & except) {
+forall(dtype exceptT | is_exception(exceptT))
+static inline void defaultResumptionHandler(exceptT & except) {
 	throw except;
 }
Index: libcfa/src/exception.hfa
===================================================================
--- libcfa/src/exception.hfa	(revision 113d785d478f1c0f6f9919409f7ef21040acaa47)
+++ libcfa/src/exception.hfa	(revision 1c01c5836c12d14d4c519d76550c0381bc562aaf)
@@ -192,5 +192,5 @@
 		size_t size; \
 		void (*copy)(exception_name * this, exception_name * other); \
-		void (*free)(exception_name & this); \
+		void (*^?{})(exception_name & this); \
 		const char * (*msg)(exception_name * this); \
 		_CLOSE
@@ -213,5 +213,5 @@
 		size_t size; \
 		void (*copy)(exception_name parameters * this, exception_name parameters * other); \
-		void (*free)(exception_name parameters & this); \
+		void (*^?{})(exception_name parameters & this); \
 		const char * (*msg)(exception_name parameters * this); \
 		_CLOSE
