version 1.9, 1999/12/02 20:10:05 |
version 1.10, 2000/01/10 10:15:28 |
|
|
static void chan_send_oclose(Channel *c); |
static void chan_send_oclose(Channel *c); |
static void chan_shutdown_write(Channel *c); |
static void chan_shutdown_write(Channel *c); |
static void chan_shutdown_read(Channel *c); |
static void chan_shutdown_read(Channel *c); |
static void chan_delele_if_full_closed(Channel *c); |
static void chan_delete_if_full_closed(Channel *c); |
|
|
/* |
/* |
* EVENTS update channel input/output states execute ACTIONS |
* EVENTS update channel input/output states execute ACTIONS |
|
|
case CHAN_INPUT_WAIT_OCLOSE: |
case CHAN_INPUT_WAIT_OCLOSE: |
debug("channel %d: INPUT_WAIT_OCLOSE -> INPUT_CLOSED [rcvd OCLOSE]", c->self); |
debug("channel %d: INPUT_WAIT_OCLOSE -> INPUT_CLOSED [rcvd OCLOSE]", c->self); |
c->istate = CHAN_INPUT_CLOSED; |
c->istate = CHAN_INPUT_CLOSED; |
chan_delele_if_full_closed(c); |
|
break; |
break; |
case CHAN_INPUT_OPEN: |
case CHAN_INPUT_OPEN: |
debug("channel %d: INPUT_OPEN -> INPUT_CLOSED [rvcd OCLOSE, send IEOF]", c->self); |
debug("channel %d: INPUT_OPEN -> INPUT_CLOSED [rvcd OCLOSE, send IEOF]", c->self); |
chan_shutdown_read(c); |
chan_shutdown_read(c); |
chan_send_ieof(c); |
chan_send_ieof(c); |
c->istate = CHAN_INPUT_CLOSED; |
c->istate = CHAN_INPUT_CLOSED; |
chan_delele_if_full_closed(c); |
|
break; |
break; |
|
case CHAN_INPUT_WAIT_DRAIN: |
|
/* both local read_failed and remote write_failed */ |
|
log("channel %d: INPUT_WAIT_DRAIN -> INPUT_CLOSED [rvcd OCLOSE, send IEOF]", c->self); |
|
debug("channel %d: INPUT_WAIT_DRAIN -> INPUT_CLOSED [rvcd OCLOSE, send IEOF]", c->self); |
|
chan_send_ieof(c); |
|
c->istate = CHAN_INPUT_CLOSED; |
|
break; |
default: |
default: |
error("protocol error: chan_rcvd_oclose %d for istate %d", c->self, c->istate); |
error("protocol error: chan_rcvd_oclose %d for istate %d", c->self, c->istate); |
break; |
return; |
} |
} |
|
chan_delete_if_full_closed(c); |
} |
} |
void |
void |
chan_read_failed(Channel *c) |
chan_read_failed(Channel *c) |
|
|
case CHAN_OUTPUT_WAIT_IEOF: |
case CHAN_OUTPUT_WAIT_IEOF: |
debug("channel %d: OUTPUT_WAIT_IEOF -> OUTPUT_CLOSED [rvcd IEOF]", c->self); |
debug("channel %d: OUTPUT_WAIT_IEOF -> OUTPUT_CLOSED [rvcd IEOF]", c->self); |
c->ostate = CHAN_OUTPUT_CLOSED; |
c->ostate = CHAN_OUTPUT_CLOSED; |
chan_delele_if_full_closed(c); |
chan_delete_if_full_closed(c); |
break; |
break; |
default: |
default: |
error("protocol error: chan_rcvd_ieof %d for ostate %d", c->self, c->ostate); |
error("protocol error: chan_rcvd_ieof %d for ostate %d", c->self, c->ostate); |
|
|
debug("channel %d: OUTPUT_WAIT_DRAIN -> OUTPUT_CLOSED [write failed]", c->self); |
debug("channel %d: OUTPUT_WAIT_DRAIN -> OUTPUT_CLOSED [write failed]", c->self); |
chan_send_oclose(c); |
chan_send_oclose(c); |
c->ostate = CHAN_OUTPUT_CLOSED; |
c->ostate = CHAN_OUTPUT_CLOSED; |
chan_delele_if_full_closed(c); |
chan_delete_if_full_closed(c); |
break; |
break; |
default: |
default: |
error("internal error: chan_write_failed %d for ostate %d", c->self, c->ostate); |
error("internal error: chan_write_failed %d for ostate %d", c->self, c->ostate); |
|
|
debug("channel %d: OUTPUT_WAIT_DRAIN -> OUTPUT_CLOSED [obuf empty, send OCLOSE]", c->self); |
debug("channel %d: OUTPUT_WAIT_DRAIN -> OUTPUT_CLOSED [obuf empty, send OCLOSE]", c->self); |
chan_send_oclose(c); |
chan_send_oclose(c); |
c->ostate = CHAN_OUTPUT_CLOSED; |
c->ostate = CHAN_OUTPUT_CLOSED; |
chan_delele_if_full_closed(c); |
chan_delete_if_full_closed(c); |
break; |
break; |
default: |
default: |
error("internal error: chan_obuf_empty %d for ostate %d", c->self, c->ostate); |
error("internal error: chan_obuf_empty %d for ostate %d", c->self, c->ostate); |
|
|
{ |
{ |
debug("channel %d: shutdown_read", c->self); |
debug("channel %d: shutdown_read", c->self); |
if (shutdown(c->sock, SHUT_RD) < 0) |
if (shutdown(c->sock, SHUT_RD) < 0) |
error("chan_shutdown_read failed for #%d/fd%d: %.100s", |
error("chan_shutdown_read failed for #%d/fd%d [i%d o%d]: %.100s", |
c->self, c->sock, strerror(errno)); |
c->self, c->sock, c->istate, c->ostate, strerror(errno)); |
} |
} |
static void |
static void |
chan_delele_if_full_closed(Channel *c) |
chan_delete_if_full_closed(Channel *c) |
{ |
{ |
if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) { |
if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) { |
debug("channel %d: closing", c->self); |
debug("channel %d: full closed", c->self); |
channel_free(c->self); |
channel_free(c->self); |
} |
} |
} |
} |