--- 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);
|