示例#1
0
/*
 * Disable SIGALRM and remove all timeouts from the active list,
 * and optionally reset their timeout indicators.
 */
void
disable_all_timeouts(bool keep_indicators)
{
	disable_alarm();

	/*
	 * Only bother to reset the timer if we think it's active.  We could just
	 * let the interrupt happen anyway, but it's probably a bit cheaper to do
	 * setitimer() than to let the useless interrupt happen.
	 */
	if (num_active_timeouts > 0)
	{
		struct itimerval timeval;

		MemSet(&timeval, 0, sizeof(struct itimerval));
		if (setitimer(ITIMER_REAL, &timeval, NULL) != 0)
			elog(FATAL, "could not disable SIGALRM timer: %m");
	}

	num_active_timeouts = 0;

	if (!keep_indicators)
	{
		int			i;

		for (i = 0; i < MAX_TIMEOUTS; i++)
			all_timeouts[i].indicator = false;
	}
}
示例#2
0
/*
 * Cancel the specified timeout.
 *
 * The timeout's I've-been-fired indicator is reset,
 * unless keep_indicator is true.
 *
 * When a timeout is canceled, any other active timeout remains in force.
 * It's not an error to disable a timeout that is not enabled.
 */
void
disable_timeout(TimeoutId id, bool keep_indicator)
{
	int			i;

	/* Assert request is sane */
	Assert(all_timeouts_initialized);
	Assert(all_timeouts[id].timeout_handler != NULL);

	/* Disable timeout interrupts for safety. */
	disable_alarm();

	/* Find the timeout and remove it from the active list. */
	i = find_active_timeout(id);
	if (i >= 0)
		remove_timeout_index(i);

	/* Mark it inactive, whether it was active or not. */
	if (!keep_indicator)
		all_timeouts[id].indicator = false;

	/* Reschedule the interrupt, if any timeouts remain active. */
	if (num_active_timeouts > 0)
		schedule_alarm(GetCurrentTimestamp());
}
示例#3
0
文件: guifn.c 项目: basilfx/u8g2
void gui_Next(void)
{
  if ( gui_menu.me_list == melist_active_alarm_menu )
  {
    disable_alarm();
    if ( gui_alarm_list[gui_data.active_alarm_idx].snooze_count != 0 )
    {
      int i;
      /* this is already the snooze alarm, so clear all and behave like the normal alarm off */
      for( i = 0; i < GUI_ALARM_CNT; i++ )
	gui_alarm_list[i].snooze_count = 0;
    }
    else
    {
      /* enable snooze */
      gui_alarm_list[gui_data.active_alarm_idx].snooze_count = 1;
    }
    gui_data.is_alarm = 0;
    gui_Recalculate();
    menu_SetMEList(&gui_menu, melist_display_time, 0);
  }
  else
  {
    menu_NextFocus(&gui_menu);
  }
}
示例#4
0
/*
 * Cancel multiple timeouts at once.
 *
 * The timeouts' I've-been-fired indicators are reset,
 * unless timeouts[i].keep_indicator is true.
 *
 * This works like calling disable_timeout() multiple times.
 * Use this to reduce the number of GetCurrentTimestamp()
 * and setitimer() calls needed to cancel multiple timeouts.
 */
