version 1.139, 2001/10/09 21:59:41 |
version 1.140, 2001/10/10 22:18:47 |
|
|
debug3("channel_free: status: %s", s); |
debug3("channel_free: status: %s", s); |
xfree(s); |
xfree(s); |
|
|
if (c->detach_user != NULL) { |
|
debug("channel_free: channel %d: detaching channel user", c->self); |
|
c->detach_user(c->self, NULL); |
|
} |
|
if (c->sock != -1) |
if (c->sock != -1) |
shutdown(c->sock, SHUT_RDWR); |
shutdown(c->sock, SHUT_RDWR); |
channel_close_fds(c); |
channel_close_fds(c); |
|
|
channel_handler_init_15(); |
channel_handler_init_15(); |
} |
} |
|
|
|
/* gc dead channels */ |
static void |
static void |
|
channel_garbage_collect(Channel *c) |
|
{ |
|
if (c == NULL) |
|
return; |
|
if (c->detach_user != NULL) { |
|
if (!chan_is_dead(c, 0)) |
|
return; |
|
debug("channel %d: gc: notify user", c->self); |
|
c->detach_user(c->self, NULL); |
|
/* if we still have a callback */ |
|
if (c->detach_user != NULL) |
|
return; |
|
debug("channel %d: gc: user detached", c->self); |
|
} |
|
if (!chan_is_dead(c, 1)) |
|
return; |
|
debug("channel %d: garbage collecting", c->self); |
|
channel_free(c); |
|
} |
|
|
|
static void |
channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset) |
channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset) |
{ |
{ |
static int did_init = 0; |
static int did_init = 0; |
|
|
continue; |
continue; |
if (ftab[c->type] != NULL) |
if (ftab[c->type] != NULL) |
(*ftab[c->type])(c, readset, writeset); |
(*ftab[c->type])(c, readset, writeset); |
if (chan_is_dead(c)) { |
channel_garbage_collect(c); |
/* |
|
* we have to remove the fd's from the select mask |
|
* before the channels are free'd and the fd's are |
|
* closed |
|
*/ |
|
if (c->wfd != -1) |
|
FD_CLR(c->wfd, writeset); |
|
if (c->rfd != -1) |
|
FD_CLR(c->rfd, readset); |
|
if (c->efd != -1) { |
|
if (c->extended_usage == CHAN_EXTENDED_READ) |
|
FD_CLR(c->efd, readset); |
|
if (c->extended_usage == CHAN_EXTENDED_WRITE) |
|
FD_CLR(c->efd, writeset); |
|
} |
|
channel_free(c); |
|
} |
|
} |
} |
} |
} |
|
|
|
|
if (compat20 && |
if (compat20 && |
(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) { |
(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) { |
/* XXX is this true? */ |
/* XXX is this true? */ |
debug2("channel %d: no data after CLOSE", c->self); |
debug3("channel %d: will not send data after close", c->self); |
continue; |
continue; |
} |
} |
|
|