diff -uwr jack-u/include/engine.h jack-p/include/engine.h
--- jack-u/include/engine.h	2016-02-16 09:12:35.153657784 -0500
+++ jack-p/include/engine.h	2016-02-16 09:12:49.101885189 -0500
@@ -144,13 +144,6 @@
 	JSList         *clients_waiting;
 	JSList         *reserved_client_names;
 
-	/* Double linked list of clients in running order */
-	jack_client_internal_t  *execlist_head;
-	jack_client_internal_t  *execlist_tail;
-#define EXECLIST_ORDER 1        /* Re-order clients */
-#define EXECLIST_CYCLE 2        /* Check cycles */
-	int execlist_request;
-
 	jack_port_internal_t    *internal_ports;
 	jack_client_internal_t  *timebase_client;
 	jack_port_buffer_info_t *silent_buffer;
diff -uwr jack-u/include/internal.h jack-p/include/internal.h
--- jack-u/include/internal.h	2016-02-16 09:12:35.165657979 -0500
+++ jack-p/include/internal.h	2016-02-16 09:12:49.113885384 -0500
@@ -452,18 +452,6 @@
 	int32_t status;
 } POST_PACKED_STRUCTURE;
 
-
-/* Data used by the algorithm determining running order
- * of clients.
- */
-typedef struct _jack_feedcounts {
-	struct _jack_feedcounts  *next;
-	struct _jack_client_internal *client;
-	int fwd_count;
-	int rev_count;
-} jack_feedcounts_t;
-
-
 /* Per-client structure allocated in the server's address space.
  * It's here because its not part of the engine structure.
  */
@@ -476,18 +464,14 @@
 	int event_fd;
 	int subgraph_start_fd;
 	int subgraph_wait_fd;
-
-	/* protected by engine->client_lock */
-	JSList    *ports;
-
-	jack_feedcounts_t  *feedlist;
-	struct  _jack_client_internal *execlist_next;
-	struct  _jack_client_internal *execlist_prev;
-	int depcount;
-	int depcheck;
-
+	JSList    *ports;       /* protected by engine->client_lock */
+	JSList    *truefeeds;   /* protected by engine->client_lock */
+	JSList    *sortfeeds;   /* protected by engine->client_lock */
+	int fedcount;
+	int tfedcount;
 	jack_shm_info_t control_shm;
 	unsigned long execution_order;
+	struct  _jack_client_internal *next_client;     /* not a linked list! */
 	dlhandle handle;
 	int (*initialize)(jack_client_t*, const char*); /* int. clients only */
 	void (*finish)(void *);                         /* internal clients only */
diff -uwr jack-u/jackd/clientengine.c jack-p/jackd/clientengine.c
--- jack-u/jackd/clientengine.c	2016-02-16 09:12:35.201658567 -0500
+++ jack-p/jackd/clientengine.c	2016-02-16 09:12:49.149885971 -0500
@@ -62,13 +62,13 @@
 	}
 
 	jack_slist_free (client->ports);
+	jack_slist_free (client->truefeeds);
+	jack_slist_free (client->sortfeeds);
+	client->truefeeds = 0;
+	client->sortfeeds = 0;
 	client->ports = 0;
 }
 
-
-/* Modified for new client execution order algorithm.
- * FA 08/2015
- */
 int
 jack_client_do_deactivate (jack_engine_t *engine,
 			   jack_client_internal_t *client, int sort_graph)
@@ -88,7 +88,6 @@
 	}
 
 	if (sort_graph) {
-		engine->execlist_request = EXECLIST_ORDER | EXECLIST_CYCLE;
 		jack_sort_graph (engine);
 	}
 	return 0;
@@ -163,6 +162,7 @@
 		 client->control->name);
 
 	/* caller must hold the client_lock */
+
 	/* this stops jack_deliver_event() from contacing this client */
 
 	client->control->dead = TRUE;
@@ -337,9 +337,6 @@
 	return errs;
 }
 
-/* Modified for new client execution order algorithm.
- * FA 08/2015
- */
 void
 jack_remove_clients (jack_engine_t* engine, int* exit_freewheeling_when_done)
 {
@@ -407,7 +404,6 @@
 	}
 
 	if (need_sort) {
-		engine->execlist_request = EXECLIST_ORDER | EXECLIST_CYCLE;
 		jack_sort_graph (engine);
 	}
 
@@ -568,9 +564,6 @@
 
 /* Set up the engine's client internal and control structures for both
  * internal and external clients. */
-/* Modified for new client execution order algorithm.
- * FA 08/2015
- */
 static jack_client_internal_t *
 jack_setup_client_control (jack_engine_t *engine, int fd, ClientType type, const char *name, jack_uuid_t uuid)
 {
@@ -582,11 +575,10 @@
 	client->request_fd = fd;
 	client->event_fd = -1;
 	client->ports = 0;
-	client->feedlist = 0;
-	client->depcount = 0;
-	client->depcheck = 0;
-	client->execlist_next = 0;
+	client->truefeeds = 0;
+	client->sortfeeds = 0;
 	client->execution_order = UINT_MAX;
+	client->next_client = NULL;
 	client->handle = NULL;
 	client->finish = NULL;
 	client->error = 0;
@@ -772,15 +764,19 @@
 	jack_engine_reset_rolling_usecs (engine);
 
 	if (jack_client_is_internal (client)) {
+
+
 		jack_unlock_graph (engine);
 
 		/* Call its initialization function.  This function
 		 * may make requests of its own, so we temporarily
 		 * release and then reacquire the request_lock.  */
 		if (client->control->type == ClientInternal) {
+
 			pthread_mutex_unlock (&engine->request_lock);
 			if (client->initialize (client->private_client,
 						object_data)) {
+
 				/* failed: clean up client data */
 				VERBOSE (engine,
 					 "%s jack_initialize() failed!",
@@ -796,7 +792,8 @@
 			pthread_mutex_lock (&engine->request_lock);
 		}
 
-	} else {
+	} else {                        /* external client */
+
 		jack_unlock_graph (engine);
 	}
 
@@ -867,7 +864,6 @@
 	}
 	return 0;
 }
-
 int
 jack_client_create (jack_engine_t *engine, int client_fd)
 {
@@ -977,10 +973,6 @@
 	return 0;
 }
 
-
-/* Modified for new client execution order algorithm.
- * FA 08/2015
- */
 int
 jack_client_activate (jack_engine_t *engine, jack_uuid_t id)
 {
@@ -1005,8 +997,8 @@
 		 * this point.
 		 */
 
-		jack_get_fifo_fd (engine, ++engine->external_client_cnt);
-		engine->execlist_request = EXECLIST_ORDER;
+		jack_get_fifo_fd (engine,
+				  ++engine->external_client_cnt);
 		jack_sort_graph (engine);
 
 
diff -uwr jack-u/jackd/engine.c jack-p/jackd/engine.c
--- jack-u/jackd/engine.c	2016-02-16 09:12:35.265659610 -0500
+++ jack-p/jackd/engine.c	2016-02-16 09:12:49.209886950 -0500
@@ -71,6 +71,7 @@
 
 	jack_port_internal_t *source;
 	jack_port_internal_t *destination;
+	signed int dir; /* -1 = feedback, 0 = self, 1 = forward */
 	jack_client_internal_t *srcclient;
 	jack_client_internal_t *dstclient;
 } jack_connection_internal_t;
@@ -126,6 +127,11 @@
 			      float delayed_usecs);
 static void jack_engine_driver_exit(jack_engine_t* engine);
 static int  jack_start_freewheeling(jack_engine_t* engine, jack_uuid_t);