void
disable_timeouts(const DisableTimeoutParams *timeouts, int count)
{
	int			i;

	Assert(all_timeouts_initialized);

	/* Disable timeout interrupts for safety. */
	disable_alarm();

	/* Cancel the timeout(s). */
	for (i = 0; i < count; i++)
	{
		TimeoutId	id = timeouts[i].id;
		int			idx;

		Assert(all_timeouts[id].timeout_handler != NULL);

		idx = find_active_timeout(id);
		if (idx >= 0)
			remove_timeout_index(idx);

		if (!timeouts[i].keep_indicator)
			all_timeouts[id].indicator = false;
	}

	/* Reschedule the interrupt, if any timeouts remain active. */
	if (num_active_timeouts > 0)
		schedule_alarm(GetCurrentTimestamp());
}
示例#5
0
int stream_handler::on_parse_complete(inmessage* msg)
{
	if (state_ == CONNECT) {
		state_ = REQUEST;
		disable_alarm();
	}
	return msghandler_->on_message(this, msg);
}
示例#6
0
stream_handler::~stream_handler(void)
{
	disable_alarm();
 	if (msgparser_ != NULL)	{
 		delete msgparser_;
 		msgparser_ = NULL;
 	}
}
示例#7
0
/*
 * Reschedule any pending SIGALRM interrupt.
 *
 * This can be used during error recovery in case query cancel resulted in loss
 * of a SIGALRM event (due to longjmp'ing out of handle_sig_alarm before it
 * could do anything).  But note it's not necessary if any of the public
 * enable_ or disable_timeout functions are called in the same area, since
 * those all do schedule_alarm() internally if needed.
 */
void
reschedule_timeouts(void)
{
	/* For flexibility, allow this to be called before we're initialized. */
	if (!all_timeouts_initialized)
		return;

	/* Disable timeout interrupts for safety. */
	disable_alarm();

	/* Reschedule the interrupt, if any timeouts remain active. */
	if (num_active_timeouts > 0)
		schedule_alarm(GetCurrentTimestamp());
}
示例#8
0
/*
 * Enable the specified timeout to fire at the specified time.
 *
 * This is provided to support cases where there's a reason to calculate
 * the timeout by reference to some point other than "now".  If there isn't,
 * use enable_timeout_after(), to avoid calling GetCurrentTimestamp() twice.
 */
void
enable_timeout_at(TimeoutId id, TimestampTz fin_time)
{
	TimestampTz now;

	/* Disable timeout interrupts for safety. */
	disable_alarm();

	/* Queue the timeout at the appropriate time. */
	now = GetCurrentTimestamp();
	enable_timeout(id, now, fin_time);

	/* Set the timer interrupt. */
	schedule_alarm(now);
}
示例#9
0
/*
 * Enable the specified timeout to fire after the specified delay.
 *
 * Delay is given in milliseconds.
 */
void
enable_timeout_after(TimeoutId id, int delay_ms)
{
	TimestampTz now;
	TimestampTz fin_time;

	/* Disable timeout interrupts for safety. */
	disable_alarm();

	/* Queue the timeout at the appropriate time. */
	now = GetCurrentTimestamp();
	fin_time = TimestampTzPlusMilliseconds(now, delay_ms);
	enable_timeout(id, now, fin_time);

	/* Set the timer interrupt. */
	schedule_alarm(now);
}
示例#10
0
文件: guifn.c 项目: basilfx/u8g2
void gui_Select(void)
{
  if ( gui_menu.me_list == melist_active_alarm_menu )
  {
    int i;
    disable_alarm();
    for( i = 0; i < GUI_ALARM_CNT; i++ )
      gui_alarm_list[i].snooze_count = 0;
    gui_data.is_alarm = 0;
    gui_Recalculate();
    menu_SetMEList(&gui_menu, melist_display_time, 0);
  }
  else
  {
    menu_Select(&gui_menu);
  }
}
示例#11
0
文件: main.c 项目: marmolak/exalarm
int main (int argc, char **argv)
{
	(void) argc; (void) argv;

	int exc = 0;
	do_exception (&exc);
	if ( ! exc ) {
		set_alarm (1);
		//failed ();
		sleep (10);
	} else {
		if ( exc == timeout_ex ) {
			printf ("timeout!\n");
		} else if ( exc ) {
			printf ("error code: %d\n", exc);
		}
	}
	disable_alarm ();

	return EXIT_SUCCESS;
}
示例#12
0
/*
 * Enable multiple timeouts at once.
 *
 * This works like calling enable_timeout_after() and/or enable_timeout_at()
 * multiple times.  Use this to reduce the number of GetCurrentTimestamp()
 * and setitimer() calls needed to establish multiple timeouts.
 */
