+ if (!conn->xmitu) {
+ perhaps_transmit_on(conn);
+ if (!conn->xmitu) {
+ unlink from readable;
+ break;
+ }
+ }
+
+ int count= conn->xmitu;
+ if (count > IOV_MAX) count= IOV_MAX;
+ ssize_t rs= writev(conn->fd, conn->xmit, count);
+ if (rs < 0) {
+ if (errno == EAGAIN) break;
+ syswarn(CN "write failed", conn->fd);
+ conn_failed(conn);
+ break;
+ }
+ assert(rs > 0);
+
+ for (done=0; rs && done<xmitu; done++) {
+ struct iovec *vp= &conn->xmit[done];
+ XmitDetails *dp= &conn->xmitd[done];
+ if (rs > vp->iov_len) {
+ rs -= vp->iov_len;
+ xmit_free(dp);
+ } else {
+ vp->iov_base += rs;
+ vp->iov_len -= rs;
+ }
+ }
+ int newu= conn->xmitu - done;
+ memmove(conn->xmit, conn->xmit + done, newu * sizeof(*conn->xmit));
+ memmove(conn->xmitd, conn->xmitd + done, newu * sizeof(*conn->xmitd));
+ conn->xmitu= newu;
+ }
+
+ return OOP_CONTINUE;
+}
+
+static void transmit(Conn *conn) {
+ int inqueue= conn->sent.count + !!conn->send + conn->queue.count;
+ assert(inqueue < max_queue);
+ Article *art= LIST_REMHEAD(queue);
+ LIST_ADDTAIL(conn->queue, art);
+ if (inqueue == 0) {
+ LIST_REMOVE(idle, conn);
+ if (conn->max_queue==1) LIST_ADD(full, conn);
+ else LIST_ADD(working, conn);
+ } else if (inqueue == max_queue-1) {
+ LIST_REMOVE(working, conn);
+ LIST_ADD(full, conn);
+ }
+ perhaps_transmit_on(conn);
+}
+
+static void perhaps_transmit_on(Conn *conn) {
+ for (;;) {
+ if (conn->send) {
+ /* do something about this article text */
+ continue;
+ }
+ if (conn->xmitu+3 > xmita)
+ /* no space for a CHECK even */
+ return;
+
+ Article *art= LIST_REMHEAD(conn->queue);
+ if (art) return;
+
+ if (art->checked || conn->nocheck) {
+ if (conn->stream) {
+ XMIT_LITERAL("TAKETHIS ");
+ xmit_noalloc(art->mid, art->midlen);
+ XMIT_LITERAL("\r\n");
+ } else {
+ /* we got 235 */
+ }
+ conn->send= art;
+ } else {
+ if (conn->stream) XMIT_LITERAL("IHAVE ");
+ else XMIT_LITERAL("CHECK ");
+ xmit_noalloc(art->mid, art->midlen);
+ XMIT_LITERAL("\r\n");
+ LIST_ADDTAIL(conn->sent, art);
+ }
+ }
+}
+
+
+ if (conn->queue.head) {
+ if (conn->queue.checked || conn->nocheck) {
+
+
+ && conn->xmitu+3 <= xmita) {
+ if (
+ XMIT("
+ if (conn->xmitu < xmita
+
+
+ if (!queue
+
+
+
+
+