+static int jack_client_feeds_transitive(jack_client_internal_t *source,
+					jack_client_internal_t *dest);
+static int jack_client_sort(jack_client_internal_t *a,
+			    jack_client_internal_t *b);
+static void jack_check_acyclic(jack_engine_t* engine);
 static void jack_compute_all_port_total_latencies(jack_engine_t *engine);
 static void jack_compute_port_total_latency(jack_engine_t *engine, jack_port_shared_t*);
 static int jack_check_client_status(jack_engine_t* engine);
@@ -566,20 +572,21 @@
 }
 
 
-/* Modified to use the new double-linked list of clients in execution order
- * FA 08/2015
- */
-static jack_client_internal_t*
-jack_process_internal (jack_engine_t *engine, jack_client_internal_t *client,
+static JSList *
+jack_process_internal (jack_engine_t *engine, JSList *node,
 		       jack_nframes_t nframes)
 {
+	jack_client_internal_t *client;
 	jack_client_control_t *ctl;
 
+	client = (jack_client_internal_t*)node->data;
 	ctl = client->control;
-	ctl->state = Running;
-	engine->current_client = client;
+
+	/* internal client */
 
 	DEBUG ("invoking an internal client's (%s) callbacks", ctl->name);
+	ctl->state = Running;
+	engine->current_client = client;
 
 	/* XXX how to time out an internal client? */
 
@@ -601,10 +608,11 @@
 	ctl->state = Finished;
 
 	if (engine->process_errors) {
-		return NULL;
-	} else {      return client->execlist_next; }
+		return NULL;            /* will stop the loop */
+	} else {
+		return jack_slist_next (node);
+	}
 }
-
 
 #ifdef __linux
 
@@ -642,22 +650,18 @@
 }
 #endif
 
-
 #ifdef JACK_USE_MACH_THREADS
-
-/* Modified to use the new double-linked list of clients in execution order.
- * Unlike the Linux version, this just returns the next client in the list,
- * as did the original. I'm not sure if I understand how this works and
- * can't test it, but it seems to be correct.
- * FA 08/2015
- */
-static jack_client_internal *
-jack_process_external (jack_engine_t *engine, jack_client_internal_t *client)
+static JSList *
+jack_process_external (jack_engine_t *engine, JSList *node)
 {
+	jack_client_internal_t * client = (jack_client_internal_t*)node->data;
 	jack_client_control_t *ctl;
 
-	engine->current_client = client;
+	client = (jack_client_internal_t*)node->data;
 	ctl = client->control;
+
+	engine->current_client = client;
+
 	// a race exists if we do this after the write(2)
 	ctl->state = Triggered;
 	ctl->signalled_at = jack_get_microseconds ();
@@ -667,32 +671,35 @@
 		ctl->state = Finished;
 	}
 
-	return client->execlist_next;
+	return jack_slist_next (node);
 }
-
 #else /* !JACK_USE_MACH_THREADS */
-
-/* Modified to use the new double-linked list of clients in execution order.
- * FA 08/2015
- */
-static jack_client_internal_t *
-jack_process_external (jack_engine_t *engine, jack_client_internal_t *client)
+static JSList *
+jack_process_external (jack_engine_t *engine, JSList *node)
 {
 	int status = 0;
 	char c = 0;
 	struct pollfd pfd[1];
 	int poll_timeout;
 	jack_time_t poll_timeout_usecs;
+	jack_client_internal_t *client;
 	jack_client_control_t *ctl;
 	jack_time_t now, then;
 	int pollret;
 
-	engine->current_client = client;
+	client = (jack_client_internal_t*)node->data;
+
 	ctl = client->control;
+
+	/* external subgraph */
+
 	/* a race exists if we do this after the write(2) */
 	ctl->state = Triggered;
+
 	ctl->signalled_at = jack_get_microseconds ();
 
+	engine->current_client = client;
+
 	DEBUG ("calling process() on an external subgraph, fd==%d",
 	       client->subgraph_start_fd);
 
@@ -737,16 +744,22 @@
 	}
 
 	if (pfd[0].revents & POLLIN) {
+
 		status = 0;
 
 	} else if (status == 0) {
-		/* no events, no errors, we woke up because poll() decided that time was up ... */
+
+		/* no events, no errors, we woke up because poll()
+		   decided that time was up ...
+		 */
+
 		if (engine->freewheeling) {
 			if (jack_check_client_status (engine)) {
 				return NULL;
 			} else {
 				/* all clients are fine - we're just not done yet. since
-				   we're freewheeling, that is fine. */
+				   we're freewheeling, that is fine.
+				 */
 				goto again;
 			}
 		}
@@ -760,6 +773,7 @@
 			VERBOSE (engine, "FALSE WAKEUP skipped, remaining = %lld usec", poll_timeout_usecs);
 		} else {
 #endif
+
 		jack_error ("subgraph starting at %s timed out "
 			    "(subgraph_wait_fd=%d, status = %d, state = %s, pollret = %d revents = 0x%x)",
 			    client->control->name,
@@ -791,6 +805,7 @@
 					     ctl->signalled_at) : 0);
 
 		if (jack_check_clients (engine, 1)) {
+
 			engine->process_errors++;
 			return NULL;            /* will stop the loop */
 		}