void
enable_timeouts(const EnableTimeoutParams *timeouts, int count)
{
	TimestampTz now;
	int			i;

	/* Disable timeout interrupts for safety. */
	disable_alarm();

	/* Queue the timeout(s) at the appropriate times. */
	now = GetCurrentTimestamp();

	for (i = 0; i < count; i++)
	{
		TimeoutId	id = timeouts[i].id;
		TimestampTz fin_time;

		switch (timeouts[i].type)
		{
			case TMPARAM_AFTER:
				fin_time = TimestampTzPlusMilliseconds(now,
													   timeouts[i].delay_ms);
				enable_timeout(id, now, fin_time);
				break;

			case TMPARAM_AT:
				enable_timeout(id, now, timeouts[i].fin_time);
				break;

			default:
				elog(ERROR, "unrecognized timeout type %d",
					 (int) timeouts[i].type);
				break;
		}
	}

	/* Set the timer interrupt. */
	schedule_alarm(now);
}
示例#13
0
/*
 * Initialize timeout module.
 *
 * This must be called in every process that wants to use timeouts.
 *
 * If the process was forked from another one that was also using this
 * module, be sure to call this before re-enabling signals; else handlers
 * meant to run in the parent process might get invoked in this one.
 */
void
InitializeTimeouts(void)
{
	int			i;

	/* Initialize, or re-initialize, all local state */
	disable_alarm();

	num_active_timeouts = 0;

	for (i = 0; i < MAX_TIMEOUTS; i++)
	{
		all_timeouts[i].index = i;
		all_timeouts[i].indicator = false;
		all_timeouts[i].timeout_handler = NULL;
		all_timeouts[i].start_time = 0;
		all_timeouts[i].fin_time = 0;
	}

	all_timeouts_initialized = true;

	/* Now establish the signal handler */
	pqsignal(SIGALRM, handle_sig_alarm);
}
示例#14
0
/*
 * Signal handler for SIGALRM
 *
 * Process any active timeout reasons and then reschedule the interrupt
 * as needed.
 */
