Index: ossp-pkg/sio/sio_bio.c RCS File: /v/ossp/cvs/ossp-pkg/sio/sio_bio.c,v rcsdiff -q -kk '-r1.6' '-r1.7' -u '/v/ossp/cvs/ossp-pkg/sio/sio_bio.c,v' 2>/dev/null --- 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);