Previous implemenation used global structure to hold scheduled signal.
If some other thread created new scheduler it reset all the signals,
possibly unscheduling signals that should have been called. Now they
are thread specific.
} SilcUnixSignal;
#define SIGNAL_COUNT 32
} SilcUnixSignal;
#define SIGNAL_COUNT 32
-SilcUnixSignal signal_call[SIGNAL_COUNT];
#if defined(HAVE_EPOLL_WAIT)
#if defined(HAVE_EPOLL_WAIT)
void *app_context)
{
SilcUnixScheduler internal;
void *app_context)
{
SilcUnixScheduler internal;
+ SilcUnixSignal *signal_call;
int i;
internal = silc_scalloc(schedule->stack, 1, sizeof(*internal));
int i;
internal = silc_scalloc(schedule->stack, 1, sizeof(*internal));
internal->app_context = app_context;
internal->app_context = app_context;
- for (i = 0; i < SIGNAL_COUNT; i++) {
- signal_call[i].sig = 0;
- signal_call[i].call = FALSE;
- signal_call[i].schedule = schedule;
+ signal_call = silc_global_get_var("srtsignals", TRUE);
+ if (!signal_call)
+ signal_call = silc_global_set_var("srtsignals",
+ sizeof(*signal_call) * SIGNAL_COUNT,
+ NULL, TRUE);
+ if (signal_call) {
+ for (i = 0; i < SIGNAL_COUNT; i++) {
+ signal_call[i].sig = 0;
+ signal_call[i].call = FALSE;
+ signal_call[i].schedule = schedule;
+ }
}
return (void *)internal;
}
return (void *)internal;
#elif defined(HAVE_POLL) && defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
silc_free(internal->fds);
#endif /* HAVE_POLL && HAVE_SETRLIMIT && RLIMIT_NOFILE */
#elif defined(HAVE_POLL) && defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
silc_free(internal->fds);
#endif /* HAVE_POLL && HAVE_SETRLIMIT && RLIMIT_NOFILE */
+
+ silc_global_del_var("srtsignals", TRUE);
}
/* Wakes up the scheduler */
}
/* Wakes up the scheduler */
static void silc_schedule_internal_sighandler(int signal)
{
int i;
static void silc_schedule_internal_sighandler(int signal)
{
int i;
+ SilcUnixSignal *signal_call = silc_global_get_var("srtsignals", TRUE);
+
+ if (!signal_call)
+ return;
SILC_LOG_DEBUG(("Start"));
SILC_LOG_DEBUG(("Start"));
void *callback_context)
{
SilcUnixScheduler internal = (SilcUnixScheduler)context;
void *callback_context)
{
SilcUnixScheduler internal = (SilcUnixScheduler)context;
+ SilcUnixSignal *signal_call = silc_global_get_var("srtsignals", TRUE);
+ if (!internal || !signal_call)
return;
SILC_LOG_DEBUG(("Registering signal %d", sig));
return;
SILC_LOG_DEBUG(("Registering signal %d", sig));
SilcUInt32 sig)
{
SilcUnixScheduler internal = (SilcUnixScheduler)context;
SilcUInt32 sig)
{
SilcUnixScheduler internal = (SilcUnixScheduler)context;
+ SilcUnixSignal *signal_call = silc_global_get_var("srtsignals", TRUE);
+ if (!internal || !signal_call)
return;
SILC_LOG_DEBUG(("Unregistering signal %d", sig));
return;
SILC_LOG_DEBUG(("Unregistering signal %d", sig));
void silc_schedule_internal_signals_call(SilcSchedule schedule, void *context)
{
SilcUnixScheduler internal = (SilcUnixScheduler)context;
void silc_schedule_internal_signals_call(SilcSchedule schedule, void *context)
{
SilcUnixScheduler internal = (SilcUnixScheduler)context;
+ SilcUnixSignal *signal_call = silc_global_get_var("srtsignals", TRUE);
int i;
SILC_LOG_DEBUG(("Start"));
int i;
SILC_LOG_DEBUG(("Start"));
+ if (!internal || !signal_call)
return;
silc_schedule_internal_signals_block(schedule, context);
return;
silc_schedule_internal_signals_block(schedule, context);