+
+static int conn_total_queued_articles(Conn *conn) {
+ return conn->sent.count + !!conn->send + conn->queue.count;
+}
+
+static void conn_assign_one_article(LIST(Conn) *connlist) {
+ Conn *conn= connlist->head;
+
+ LIST_REMOVE(*connlist, conn);
+ Article *art= LIST_REMHEAD(queue);
+ LIST_ADDTAIL(conn->queue, art);
+ LIST_ADD(*conn_determine_right_list(conn), conn);
+
+ check_conn_work(conn);
+}
+
+static LIST(Conn) *conn_determine_right_list(Conn *conn) {
+ int inqueue= conn_total_queued_articles(conn);
+ assert(inqueue <= max_queue);
+ if (inqueue == 0) return &idle;
+ if (inqueue == conn->max_queue) return &full;
+ return &working;
+}
+
+static void check_conn_work(Conn *conn) {
+ void *rp;
+ for (;;) {
+ conn_make_some_xmits(conn);
+
+ void *rp= conn_write_some_xmits(conn);
+ if (!rp) {
+ loop->cancel_fd(loop, conn->fd, OOP_WRITE);
+ return;
+ } else if (rp==OOP_CONTINUE) {
+ loop->on_fd(loop, conn->fd, OOP_WRITE;)
+ else if (rp==OOP_HALT) {
+ return;
+ }
+
+
+ if (
+
+ while (
+
+}