Delay rehashing until we're not processing events
Fixes crash introduced by 0ab6dbbc65
. It's
probably a regression since it defeats a system designed to stop this
from happening, but I didn't dig through the history.
rehash() closes listeners. If we happen to get a single epoll() result
that wants to first rehash and then accept a connection, the epoll info
will point to a freed rb_fde_t. Other selectors should have similar
problems, but we didn't investigate that.
rb_fde_ts are normally batched up and freed outside the event
processing, but as of the above commit close_listeners() screws that up
by closing pending FDs immediately in order to create new listeners.
I think it might be a bit better to revert this behaviour and simply not
close listeners if we are going to open new ones over them, but have
opted for the smallest reasonable change I can think of.
Helped-by: Eric Mertens <emertens@gmail.com>
This commit is contained in:
parent
460e793274
commit
59ea3c6753
4 changed files with 53 additions and 9 deletions
|
@ -642,16 +642,18 @@ attach_conf(struct Client *client_p, struct ConfItem *aconf)
|
|||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* rehash
|
||||
*
|
||||
* Actual REHASH service routine. Called with sig == 0 if it has been called
|
||||
* as a result of an operator issuing this command, else assume it has been
|
||||
* called as a result of the server receiving a HUP signal.
|
||||
*/
|
||||
bool
|
||||
rehash(bool sig)
|
||||
struct rehash_data {
|
||||
bool sig;
|
||||
};
|
||||
|
||||
static void
|
||||
service_rehash(void *data_)
|
||||
{
|
||||
struct rehash_data *data = data_;
|
||||
bool sig = data->sig;
|
||||
|
||||
free(data);
|
||||
|
||||
rb_dlink_node *n;
|
||||
|
||||
hook_data_rehash hdata = { sig };
|
||||
|
@ -684,6 +686,21 @@ rehash(bool sig)
|
|||
privilegeset_cleanup_rehash();
|
||||
|
||||
call_hook(h_rehash, &hdata);
|
||||
}
|
||||
|
||||
/*
|
||||
* rehash
|
||||
*
|
||||
* Called with sig == 0 if it has been called as a result of an operator
|
||||
* issuing this command, else assume it has been called as a result of the
|
||||
* server receiving a HUP signal.
|
||||
*/
|
||||
bool
|
||||
rehash(bool sig)
|
||||
{
|
||||
struct rehash_data *data = rb_malloc(sizeof *data);
|
||||
data->sig = sig;
|
||||
rb_defer(service_rehash, data);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -159,6 +159,7 @@ int rb_ignore_errno(int);
|
|||
void rb_setselect(rb_fde_t *, unsigned int type, PF * handler, void *client_data);
|
||||
void rb_init_netio(void);
|
||||
int rb_select(unsigned long);
|
||||
void rb_defer(void (*)(void *), void *);
|
||||
int rb_fd_ssl(rb_fde_t *F);
|
||||
int rb_get_fd(rb_fde_t *F);
|
||||
const char *rb_get_ssl_strerror(rb_fde_t *F);
|
||||
|
|
|
@ -51,6 +51,14 @@ static rb_bh *fd_heap;
|
|||
static rb_dlink_list timeout_list;
|
||||
static rb_dlink_list closed_list;
|
||||
|
||||
struct defer
|
||||
{
|
||||
rb_dlink_node node;
|
||||
void (*fn)(void *);
|
||||
void *data;
|
||||
};
|
||||
static rb_dlink_list defer_list;
|
||||
|
||||
static struct ev_entry *rb_timeout_ev;
|
||||
|
||||
|
||||
|
@ -2015,10 +2023,27 @@ rb_setselect(rb_fde_t *F, unsigned int type, PF * handler, void *client_data)
|
|||
setselect_handler(F, type, handler, client_data);
|
||||
}
|
||||
|
||||
void
|
||||
rb_defer(void (*fn)(void *), void *data)
|
||||
{
|
||||
struct defer *defer = rb_malloc(sizeof *defer);
|
||||
defer->fn = fn;
|
||||
defer->data = data;
|
||||
rb_dlinkAdd(defer, &defer->node, &defer_list);
|
||||
}
|
||||
|
||||
int
|
||||
rb_select(unsigned long timeout)
|
||||
{
|
||||
int ret = select_handler(timeout);
|
||||
rb_dlink_node *ptr, *next;
|
||||
RB_DLINK_FOREACH_SAFE(ptr, next, defer_list.head)
|
||||
{
|
||||
struct defer *defer = ptr->data;
|
||||
defer->fn(defer->data);
|
||||
rb_dlinkDelete(ptr, &defer_list);
|
||||
rb_free(defer);
|
||||
}
|
||||
rb_close_pending_fds();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ rb_ctime
|
|||
rb_current_time
|
||||
rb_current_time_tv
|
||||
rb_date
|
||||
rb_defer
|
||||
rb_destroy_patricia
|
||||
rb_dictionary_add
|
||||
rb_dictionary_create
|
||||
|
|
Loading…
Reference in a new issue