1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-26 01:49:31 +03:00

r20960: attempt to fix a valgrind error in the signals backend.

This also reduces the static data in the signal backend when not using
signals to 4 bytes.
(This used to be commit 071a6e8eb1)
This commit is contained in:
Andrew Tridgell
2007-01-23 00:06:33 +00:00
committed by Gerald (Jerry) Carter
parent 2ea9ee8b5a
commit 45c2b83ec7

View File

@ -45,7 +45,7 @@ struct sigcounter {
/*
the poor design of signals means that this table must be static global
*/
static struct {
static struct sig_state {
struct signal_event *sig_handlers[NUM_SIGNALS];
struct sigaction *oldact[NUM_SIGNALS];
struct sigcounter signal_count[NUM_SIGNALS];
@ -56,7 +56,7 @@ static struct {
siginfo_t *sig_info[NUM_SIGNALS];
struct sigcounter sig_blocked[NUM_SIGNALS];
#endif
} sig_state;
} *sig_state;
/*
return number of sigcounter events not processed yet
@ -75,10 +75,10 @@ static uint32_t sig_count(struct sigcounter s)
static void signal_handler(int signum)
{
char c = 0;
SIG_INCREMENT(sig_state.signal_count[signum]);
SIG_INCREMENT(sig_state.got_signal);
SIG_INCREMENT(sig_state->signal_count[signum]);
SIG_INCREMENT(sig_state->got_signal);
/* doesn't matter if this pipe overflows */
write(sig_state.pipe_hack[1], &c, 1);
write(sig_state->pipe_hack[1], &c, 1);
}
#ifdef SA_SIGINFO
@ -87,8 +87,8 @@ static void signal_handler(int signum)
*/
static void signal_handler_info(int signum, siginfo_t *info, void *uctx)
{
uint32_t count = sig_count(sig_state.signal_count[signum]);
sig_state.sig_info[signum][count] = *info;
uint32_t count = sig_count(sig_state->signal_count[signum]);
sig_state->sig_info[signum][count] = *info;
signal_handler(signum);
@ -100,7 +100,7 @@ static void signal_handler_info(int signum, siginfo_t *info, void *uctx)
sigemptyset(&set);
sigaddset(&set, signum);
sigprocmask(SIG_BLOCK, &set, NULL);
SIG_INCREMENT(sig_state.sig_blocked[signum]);
SIG_INCREMENT(sig_state->sig_blocked[signum]);
}
}
#endif
@ -111,15 +111,15 @@ static void signal_handler_info(int signum, siginfo_t *info, void *uctx)
static int signal_event_destructor(struct signal_event *se)
{
se->event_ctx->num_signal_handlers--;
DLIST_REMOVE(sig_state.sig_handlers[se->signum], se);
if (sig_state.sig_handlers[se->signum] == NULL) {
DLIST_REMOVE(sig_state->sig_handlers[se->signum], se);
if (sig_state->sig_handlers[se->signum] == NULL) {
/* restore old handler, if any */
sigaction(se->signum, sig_state.oldact[se->signum], NULL);
sig_state.oldact[se->signum] = NULL;
sigaction(se->signum, sig_state->oldact[se->signum], NULL);
sig_state->oldact[se->signum] = NULL;
#ifdef SA_SIGINFO
if (se->sa_flags & SA_SIGINFO) {
talloc_free(sig_state.sig_info[se->signum]);
sig_state.sig_info[se->signum] = NULL;
talloc_free(sig_state->sig_info[se->signum]);
sig_state->sig_info[se->signum] = NULL;
}
#endif
}
@ -134,7 +134,7 @@ static void signal_pipe_handler(struct event_context *ev, struct fd_event *fde,
{
char c[16];
/* its non-blocking, doesn't matter if we read too much */
read(sig_state.pipe_hack[0], c, sizeof(c));
read(sig_state->pipe_hack[0], c, sizeof(c));
}
/*
@ -154,6 +154,15 @@ struct signal_event *common_event_add_signal(struct event_context *ev,
return NULL;
}
/* the sig_state needs to be on a global context as it can last across
multiple event contexts */
if (sig_state == NULL) {
sig_state = talloc_zero(talloc_autofree_context(), struct sig_state);
if (sig_state == NULL) {
return NULL;
}
}
se = talloc(mem_ctx?mem_ctx:ev, struct signal_event);
if (se == NULL) return NULL;
@ -164,7 +173,7 @@ struct signal_event *common_event_add_signal(struct event_context *ev,
se->sa_flags = sa_flags;
/* only install a signal handler if not already installed */
if (sig_state.sig_handlers[signum] == NULL) {
if (sig_state->sig_handlers[signum] == NULL) {
struct sigaction act;
ZERO_STRUCT(act);
act.sa_handler = signal_handler;
@ -173,40 +182,40 @@ struct signal_event *common_event_add_signal(struct event_context *ev,
if (sa_flags & SA_SIGINFO) {
act.sa_handler = NULL;
act.sa_sigaction = signal_handler_info;
if (sig_state.sig_info[signum] == NULL) {
sig_state.sig_info[signum] = talloc_array(ev, siginfo_t, SA_INFO_QUEUE_COUNT);
if (sig_state.sig_info[signum] == NULL) {
if (sig_state->sig_info[signum] == NULL) {
sig_state->sig_info[signum] = talloc_array(sig_state, siginfo_t, SA_INFO_QUEUE_COUNT);
if (sig_state->sig_info[signum] == NULL) {
talloc_free(se);
return NULL;
}
}
}
#endif
sig_state.oldact[signum] = talloc(ev, struct sigaction);
if (sig_state.oldact[signum] == NULL) {
sig_state->oldact[signum] = talloc(sig_state, struct sigaction);
if (sig_state->oldact[signum] == NULL) {
talloc_free(se);
return NULL;
}
if (sigaction(signum, &act, sig_state.oldact[signum]) == -1) {
if (sigaction(signum, &act, sig_state->oldact[signum]) == -1) {
talloc_free(se);
return NULL;
}
}
DLIST_ADD(sig_state.sig_handlers[signum], se);
DLIST_ADD(sig_state->sig_handlers[signum], se);
talloc_set_destructor(se, signal_event_destructor);
/* we need to setup the pipe hack handler if not already
setup */
if (ev->pipe_fde == NULL) {
if (sig_state.pipe_hack[0] == 0 &&
sig_state.pipe_hack[1] == 0) {
pipe(sig_state.pipe_hack);
set_blocking(sig_state.pipe_hack[0], False);
set_blocking(sig_state.pipe_hack[1], False);
if (sig_state->pipe_hack[0] == 0 &&
sig_state->pipe_hack[1] == 0) {
pipe(sig_state->pipe_hack);
set_blocking(sig_state->pipe_hack[0], False);
set_blocking(sig_state->pipe_hack[1], False);
}
ev->pipe_fde = event_add_fd(ev, ev, sig_state.pipe_hack[0],
ev->pipe_fde = event_add_fd(ev, ev, sig_state->pipe_hack[0],
EVENT_FD_READ, signal_pipe_handler, NULL);
}
ev->num_signal_handlers++;
@ -222,19 +231,20 @@ struct signal_event *common_event_add_signal(struct event_context *ev,
int common_event_check_signal(struct event_context *ev)
{
int i;
if (!SIG_PENDING(sig_state.got_signal)) {
if (!sig_state || !SIG_PENDING(sig_state->got_signal)) {
return 0;
}
for (i=0;i<NUM_SIGNALS+1;i++) {
struct signal_event *se, *next;
struct sigcounter counter = sig_state.signal_count[i];
struct sigcounter counter = sig_state->signal_count[i];
uint32_t count = sig_count(counter);
if (count == 0) {
continue;
}
for (se=sig_state.sig_handlers[i];se;se=next) {
for (se=sig_state->sig_handlers[i];se;se=next) {
next = se->next;
#ifdef SA_SIGINFO
if (se->sa_flags & SA_SIGINFO) {
@ -244,17 +254,17 @@ int common_event_check_signal(struct event_context *ev)
ring buffer */
int ofs = (counter.count + j) % SA_INFO_QUEUE_COUNT;
se->handler(ev, se, i, 1,
(void*)&sig_state.sig_info[i][ofs],
(void*)&sig_state->sig_info[i][ofs],
se->private_data);
}
if (SIG_PENDING(sig_state.sig_blocked[i])) {
if (SIG_PENDING(sig_state->sig_blocked[i])) {
/* we'd filled the queue, unblock the
signal now */
sigset_t set;
sigemptyset(&set);
sigaddset(&set, i);
SIG_SEEN(sig_state.sig_blocked[i],
sig_count(sig_state.sig_blocked[i]));
SIG_SEEN(sig_state->sig_blocked[i],
sig_count(sig_state->sig_blocked[i]));
sigprocmask(SIG_UNBLOCK, &set, NULL);
}
if (se->sa_flags & SA_RESETHAND) {
@ -268,8 +278,8 @@ int common_event_check_signal(struct event_context *ev)
talloc_free(se);
}
}
SIG_SEEN(sig_state.signal_count[i], count);
SIG_SEEN(sig_state.got_signal, count);
SIG_SEEN(sig_state->signal_count[i], count);
SIG_SEEN(sig_state->got_signal, count);
}
return 1;