@@ -802,7 +817,8 @@
 	DEBUG ("reading byte from subgraph_wait_fd==%d",
 	       client->subgraph_wait_fd);
 
-	if (read (client->subgraph_wait_fd, &c, sizeof(c)) != sizeof(c)) {
+	if (read (client->subgraph_wait_fd, &c, sizeof(c))
+	    != sizeof(c)) {
 		if (errno == EAGAIN) {
 			jack_error ("pp: cannot clean up byte from graph wait "
 				    "fd - no data present");
@@ -815,57 +831,58 @@
 	}
 
 	/* Move to next internal client (or end of client list) */
-	while (client) {
-		if (jack_client_is_internal (client)) {
+	while (node) {
+		if (jack_client_is_internal ((jack_client_internal_t*)
+					     node->data)) {
 			break;
 		}
-		client = client->execlist_next;
+		node = jack_slist_next (node);
 	}
-	return client;
+
+	return node;
 }
 
 #endif /* JACK_USE_MACH_THREADS */
 
-
-/* Modified to use the new double-linked list of clients in execution order.
- * FA 08/2015
- */
 static int
 jack_engine_process (jack_engine_t *engine, jack_nframes_t nframes)
 {
 	/* precondition: caller has graph_lock */
 	jack_client_internal_t *client;
+	JSList *node;
 
 	engine->process_errors = 0;
 
-	for (client = engine->execlist_head; client; client = client->execlist_next) {
-		jack_client_control_t *ctl = client->control;
+	for (node = engine->clients; node; node = jack_slist_next (node)) {
+		jack_client_control_t *ctl =
+			((jack_client_internal_t*)node->data)->control;
 		ctl->state = NotTriggered;
 		ctl->timed_out = 0;
 		ctl->awake_at = 0;
 		ctl->finished_at = 0;
 	}
 
+	for (node = engine->clients; engine->process_errors == 0 && node; ) {
 
-	client = engine->execlist_head;
-	while (client) {
-		DEBUG ("considering client %s for processing", client->control->name);
+		client = (jack_client_internal_t*)node->data;
+
+		DEBUG ("considering client %s for processing",
+		       client->control->name);
 
 		if (!client->control->active ||
 		    (!client->control->process_cbset && !client->control->thread_cb_cbset) ||
 		    client->control->dead) {
-			client = client->execlist_next;
+			node = jack_slist_next (node);
 		} else if (jack_client_is_internal (client)) {
-			client = jack_process_internal (engine, client, nframes);
+			node = jack_process_internal (engine, node, nframes);
 		} else {
-			client = jack_process_external (engine, client);
+			node = jack_process_external (engine, node);
 		}
 	}
 
 	return engine->process_errors > 0;
 }
 
-
 static void
 jack_calc_cpu_load (jack_engine_t *engine)
 {
@@ -1833,13 +1850,6 @@
 	engine->clients = 0;
 	engine->reserved_client_names = 0;
 
-	/* Added new double-linked list of clients in execution order.
-	 * FA 08/2015
-	 */
-	engine->execlist_head = 0;
-	engine->execlist_tail = 0;
-	engine->execlist_request = 0;
-
 	engine->pfd_size = 0;
 	engine->pfd_max = 0;
 	engine->pfd = 0;
@@ -3172,89 +3182,159 @@
 	return status;
 }
 
-
-/* Modified to use the new double-linked list of clients in execution order
- * FA 08/2015
- */
 int
 jack_rechain_graph (jack_engine_t *engine)
 {
-	jack_client_internal_t *client, *subgraph_client;
+	JSList *node, *next;
+	unsigned long n;
+	int err = 0;
+	jack_client_internal_t *subgraph_client, *next_client;
 	jack_event_t event;
 	int upstream_is_jackd;
-	unsigned long n;
 
-
-	VERBOSE (engine, "++ jack_rechain_graph():");
 	VALGRIND_MEMSET (&event, 0, sizeof(event));
 
 	jack_clear_fifos (engine);
+
 	subgraph_client = 0;
 
+	VERBOSE (engine, "++ jack_rechain_graph():");
+
 	event.type = GraphReordered;
 
-	n = 0;
-	for (client = engine->execlist_head; client; client = client->execlist_next) {
-		/* We are only interested in active clients that have a process callback */
-		if (!client->control->active ||
-		    (!client->control->process_cbset && !client->control->thread_cb_cbset)) {
+	for (n = 0, node = engine->clients, next = NULL; node; node = next) {
+
+		jack_client_internal_t* client = (jack_client_internal_t*)node->data;
+
+		next = jack_slist_next (node);
+
+		if (!client->control->process_cbset && !client->control->thread_cb_cbset) {
 			continue;
 		}
 
-		VERBOSE (engine, "+++ client is now %s", client->control->name);
+		VERBOSE (engine, "+++ client is now %s active ? %d",
+			 client->control->name, client->control->active);
+
+		if (client->control->active) {
+
+			/* find the next active client. its ok for
+			 * this to be NULL */
+
+			while (next) {
+				if (client->control->active && (client->control->process_cbset || client->control->thread_cb_cbset)) {
+					break;
+				}
+				next = jack_slist_next (next);
+			}
+			;
+
+			if (next == NULL) {
+				next_client = NULL;
+			} else {
+				next_client = (jack_client_internal_t*)
+					      next->data;
+			}
 
 		client->execution_order = n;
+			client->next_client = next_client;
 
 		if (jack_client_is_internal (client)) {
-			/* Break the chain for the current subgraph. The server will
-			 * wait for the chain on the nth FIFO, and will then execute
-			 * this internal client. */
+
+				/* break the chain for the current
+				 * subgraph. the server will wait for
+				 * chain on the nth FIFO, and will
+				 * then execute this internal
+				 * client. */
+
 			if (subgraph_client) {
-				subgraph_client->subgraph_wait_fd = jack_get_fifo_fd (engine, n);
-				VERBOSE (engine, "client %s: wait_fd=%d execution_order=%lu.",
-					 subgraph_client->control->name,
-					 subgraph_client->subgraph_wait_fd, n);
+					subgraph_client->subgraph_wait_fd =
+						jack_get_fifo_fd (engine, n);
+					VERBOSE (engine, "client %s: wait_fd="
+						 "%d, execution_order="
+						 "%lu.",
+						 subgraph_client->
+						 control->name,
+						 subgraph_client->
+						 subgraph_wait_fd, n);
 				n++;
 			}
-			VERBOSE (engine, "client %s: internal client, execution_order=%lu.",
+
+				VERBOSE (engine, "client %s: internal "
+					 "client, execution_order="
+					 "%lu.",
 				 client->control->name, n);
 
-			/* this does the right thing for internal clients too */
+				/* this does the right thing for
+				 * internal clients too
+				 */
+
 			jack_deliver_event (engine, client, &event);
+
 			subgraph_client = 0;
+
 		} else {
-			if (subgraph_client) {
-				/* continue current subgraph. */
-				subgraph_client->subgraph_wait_fd = -1;
-				upstream_is_jackd = 0;
-				VERBOSE (engine, "client %s: in subgraph after %s, "
-					 "execution_order=%lu.",
-					 client->control->name,
-					 subgraph_client->control->name, n);
-			} else {
-				/* start a new subgraph. The engine will start the chain
-				 * by writing to the nth FIFO. */
+
+				if (subgraph_client == NULL) {
+
+					/* start a new subgraph. the
+					 * engine will start the chain
+					 * by writing to the nth
+					 * FIFO.
+					 */
+
 				subgraph_client = client;
-				subgraph_client->subgraph_start_fd = jack_get_fifo_fd (engine, n);
+					subgraph_client->subgraph_start_fd =
+						jack_get_fifo_fd (engine, n);
+					VERBOSE (engine, "client %s: "
+						 "start_fd=%d, execution"
+						 "_order=%lu.",
+						 subgraph_client->
+						 control->name,
+						 subgraph_client->
+						 subgraph_start_fd, n);
+
+					/* this external client after
+					   this will have jackd as its
+					   upstream connection.
+					 */
+
 				upstream_is_jackd = 1;
-				VERBOSE (engine, "client %s: start_fd=%d "
-					 "execution_order=%lu.",
-					 subgraph_client->control->name,
-					 subgraph_client->subgraph_start_fd, n);
+
+				} else {
+					VERBOSE (engine, "client %s: in"
+						 " subgraph after %s, "
+						 "execution_order="
+						 "%lu.",
+						 client->control->name,
+						 subgraph_client->
+						 control->name, n);
+					subgraph_client->subgraph_wait_fd = -1;
+
+					/* this external client after
+					   this will have another
+					   client as its upstream
+					   connection.
+					 */
+
+					upstream_is_jackd = 0;
 			}
 
-			/* make sure fifo for 'n + 1' exists before issuing client reorder. */
-			(void)jack_get_fifo_fd (engine, client->execution_order + 1);
+				/* make sure fifo for 'n + 1' exists
+				 * before issuing client reorder
+				 */
+				(void)jack_get_fifo_fd (
+					engine, client->execution_order + 1);
 			event.x.n = client->execution_order;
 			event.y.n = upstream_is_jackd;
 			jack_deliver_event (engine, client, &event);
 			n++;
 		}
 	}
+	}
 
 	if (subgraph_client) {
-		/* finish current subgraph. */
-		subgraph_client->subgraph_wait_fd = jack_get_fifo_fd (engine, n);
+		subgraph_client->subgraph_wait_fd =
+			jack_get_fifo_fd (engine, n);
 		VERBOSE (engine, "client %s: wait_fd=%d, "
 			 "execution_order=%lu (last client).",
 			 subgraph_client->control->name,
@@ -3262,9 +3342,9 @@
 	}
 
 	VERBOSE (engine, "-- jack_rechain_graph()");
-	return 0;
-}
 
+	return err;
+}
 
 static jack_nframes_t
 jack_get_port_total_latency (jack_engine_t *engine,
@@ -3398,11 +3478,13 @@
 
 	for (i = 0; i < engine->control->port_max; i++) {
 		if (shared[i].in_use) {
+
 			if (shared[i].flags & JackPortIsOutput) {
 				toward_port = FALSE;
 			} else {
 				toward_port = TRUE;
 			}
+
 			shared[i].total_latency =
 				jack_get_port_total_latency (
 					engine, &engine->internal_ports[i],
@@ -3411,328 +3493,238 @@
 	}
 }
 
-
-/* Modified to use the new double-linked list of clients in execution order
- * FA 08/2015
- */
 static void
 jack_compute_new_latency (jack_engine_t *engine)
 {
-	jack_client_internal_t* client;
+	JSList *node;
+	JSList *reverse_list = NULL;
 	jack_event_t event;
 
 	VALGRIND_MEMSET (&event, 0, sizeof(event));
-	event.type = LatencyCallback;
 
-	/* iterate over all clients in graph order and emit capture latency callback. */
+	event.type = LatencyCallback;
 	event.x.n = 0;
-	for (client = engine->execlist_head; client; client = client->execlist_next)
+
+	/* iterate over all clients in graph order, and emit
+	 * capture latency callback.
+	 * also builds up list in reverse graph order.
+	 */
+	for (node = engine->clients; node; node = jack_slist_next (node)) {
+
+		jack_client_internal_t* client = (jack_client_internal_t*)node->data;
+		reverse_list = jack_slist_prepend (reverse_list, client);
 		jack_deliver_event (engine, client, &event);
+	}
+
 	if (engine->driver) {
 		jack_deliver_event (engine, engine->driver->internal_client, &event);
 	}
 
-	/* iterate over all clients in reverse order and emit playback latency callback. */
+	/* now issue playback latency callbacks in reverse graphorder
+	 */
 	event.x.n = 1;
-	for (client = engine->execlist_tail; client; client = client->execlist_prev)
+	for (node = reverse_list; node; node = jack_slist_next (node)) {
+		jack_client_internal_t* client = (jack_client_internal_t*)node->data;
 		jack_deliver_event (engine, client, &event);
+	}
+
 	if (engine->driver) {
 		jack_deliver_event (engine, engine->driver->internal_client, &event);
 	}
+
+	jack_slist_free (reverse_list);
 }
 
 
-/* HOW THE SORT WORKS (new version)
- * FA 08/2015
- *
- * Each client has a linked list called 'feedlist' of other clients
- * directly depending on data from it. Element of the list are structs
- * of type jack_feedcounts_t, which contains:
- *
- *   .next      : pointer to the next list element (this is not a JSlist).
- *   .client    : pointer to the destination client depending on this one.
- *   .fwd_count : counter of forward direct connections.
- *   .rev_count : counter of reversed direct connections.
- *
- * The counters are incremented or decremented by port connect or disconnect
- * requests. At least one of them will be non-zero. Reversed dependencies
- * are those created by connections that create a cycle.
+/* How the sort works:
  *
- * As in the previous version, connections having the driver as destination
- * are ignored in order to avoid apparent cycles. Note: things just work
- * this way so this was not changed, but it would be cleaner to represent
- * the driver as two clients. This would allow to represent all dependencies
- * (which could be interesting for debugging) without creating fake cycles.
+ * Each client has a "sortfeeds" list of clients indicating which clients
+ * it should be considered as feeding for the purposes of sorting the
+ * graph. This list differs from the clients it /actually/ feeds in the
+ * following ways:
  *
- * In contrast to the previous version, there is no implicit dependency
- * of each client on the driver, this is created only when there is an
- * actual connection from the capture part. Other logic ensures that the
- * driver will run first anyway, even if no clients are connected to it
- * at all.
+ * 1. Connections from a client to itself are disregarded
  *
- * Each client also has a counter 'depcount' indicating from how many
- * other clients it requires input. This is always equal to the number
- * of other clients having a feedlist element referring to this one.
+ * 2. Connections to a driver client are disregarded
  *
- * The algorithm that actually determines the execution order is run only
- * when an element is added or revomed from any of the 'feedlist' lists,
- * and when clients are activated or deactivated. It consists of two
- * parts, each of them controlled by a binary flag maintained in
- * engine->execlist_requestm and, if necessary, set by the port connect
- * and disconnect routines.
+ * 3. If a connection from A to B is a feedback connection (ie there was
+ *    already a path from B to A when the connection was made) then instead
+ *    of B appearing on A's sortfeeds list, A will appear on B's sortfeeds
+ *    list.
  *
- * First, if the EXECLIST_CYCLE flag is set, we test if any feedback
- * connections can be reverted to normal ones. If there are any, we
- * also set the EXECLIST_ORDER flag in case it was not already set.
- * Second, if the EXECLIST_ORDER flag is set, a double linked list
- * of clients in execution order is constructed. This list is then
- * used by all other routines that control running a cycle.
+ * If client A is on client B's sortfeeds list, client A must come after
+ * client B in the execution order. The above 3 rules ensure that the
+ * sortfeeds relation is always acyclic so that all ordering constraints
+ * can actually be met.
  *
- * The 'sorting' works as follows. Each client has a 'depcheck' field
- * which is originally set to its 'depcount' value. The list is reset,
- * and the driver is added to it. Then we loop over the engine->clients
- * JSlist, and add any clients which have their 'depcheck' equal to
- * zero to the new list.
+ * Each client also has a "truefeeds" list which is the same as sortfeeds
+ * except that feedback connections appear normally instead of reversed.
+ * This is used to detect whether the graph has become acyclic.
  *
- * Whenever a client is added to the new list, its 'depcheck' is set to
- * -1 so that client won't be considered again, and we loop over its
- * 'feedlist' and decrement the 'depcheck' of each client on it. When
- * this decrements to zero, that client is added to the list recursively.
- *
- * The complexity of this algorithm is linear in the number of clients
- * plus the number of direct dependencies between them (i.e. the sum
- * of the lenghts of all feedlists). Multiple port connections between
- * the same clients count as a single dependency.
- *
- * Finally, the new double linked list is copied to the original
- * engine->clients JSlist. This ensures that in this list the driver
- * will always come before any active clients. It's not clear if this
- * is actually necessary, as all code related to running a cycle is
- * using the new list anyway (as far as I could verify), and all
- * other uses seem to be related to looking up client data only.
- *
- * Another open question is if jack_rechain_graph() needs to be
- * called if the order didn't change. If not, the call could be
- * moved to the place indicated in jack_check_execorder().
  */
 
-
-/* Test if there is a direct dependency of client B on client A.
- * This may be because A feeds B directly, or because there is
- * a feedback connection from B to A.
- * Returns the jack_feedcounts_t for the dependency if it exists,
- * zero otherwise.
- */
-static jack_feedcounts_t *
-depends_direct (jack_client_internal_t *A, jack_client_internal_t *B)
+void
+jack_sort_graph (jack_engine_t *engine)
 {
-	jack_feedcounts_t *F;
+	/* called, obviously, must hold engine->client_lock */
 
-	for (F = A->feedlist; F; F = F->next)
-		if (F->client == B) {
-			return F;
-		}
-	return 0;
+	VERBOSE (engine, "++ jack_sort_graph");
+	engine->clients = jack_slist_sort (engine->clients,
+					   (JCompareFunc)jack_client_sort);
+	jack_compute_all_port_total_latencies (engine);
+	jack_compute_new_latency (engine);
+	jack_rechain_graph (engine);
+	engine->timeout_count = 0;
+	VERBOSE (engine, "-- jack_sort_graph");
 }
 
-/* Test if client B depends on output from client A, either directly
- * or via other clients. Feedback connections are not considered in
- * this case. This is used to detect cycles.
- * Returns 1 if the dependency exists, 0 otherwise.
- */
 static int
-depends_closure (jack_client_internal_t *A, jack_client_internal_t *B)
+jack_client_sort (jack_client_internal_t *a, jack_client_internal_t *b)
 {
-	jack_feedcounts_t *F;
+	/* drivers are forced to the front, ie considered as sources
+	   rather than sinks for purposes of the sort */
 
-	for (F = A->feedlist; F; F = F->next) {
-		if (F->fwd_count == 0) {
-			continue;
-		}
-		if (F->client == B) {
+	if (jack_client_feeds_transitive (a, b) ||
+	    (a->control->type == ClientDriver &&
+	     b->control->type != ClientDriver)) {
+		return -1;
+	} else if (jack_client_feeds_transitive (b, a) ||
+		   (b->control->type == ClientDriver &&
+		    a->control->type != ClientDriver)) {
 			return 1;
-		} else {              return depends_closure (F->client, B); }
-	}
+	} else {
 	return 0;
 }
+}
 
-/* Create a new direct dependency of client B on client A.
- */
-static void
-add_depends (jack_client_internal_t *A, jack_client_internal_t *B, int fwd, int rev)
+/* transitive closure of the relation expressed by the sortfeeds lists. */
+static int
+jack_client_feeds_transitive (jack_client_internal_t *source,
+			      jack_client_internal_t *dest )
 {
-	jack_feedcounts_t *F;
+	jack_client_internal_t *med;
+	JSList *node;
 
-	F = (jack_feedcounts_t*)malloc (sizeof(jack_feedcounts_t));
-	F->client = B;
-	F->fwd_count = fwd;
-	F->rev_count = rev;
-	F->next = A->feedlist;
-	A->feedlist = F;
-	B->depcount++;
+	if (jack_slist_find (source->sortfeeds, dest)) {
+		return 1;
 }
 
-/* Delete a direct dependency of client B on client A.
- */
-static void
-rem_depends (jack_client_internal_t *A, jack_client_internal_t *B)
-{
-	jack_feedcounts_t *X, *Y;
+	for (node = source->sortfeeds; node; node = jack_slist_next (node)) {
 
-	for (X = 0, Y = A->feedlist; Y; X = Y, Y = Y->next) {
-		if (Y->client == B) {
-			if (X) {
-				X->next = Y->next;
-			} else {                      A->feedlist = Y->next; }
-			B->depcount--;
-			free (Y);
-			return;
-		}
+		med = (jack_client_internal_t*)node->data;
+
+		if (jack_client_feeds_transitive (med, dest)) {
+			return 1;
 	}
 }
 
+	return 0;
+}
 
-/* Add client C at the tail of the execution order list, and then
- * recursively test if any others can be run after C has finished.
+/**
+ * Checks whether the graph has become acyclic and if so modifies client
+ * sortfeeds lists to turn leftover feedback connections into normal ones.
+ * This lowers latency, but at the expense of some data corruption.
  */
 static void
-append_execlist (jack_engine_t *engine, jack_client_internal_t *C)
+jack_check_acyclic (jack_engine_t *engine)
 {
-	jack_client_internal_t *D;
-	jack_feedcounts_t *F;
+	JSList *srcnode, *dstnode, *portnode, *connnode;
+	jack_client_internal_t *src, *dst;
+	jack_port_internal_t *port;
+	jack_connection_internal_t *conn;
+	int stuck;
+	int unsortedclients = 0;
 
-	/* This client must not be considered again. */
-	C->depcheck = -1;
-	/* Append at end of list */
-	C->execlist_next = 0;
-	if (engine->execlist_tail) {
-		C->execlist_prev = engine->execlist_tail;
-		engine->execlist_tail->execlist_next = C;
-	} else {
-		C->execlist_prev = 0;
-		engine->execlist_head = C;
-	}
-	engine->execlist_tail = C;
-	/* Check if any others can be run after this one. */
-	for (F = C->feedlist; F; F = F->next) {
-		D = F->client;
-		if (--(D->depcheck) == 0) {
-			append_execlist (engine, D);
-		}
-	}
-}
+	VERBOSE (engine, "checking for graph become acyclic");
 
+	for (srcnode = engine->clients; srcnode;
+	     srcnode = jack_slist_next (srcnode)) {
 
-/* Recreate the execution order client list if necessary.
- */
-void
-jack_check_execorder (jack_engine_t *engine)
-{
-	jack_client_internal_t *C, *D;
-	jack_feedcounts_t *F;
-	JSList *N;
-
-	if (engine->execlist_request & EXECLIST_CYCLE) {
-		/* Test if any feedback connections can be reverted
-		 * to normal */
-		for (C = engine->execlist_head; C; C = C->execlist_next) {
-			for (F = C->feedlist; F; F = F->next) {
-				int rev;
-				D = F->client;
-				if (F->rev_count == 0) {
-					continue;
-				}
-				if (depends_closure (C, D)) {
-					continue;
-				}
-				/* printf ("Reverting feedback %s -> %s\n", D->control->name, C->control->name); */
-				rev = F->rev_count;
-				rem_depends (C, D);
-				add_depends (D, C, rev, 0);
-				engine->execlist_request |= EXECLIST_ORDER;
-			}
-		}
+		src = (jack_client_internal_t*)srcnode->data;
+		src->tfedcount = src->fedcount;
+		unsortedclients++;
 	}
-/*
-        puts ("---------------------------------------------");
-        printf ("Original client list:\n");
-        for (N = engine->clients; N; N = jack_slist_next (N))
-        {
-                C = (jack_client_internal_t *) N->data;
-                printf ("%-20s %d\n", C->control->name, C->depcount);
-                for (F = C->feedlist; F; F = F->next)
-                {
-                        printf ("    %-20s %3d %3d\n", F->client->control->name, F->fwd_count, F->rev_count);
+
+	stuck = FALSE;
+
+	/* find out whether a normal sort would have been possible */
+	while (unsortedclients && !stuck) {
+
+		stuck = TRUE;
+
+		for (srcnode = engine->clients; srcnode;
+		     srcnode = jack_slist_next (srcnode)) {
+
+			src = (jack_client_internal_t*)srcnode->data;
+
+			if (!src->tfedcount) {
+
+				stuck = FALSE;
+				unsortedclients--;
+				src->tfedcount = -1;
+
+				for (dstnode = src->truefeeds; dstnode;
+				     dstnode = jack_slist_next (dstnode)) {
+
+					dst = (jack_client_internal_t*)
+					      dstnode->data;
+					dst->tfedcount--;
                 }
         }
-        puts ("---------------------------------------------");
- */
-	if (engine->execlist_request & EXECLIST_ORDER) {
-/*
-                puts ("Re-ordering...");
- */
-		/* Put clients in correct execution order depending
-		   on their dependencies. */
-		D = 0;
-		for (N = engine->clients; N; N = jack_slist_next (N)) {
-			C = (jack_client_internal_t*)N->data;
-			C->depcheck = C->depcount;
-			if (C->control->type == ClientDriver) {
-				D = C;
-			}
-		}
-		/* Reset bidirectional linked list and build it again. */
-		engine->execlist_head = 0;
-		engine->execlist_tail = 0;
-		/* The driver must be first even if nobody is using capture data. */
-		if (D) {
-			append_execlist (engine, D);
-		}
-		/* Then loop over all the other clients. */
-		for (N = engine->clients; N; N = jack_slist_next (N)) {
-			C = (jack_client_internal_t*)N->data;
-			if (C->depcheck == 0) {
-				append_execlist (engine, C);
 			}
 		}
 
-		/* Copy execlist to engine->clients. Just overwrite the data pointers. */
-		for (C = engine->execlist_head, N = engine->clients;
-		     C && N;
-		     C = C->execlist_next, N = N->next)
-			N->data = C;
+	if (stuck) {
 
-		/* ??? Maybe call jack_rechain_graph here instead of in jack_sort_graph() ??? */
+		VERBOSE (engine, "graph is still cyclic" );
+	} else {
+
+		VERBOSE (engine, "graph has become acyclic");
+
+		/* turn feedback connections around in sortfeeds */
+		for (srcnode = engine->clients; srcnode;
+		     srcnode = jack_slist_next (srcnode)) {
+
+			src = (jack_client_internal_t*)srcnode->data;
+
+			for (portnode = src->ports; portnode;
+			     portnode = jack_slist_next (portnode)) {
+
+				port = (jack_port_internal_t*)portnode->data;
+
+				for (connnode = port->connections; connnode;
+				     connnode = jack_slist_next (connnode)) {
+
+					conn = (jack_connection_internal_t*)
+					       connnode->data;
+
+					if (conn->dir == -1 ) {
+						/*&&
+						        conn->srcclient == src) */
+
+						VERBOSE (engine,
+							 "reversing connection from "
+							 "%s to %s",
+							 conn->srcclient->control->name,
+							 conn->dstclient->control->name);
+						conn->dir = 1;
+						conn->dstclient->sortfeeds =
+							jack_slist_remove
+								(conn->dstclient->sortfeeds,
+								conn->srcclient);
+
+						conn->srcclient->sortfeeds =
+							jack_slist_prepend
+								(conn->srcclient->sortfeeds,
+								conn->dstclient );
 	}
-/*
-        puts ("---------------------------------------------");
-        printf ("Ordered client list:\n");
-        for (C = engine->execlist_head; C; C = C->execlist_next)
-        {
-                printf ("   %-20s\n", C->control->name);
         }
-        puts ("---------------------------------------------");
- */
-	engine->execlist_request = 0;
 }
-
-
-/* Modified for new client execution order algorithm.
- * FA 08/2015
- */
-void
-jack_sort_graph (jack_engine_t *engine)
-{
-	/* caller, obviously, must hold engine->client_lock */
-	VERBOSE (engine, "++ jack_sort_graph");
-	jack_check_execorder (engine);
-	jack_compute_all_port_total_latencies (engine);
-	jack_compute_new_latency (engine);
-	jack_rechain_graph (engine);
-	engine->timeout_count = 0;
-	VERBOSE (engine, "-- jack_sort_graph");
 }
-
+		engine->feedbackcount = 0;
+	}
+}
 
 /**
  * Dumps current engine configuration.
@@ -3800,11 +3792,6 @@
 	jack_info ("engine.c: <-- dump ends -->");
 }
 
-
-
-/* Modified for new client execution order algorithm.
- * FA 08/2015
- */
 static int
 jack_port_do_connect (jack_engine_t *engine,
 		      const char *source_port,
@@ -3884,16 +3871,9 @@
 		}
 	}
 
-	if (dstport->connections && !dstport->shared->has_mixdown) {
-		jack_port_type_info_t *port_type =
-			jack_port_type_info (engine, dstport);
-		jack_error ("cannot make multiple connections to a port of"
-			    " type [%s]", port_type->type_name);
-		return -1;
-	}
-
 	connection = (jack_connection_internal_t*)
 		     malloc (sizeof(jack_connection_internal_t));
+
 	connection->source = srcport;
 	connection->destination = dstport;
 	connection->srcclient = srcclient;
@@ -3901,68 +3881,85 @@
 
 	src_id = srcport->shared->id;
 	dst_id = dstport->shared->id;
+
 	jack_lock_graph (engine);
 
+	if (dstport->connections && !dstport->shared->has_mixdown) {
+		jack_port_type_info_t *port_type =
+			jack_port_type_info (engine, dstport);
+		jack_error ("cannot make multiple connections to a port of"
+			    " type [%s]", port_type->type_name);
+		free (connection);
+		jack_unlock_graph (engine);
+		return -1;
+	} else {
+
 	if (dstclient->control->type == ClientDriver) {
 		/* Ignore output connections to drivers for purposes
 		   of sorting. Drivers are executed first in the sort
 		   order anyway, and we don't want to treat graphs
 		   such as driver -> client -> driver as containing
 		   feedback */
+
 		VERBOSE (engine,
 			 "connect %s and %s (output)",
 			 srcport->shared->name,
 			 dstport->shared->name);
+
+			connection->dir = 1;
+
 	} else if (srcclient != dstclient) {
-		jack_feedcounts_t *F;
-		int dir = 0;
 
-		if ((F = depends_direct (srcclient, dstclient)) != 0) {
-			/* We already have a direct dependency,
-			   just increment the connection count. */
-			F->fwd_count++;
-			dir = 1;
-		} else if ((F = depends_direct (dstclient, srcclient)) != 0) {
-			/* We already have a reverse direct dependency,
-			   just increment the reverse connection count. */
-			F->rev_count++;
-			dir = -1;
-		} else if (depends_closure (dstclient, srcclient)) {
-			/* We have an inverse dependency, this
-			   connection must be a delayed one. */
-			add_depends (dstclient, srcclient, 0, 1);
-			engine->execlist_request = EXECLIST_ORDER;
-			dir = -1;
-		} else {
-			/* First normal connection from source
-			   to destination client. */
-			add_depends (srcclient, dstclient, 1, 0);
-			engine->execlist_request = EXECLIST_ORDER;
-			dir = 1;
-		}
+			srcclient->truefeeds = jack_slist_prepend
+						       (srcclient->truefeeds, dstclient);
+
+			dstclient->fedcount++;
+
+			if (jack_client_feeds_transitive (dstclient,
+							  srcclient ) ||
+			    (dstclient->control->type == ClientDriver &&
+			     srcclient->control->type != ClientDriver)) {
+
+				/* dest is running before source so
+				   this is a feedback connection */
 
-		if (dir > 0) {
-			VERBOSE (engine,
-				 "connect %s and %s (forward)",
-				 srcport->shared->name,
-				 dstport->shared->name);
-		} else {
 			VERBOSE (engine,
 				 "connect %s and %s (feedback)",
 				 srcport->shared->name,
 				 dstport->shared->name);
+
+				dstclient->sortfeeds = jack_slist_prepend
+							       (dstclient->sortfeeds, srcclient);
+
+				connection->dir = -1;
 			engine->feedbackcount++;
 			VERBOSE (engine,
 				 "feedback count up to %d",
 				 engine->feedbackcount);
+
+			} else {
+
+				/* this is not a feedback connection */
+
+				VERBOSE (engine,
+					 "connect %s and %s (forward)",
+					 srcport->shared->name,
+					 dstport->shared->name);
+
+				srcclient->sortfeeds = jack_slist_prepend
+							       (srcclient->sortfeeds, dstclient);
+
+				connection->dir = 1;
 		}
 	} else {
 		/* this is a connection to self */
+
 		VERBOSE (engine,
 			 "connect %s and %s (self)",
 			 srcport->shared->name,
 			 dstport->shared->name);
 
+			connection->dir = 0;
 	}
 
 	dstport->connections =
@@ -3970,28 +3967,29 @@
 	srcport->connections =
 		jack_slist_prepend (srcport->connections, connection);
 
+		DEBUG ("actually sorted the graph...");
+
 	jack_send_connection_notification (engine,
 					   srcport->shared->client_id,
 					   src_id, dst_id, TRUE);
+
+
 	jack_send_connection_notification (engine,
 					   dstport->shared->client_id,
 					   dst_id, src_id, TRUE);
 
-	/* send a port connection notification just once to everyone who
-	 * cares excluding clients involved in the connection */
-	jack_notify_all_port_interested_clients (engine,
-						 srcport->shared->client_id,
-						 dstport->shared->client_id,
-						 src_id, dst_id, 1);
+		/* send a port connection notification just once to everyone who cares excluding clients involved in the connection */
+
+		jack_notify_all_port_interested_clients (engine, srcport->shared->client_id, dstport->shared->client_id, src_id, dst_id, 1);
+
 	jack_sort_graph (engine);
+	}
+
 	jack_unlock_graph (engine);
+
 	return 0;
 }
 
-
-/* Modified for new client execution order algorithm.
- * FA 08/2015
- */
 int
 jack_port_disconnect_internal (jack_engine_t *engine,
 			       jack_port_internal_t *srcport,
@@ -4000,15 +3998,19 @@
 {
 	JSList *node;
 	jack_connection_internal_t *connect;
-	jack_client_internal_t *src, *dst;
-	jack_port_id_t src_id, dst_id;
 	int ret = -1;
+	jack_port_id_t src_id, dst_id;
+	int check_acyclic = engine->feedbackcount;
 
 	/* call tree **** MUST HOLD **** engine->client_lock. */
-	for (node = srcport->connections; node; node = jack_slist_next (node)) {
+	for (node = srcport->connections; node;
+	     node = jack_slist_next (node)) {
+
 		connect = (jack_connection_internal_t*)node->data;
 
-		if (connect->source == srcport &&  connect->destination == dstport) {
+		if (connect->source == srcport &&
+		    connect->destination == dstport) {
+
 			VERBOSE (engine, "DIS-connect %s and %s",
 				 srcport->shared->name,
 				 dstport->shared->name);
@@ -4019,7 +4021,7 @@
 			dstport->connections =
 				jack_slist_remove (dstport->connections,
 						   connect);
-			free (connect);
+
 			src_id = srcport->shared->id;
 			dst_id = dstport->shared->id;
 
@@ -4042,59 +4044,58 @@
 				engine, dstport->shared->client_id, dst_id,
 				src_id, FALSE);
 
-			/* send a port connection notification just once to everyone
-			   who cares excluding clients involved in the connection */
-			jack_notify_all_port_interested_clients (engine,
-								 srcport->shared->client_id,
-								 dstport->shared->client_id,
-								 src_id, dst_id, 0);
+			/* send a port connection notification just once to everyone who cares excluding clients involved in the connection */
 
-			/* Update client dependencies */
-			src = jack_client_internal_by_id (engine, srcport->shared->client_id);
-			dst = jack_client_internal_by_id (engine, dstport->shared->client_id);
-			/* Again we ignore connections if the destination is the driver. */
-			if ((src != dst) && (dst->control->type != ClientDriver)) {
-				jack_feedcounts_t *F;
-				if ((F = depends_direct (src, dst)) != 0) {
-					if (F->fwd_count > 0) {
-						F->fwd_count--;
-					}
-					if (F->fwd_count == 0) {
-						/* A direct forward dependency no longer exists.
-						   This could break a cycle, so we'll test. */
-						engine->execlist_request = EXECLIST_CYCLE;
-						if (F->rev_count == 0) {
-							/* A direct dependency no longer exists,
-							   remove the corresponding list element. */
-							rem_depends (src, dst);
-							engine->execlist_request |= EXECLIST_ORDER;
-						}
-					}
-				} else if ((F = depends_direct (dst, src)) != 0) {
-					/* Removing a feedback connection. */
-					if (F->rev_count > 0) {
-						F->rev_count--;
-					}
-					if ((F->fwd_count | F->rev_count) == 0) {
-						/* A direct dependency no longer exists,
-						   remove the corresponding list element. */
-						rem_depends (dst, src);
-						engine->execlist_request = EXECLIST_ORDER;
-					}
+			jack_notify_all_port_interested_clients (engine, srcport->shared->client_id, dstport->shared->client_id, src_id, dst_id, 0);
+
+			if (connect->dir) {
+
+				jack_client_internal_t *src;
+				jack_client_internal_t *dst;
+
+				src = jack_client_internal_by_id
+					      (engine, srcport->shared->client_id);
+
+				dst =  jack_client_internal_by_id
+					      (engine, dstport->shared->client_id);
+
+				src->truefeeds = jack_slist_remove
+							 (src->truefeeds, dst);
+
+				dst->fedcount--;
+
+				if (connect->dir == 1) {
+					/* normal connection: remove dest from
+					   source's sortfeeds list */
+					src->sortfeeds = jack_slist_remove
+								 (src->sortfeeds, dst);
+				} else {
+					/* feedback connection: remove source
+					   from dest's sortfeeds list */
+					dst->sortfeeds = jack_slist_remove
+								 (dst->sortfeeds, src);
 					engine->feedbackcount--;
 					VERBOSE (engine,
 						 "feedback count down to %d",
 						 engine->feedbackcount);
 
 				}
-			}
-			jack_sort_graph (engine);
-			return 0;
+			} /* else self-connection: do nothing */
+
+			free (connect);
+			ret = 0;
+			break;
 		}
 	}
-	return -1;
+
+	if (check_acyclic) {
+		jack_check_acyclic (engine);
 }
 
+	jack_sort_graph (engine);
+
+	return ret;
+}
 
 static int
 jack_port_do_disconnect_all (jack_engine_t *engine,
Only in jack-u/jackd: engine.c.orig
Only in jack-u/jackd: engine.c.rej
