OSSP CVS Repository

ossp - Check-in [2934]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 2934
Date: 2002-Nov-29 15:26:31 (local)
2002-Nov-29 14:26:31 (UTC)
User:mlelstv
Branch:
Comment: eof/write_error handling BIO_write retries now loops through scheduler to give upper layer a chance to run.

PR: Submitted by: Reviewed by: Approved by: Obtained from:

Tickets:
Inspections:
Files:
ossp-pkg/sio/sio_bio.c      1.6 -> 1.7     43 inserted, 32 deleted

ossp-pkg/sio/sio_bio.c 1.6 -> 1.7

--- sio_bio.c    2002/11/29 13:00:18     1.6
+++ sio_bio.c    2002/11/29 14:26:31     1.7
@@ -23,8 +23,6 @@
     BIO         *bio;
     BIO         *nbio;
     al_t        *al_in, *al_out;   /* upstream buffers */
-    int          reader_writes;
-    int          writer_reads;
     int          issink;
     int          freebio;
     size_t       inputsize;
@@ -34,10 +32,11 @@
     char         eof;
     char         error;
     size_t       total;
-    int          should_retry;
+    int          needs_input;
+    int          eof_reached;
+    int          write_error;
     int          flush_upper;
     int          flush_lower;
-    int          eof_reached;
 } private_t;
 
 /********************************************************************/
@@ -136,14 +135,12 @@
             m = n;
         } else {
             al_flatten(my->al_in, 0, outl, AL_FORWARD_SPAN, label, NULL, &n);
-            m = -1;
+            my->eof_reached = 1;
+            m = 0;
         }
         al_splice(my->al_in, 0, n, NULL, NULL);
     }
 
-    if (m < 0)
-        my->eof_reached = 1;
-
     BIO_clear_retry_flags(b);
     if (m == 0)
         BIO_set_retry_read(b);
@@ -202,7 +199,7 @@
     my->issink        = 1;
     my->freebio       = 0;
     my->eof           = '\0';
-    my->error        = '\0';
+    my->error         = '\0';
 
     sio_label(sio, SIO_LN_DATA,  &my->data_label);
     sio_label(sio, SIO_LN_EOF,   &my->eof_label);
@@ -223,11 +220,15 @@
 {
     private_t *my = (private_t *)u;
     const char *name = (const char *)obj;
+    int v;
 
     if (!strcmp(name, "bio")) {
         my->bio       = (BIO *)val;
     } else if (!strcmp(name, "inputsize")) {
-        my->inputsize = *(int *)val;
+        v = *(int *)val;
+        if (v <= 0)
+            return SIO_ERR_ARG;
+        my->inputsize = v;
     } else if (!strcmp(name, "issink")) {
         my->issink    = *(int *)val;
     } else if (!strcmp(name, "freebio")) {
@@ -296,8 +297,12 @@
         BIO_push(my->bio, my->nbio);
     }
 
-    my->writer_reads  = 0;
-    my->reader_writes = 0;
+    my->eof_reached   = 0;
+    my->needs_input   = 0;
+    my->write_error   = 0;
+
+    my->flush_upper   = 0;
+    my->flush_lower   = 0;
 
     my->state = INIT;
 
@@ -338,7 +343,7 @@
  * chunk traversal of output buffer
  *
  * counts my->total
- * sets my->should_retry
+ * sets my->needs_input
  */
 static
 al_rc_t siobio_write_chunk(al_chunk_t *alc, void *u)
@@ -355,13 +360,14 @@
             i = my->bio ? BIO_write(my->bio, p+t, n-t) : (n-t);
             if (i <= 0) {
                 if (!BIO_should_retry(my->bio)) {
-                    my->should_retry = 1;
-                    arc = AL_ERR_EOF;
-                    break;
+                    my->needs_input = 1;
+                    if (my->eof_reached)
+                        my->write_error = 1;
                 }
-                i = 0;
+                arc = AL_ERR_EOF;
+                break;
             }
-            my->total += i;
+            my->total       += i;
         }
     } else {
         my->total += n;
@@ -405,8 +411,8 @@
         return SIO_SCHED_UP;
     }
 
-    if (my->should_retry) {
-        my->should_retry = 0;
+    if (my->needs_input) {
+        my->needs_input = 0;
         al_splice(al, 0, al_bytes(al), my->al_in, NULL);
         return SIO_SCHED_CROSS;
     }
@@ -424,7 +430,7 @@
 sio_rc_t siobio_input_lower(private_t *my, al_t *al)
 {
     al_splice(al, al_bytes(al), 0, my->in_buf, NULL);
-    if (al_bytes(al) > 0) {
+    if (al_bytes(al) > 0 || my->eof_reached) {
         my->state = INIT;
         return SIO_SCHED_DOWN;
     }
@@ -454,7 +460,7 @@
     int n;
 
     n = BIO_pending(my->bio);
-    if (n == 0 || n > my->inputsize)
+    if (n <= 0 || (size_t)n > my->inputsize)
         n = my->inputsize;
     p = malloc(n);
     assert(p != NULL);
@@ -481,14 +487,14 @@
 static
 void siobio_bio_write(private_t *my)
 {
-    my->should_retry = 0;
-    my->total        = 0;
+    my->needs_input = 0;
+    my->total       = 0;
     al_traverse_cb(my->out_buf, 0, al_bytes(my->out_buf),
                    AL_FORWARD, NULL,
                    siobio_write_chunk, (void *)my);
     al_splice(my->out_buf, 0, my->total, NULL, NULL);
 
-    if (my->flush_lower) {
+    if (!my->write_error && my->flush_lower) {
         my->flush_upper = 1;
         if (BIO_flush(my->bio) > 0)
             my->flush_lower = 0;
@@ -498,13 +504,6 @@
 /********************************************************************/
 
 static
-sio_rc_t siobio_eof(private_t *my, al_t *al)
-{
-    al_splice(al, 0, al_bytes(al), NULL, NULL);
-    return SIO_SCHED_DOWN;
-}
-
-static
 sio_rc_t siobio_input(sio_t *sio, al_t *al, void *u, sio_rc_t orc)
 {
     private_t *my = (private_t *)u;
@@ -519,6 +518,12 @@
     case LOWER:
         siobio_bio_read(my);
         rc = siobio_input_lower(my, al);
+        if (my->eof_reached) {
+            my->eof_reached = 0;
+            my->state       = INIT;
+            al_append_bytes(al, &my->eof, sizeof(my->eof), my->eof_label);
+            return SIO_SCHED_DOWN;
+        }
         break;
     case UPPER:
         rc = siobio_input_upper(my, al);
@@ -543,6 +548,12 @@
     case LOWER:
         rc = siobio_output_lower(my, al);
         siobio_bio_write(my);
+        if (my->write_error) {
+            my->write_error = 0;
+            my->state       = INIT;
+            al_splice(al, 0, al_bytes(al), NULL, NULL);
+            return SIO_SCHED_DOWN;
+        }
         break;
     case UPPER:
         rc = siobio_output_upper(my, al);

CVSTrac 2.0.1