chiark / gitweb /
merge changes from trunk into our branch; cvs up -j branchpoint-hostside-wip-2006...
[trains.git] / hostside / obc.c
index bc272de697ba1000aba52dcaa20e20031ba7fe0f..040ee6a5c50c0765c792648c32505fc6ff3bf585 100644 (file)
@@ -1,4 +1,7 @@
-/**/
+/*
+ * daemons
+ * output buffer chains
+ */
 
 #include <assert.h>
 #include <stdlib.h>
@@ -6,7 +9,7 @@
 #include <stdarg.h>
 #include <string.h>
 
-#include "hostside.h"
+#include "daemons.h"
 #include "../layout/dlist.h"
 
 struct OutBuffer {
@@ -15,20 +18,15 @@ struct OutBuffer {
   int l;
 };
 
-static void *writeable(oop_source *evts, int fd,
-                      oop_event evt, void *ch_v) {
-  OutBufferChain *ch= ch_v;
+int obc_tryflush(OutBufferChain *ch) {
   OutBuffer *ob;
   int r;
   
-  assert(fd == ch->fd);
-  assert(evt == OOP_WRITE);
-
   for (;;) {
     ob= ch->obs.head;
     if (!ob) {
-      events->cancel_fd(events, fd, OOP_WRITE);
-      return OOP_CONTINUE;
+      events->cancel_fd(events, ch->fd, OOP_WRITE);
+      return 0;
     }
     if (ch->done_of_head == ob->l) {
       LIST_UNLINK(ch->obs, ob);
@@ -40,8 +38,9 @@ static void *writeable(oop_source *evts, int fd,
     r= write(ch->fd, ob->m + ch->done_of_head, ob->l - ch->done_of_head);
     if (r==-1) {
       if (errno==EINTR) continue;
-      if (errno==EWOULDBLOCK) return OOP_CONTINUE;
+      if (errno==EWOULDBLOCK) return errno;
       ch->error(ch,"write",strerror(errno));
+      return errno;
     }
     assert(r>=0);
     ch->done_of_head += r;
@@ -49,6 +48,15 @@ static void *writeable(oop_source *evts, int fd,
   }
 }
 
+static void *writeable(oop_source *evts, int fd,
+                      oop_event evt, void *ch_v) {
+  OutBufferChain *ch= ch_v;
+  assert(fd == ch->fd);
+  assert(evt == OOP_WRITE);
+  obc_tryflush(ch);
+  return OOP_CONTINUE;
+}
+
 static void addlink(OutBufferChain *ch, OutBuffer *ob) {
   if (!ch->obs.head)
     events->on_fd(events, ch->fd, OOP_WRITE, writeable, ch);
@@ -56,7 +64,10 @@ static void addlink(OutBufferChain *ch, OutBuffer *ob) {
 }
 
 void obc_init(OutBufferChain *ch) {
+  int r;
   ch->done_of_head= 0;
+  r= oop_fd_nonblock(ch->fd, 1);
+  if (r) diee("nonblock(OutBufferChain->fd,1)");
   LIST_INIT(ch->obs);
 }
 
@@ -75,6 +86,12 @@ void oprintf(OutBufferChain *ch, const char *msg, ...) {
   va_end(al);
 }
 
+void voerror(OutBufferChain *ch, const char *fmt, va_list al) {
+  oprintf(ch,"error ");
+  ovprintf(ch,fmt,al);
+  owrite(ch,"\n",1);
+}
+
 void owrite(OutBufferChain *ch, const char *data, int l) {
   OutBuffer *ob;
   ob= mmalloc(sizeof(*ob));