static void
handle_sig_alarm(SIGNAL_ARGS)
{
	int			save_errno = errno;
	bool		save_ImmediateInterruptOK = ImmediateInterruptOK;

	/*
	 * We may be executing while ImmediateInterruptOK is true (e.g., when
	 * mainline is waiting for a lock).  If SIGINT or similar arrives while
	 * this code is running, we'd lose control and perhaps leave our data
	 * structures in an inconsistent state.  Disable immediate interrupts, and
	 * just to be real sure, bump the holdoff counter as well.  (The reason
	 * for this belt-and-suspenders-too approach is to make sure that nothing
	 * bad happens if a timeout handler calls code that manipulates
	 * ImmediateInterruptOK.)
	 *
	 * Note: it's possible for a SIGINT to interrupt handle_sig_alarm before
	 * we manage to do this; the net effect would be as if the SIGALRM event
	 * had been silently lost.  Therefore error recovery must include some
	 * action that will allow any lost interrupt to be rescheduled.  Disabling
	 * some or all timeouts is sufficient, or if that's not appropriate,
	 * reschedule_timeouts() can be called.  Also, the signal blocking hazard
	 * described below applies here too.
	 */
	ImmediateInterruptOK = false;
	HOLD_INTERRUPTS();

	/*
	 * SIGALRM is always cause for waking anything waiting on the process
	 * latch.  Cope with MyProc not being there, as the startup process also
	 * uses this signal handler.
	 */
	if (MyProc)
		SetLatch(&MyProc->procLatch);

	/*
	 * Fire any pending timeouts, but only if we're enabled to do so.
	 */
	if (alarm_enabled)
	{
		/*
		 * Disable alarms, just in case this platform allows signal handlers
		 * to interrupt themselves.  schedule_alarm() will re-enable if
		 * appropriate.
		 */
		disable_alarm();

		if (num_active_timeouts > 0)
		{
			TimestampTz now = GetCurrentTimestamp();

			/* While the first pending timeout has been reached ... */
			while (num_active_timeouts > 0 &&
				   now >= active_timeouts[0]->fin_time)
			{
				timeout_params *this_timeout = active_timeouts[0];

				/* Remove it from the active list */
				remove_timeout_index(0);

				/* Mark it as fired */
				this_timeout->indicator = true;

				/* And call its handler function */
				(*this_timeout->timeout_handler) ();

				/*
				 * The handler might not take negligible time (CheckDeadLock
				 * for instance isn't too cheap), so let's update our idea of
				 * "now" after each one.
				 */
				now = GetCurrentTimestamp();
			}

			/* Done firing timeouts, so reschedule next interrupt if any */
			schedule_alarm(now);
		}
	}

	/*
	 * Re-allow query cancel, and then try to service any cancel request that
	 * arrived meanwhile (this might in particular include a cancel request
	 * fired by one of the timeout handlers).  Since we are in a signal
	 * handler, we mustn't call ProcessInterrupts unless ImmediateInterruptOK
	 * is set; if it isn't, the cancel will happen at the next mainline
	 * CHECK_FOR_INTERRUPTS.
	 *
	 * Note: a longjmp from here is safe so far as our own data structures are
	 * concerned; but on platforms that block a signal before calling the
	 * handler and then un-block it on return, longjmping out of the signal
	 * handler leaves SIGALRM still blocked.  Error cleanup is responsible for
	 * unblocking any blocked signals.
	 */
	RESUME_INTERRUPTS();
	ImmediateInterruptOK = save_ImmediateInterruptOK;
	if (save_ImmediateInterruptOK)
		CHECK_FOR_INTERRUPTS();

	errno = save_errno;
}
示例#15
0
/*
 * Signal handler for SIGALRM
 *
 * Process any active timeout reasons and then reschedule the interrupt
 * as needed.
 */
static void
handle_sig_alarm(SIGNAL_ARGS)
{
	int			save_errno = errno;

	/*
	 * Bump the holdoff counter, to make sure nothing we call will process
	 * interrupts directly. No timeout handler should do that, but these
	 * failures are hard to debug, so better be sure.
	 */
	HOLD_INTERRUPTS();

	/*
	 * SIGALRM is always cause for waking anything waiting on the process
	 * latch.
	 */
	SetLatch(MyLatch);

	/*
	 * Fire any pending timeouts, but only if we're enabled to do so.
	 */
	if (alarm_enabled)
	{
		/*
		 * Disable alarms, just in case this platform allows signal handlers
		 * to interrupt themselves.  schedule_alarm() will re-enable if
		 * appropriate.
		 */
		disable_alarm();

		if (num_active_timeouts > 0)
		{
			TimestampTz now = GetCurrentTimestamp();

			/* While the first pending timeout has been reached ... */
			while (num_active_timeouts > 0 &&
				   now >= active_timeouts[0]->fin_time)
			{
				timeout_params *this_timeout = active_timeouts[0];

				/* Remove it from the active list */
				remove_timeout_index(0);

				/* Mark it as fired */
				this_timeout->indicator = true;

				/* And call its handler function */
				(*this_timeout->timeout_handler) ();

				/*
				 * The handler might not take negligible time (CheckDeadLock
				 * for instance isn't too cheap), so let's update our idea of
				 * "now" after each one.
				 */
				now = GetCurrentTimestamp();
			}

			/* Done firing timeouts, so reschedule next interrupt if any */
			schedule_alarm(now);
		}
	}

	RESUME_INTERRUPTS();

	errno = save_errno;
}