Example #1
0
/*
 * Pretty simple:
 * 1) Set up SIGALRM signal handler
 * 2) set alarmpopped to FALSE;
 * 2) Record current time
 * 3) Call setmsalarm(ms)
 * 4) Call pause(2)
 * 5) Call cancelmstimer()
 * 6) Reset signal handler
 * 7) See if SIGALRM happened
 *    if so:  return zero
 *    if not: get current time, and compute milliseconds left 'til signal
 *	should arrive, and return that...
 */
long
mssleep(long ms)
{
	struct sigaction	saveaction;
	longclock_t		start;
	longclock_t		finish;
	unsigned long		elapsedms;

	memset(&saveaction, 0, sizeof(saveaction));

	cl_signal_set_simple_handler(SIGALRM, st_timer_handler, &saveaction);
	alarmpopped = 0;
	start = time_longclock();
	setmsalarm(ms);
	pause();
	cancelmstimer();
	cl_signal_set_simple_handler(SIGALRM, saveaction.sa_handler, &saveaction);
	if (alarmpopped) {
		return 0;
	}
	
	finish = time_longclock();
	elapsedms = longclockto_ms(sub_longclock(finish, start));
	return ms - elapsedms;
}
Example #2
0
gboolean
G_CH_check_int(GSource* source)
{

	GCHSource* chp = (GCHSource*)source;
	gboolean	ret;
	longclock_t	funstart;

	g_assert(IS_CHSOURCE(chp));
	SAVESTART;
	

	if (chp->dontread){
		/* Make sure output gets unblocked */
		chp->ch->ops->resume_io(chp->ch);
		return FALSE;
	}
	
	ret = (chp->infd.revents != 0
		||	(!chp->fd_fdx && chp->outfd.revents != 0)
		||	chp->ch->ops->is_message_pending(chp->ch));
	if (ret) {
		lc_store((chp->detecttime), time_longclock());
	}
	CHECKEND(chp);
	return ret;
}
Example #3
0
static gboolean
G_SIG_check(GSource* source)
{

	GSIGSource* sig_src = (GSIGSource*)source;

	g_assert(IS_SIGSOURCE(sig_src));
	
	if (sig_src->signal_triggered) {
		clock_t			now;
		clock_t			diff;
		if (cmp_longclock(lc_fetch(sig_src->detecttime), zero_longclock) != 0){
			return TRUE;
		}
		/* Otherwise, this is when it was first detected */
		now = cl_times();
		diff = now - sig_src->sh_detecttime;
		lc_store(
			sig_src->detecttime,
			sub_longclock(time_longclock(), (longclock_t)diff)
		);
		return TRUE;
	}
	return FALSE;
}
Example #4
0
void 
G_main_set_trigger(GTRIGSource* source)
{
	GTRIGSource* trig_src = (GTRIGSource*)source;
	
	g_assert(IS_TRIGSOURCE(trig_src));
	
	trig_src->manual_trigger = TRUE;
	lc_store((trig_src->detecttime), time_longclock());
}
Example #5
0
static gboolean
G_WC_check(GSource * source)
{
	GWCSource* wcp = (GWCSource*)source;
	g_assert(IS_WCSOURCE(wcp));

	if (wcp->gpfd.revents != 0) {
		lc_store((wcp->detecttime), time_longclock());
		return TRUE;
	}
	return FALSE;
}
Example #6
0
static gboolean
G_fd_check(GSource* source)
     
{
	GFDSource*	fdp =  (GFDSource*)source;
	g_assert(IS_FDSOURCE(fdp));
	if (fdp->gpfd.revents) {
		lc_store((fdp->detecttime), time_longclock());
		return TRUE;
	}
	return FALSE;
}
Example #7
0
/* g_main_loop-style check function */
static gboolean
Gmain_timeout_check    (GSource* src)
{
	struct GTimeoutAppend* append = GTIMEOUT(src);
	longclock_t	lnow = time_longclock();
	
	g_assert(IS_TIMEOUTSRC(append));
	if (cmp_longclock(lnow, append->nexttime) >= 0) {
		return TRUE;
	}
	return FALSE;
}
Example #8
0
static gboolean
G_TRIG_check(GSource* source)
{

	GTRIGSource* trig_src = (GTRIGSource*)source;

	g_assert(IS_TRIGSOURCE(trig_src));
	if (trig_src->manual_trigger
	&&	cmp_longclock(lc_fetch(trig_src->detecttime), zero_longclock) == 0) {
		lc_store((trig_src->detecttime), time_longclock());
	}
	return trig_src->manual_trigger;
}
Example #9
0
static gboolean
send_rexmit_request( gpointer data)
{
	struct rexmit_info* ri = (struct rexmit_info*) data;
	seqno_t seq = (seqno_t) ri->seq;
	struct node_info* node = ri->node;
	struct ha_msg*	hmsg;
	
	if ((hmsg = ha_msg_new(6)) == NULL) {
		cl_log(LOG_ERR, "%s: no memory for " T_REXMIT, 
		       __FUNCTION__);
		return FALSE;
	}
	
	
	if (ha_msg_add(hmsg, F_TYPE, T_REXMIT) != HA_OK
	    ||	ha_msg_add(hmsg, F_TO, node->nodename) !=HA_OK
	    ||	ha_msg_add_int(hmsg, F_FIRSTSEQ, seq) != HA_OK
	    ||	ha_msg_add_int(hmsg, F_LASTSEQ, seq) != HA_OK) {
		cl_log(LOG_ERR, "%s: adding fields to msg failed",
		       __FUNCTION__);
		ha_msg_del(hmsg);
		return FALSE;
	}
	
	if (send_cluster_msg(hmsg) != HA_OK) {
		cl_log(LOG_ERR, "%s: cannot send " T_REXMIT
		       " request to %s",__FUNCTION__,  node->nodename);
		ha_msg_del(hmsg);
		return FALSE;
	}
	
	node->track.last_rexmit_req = time_longclock();	
	
	if (!g_hash_table_remove(rexmit_hash_table, ri)){
		cl_log(LOG_ERR, "%s: entry not found in rexmit_hash_table"
		       "for seq/node(%ld %s)", 		       
		       __FUNCTION__, ri->seq, ri->node->nodename);
		return FALSE;
	}
	
	schedule_rexmit_request(node, seq, max_rexmit_delay);
	
	return FALSE;
}
Example #10
0
/* g_main_loop-style prepare function */
static gboolean
Gmain_timeout_prepare(GSource* src,  gint* timeout)
{
	
	struct GTimeoutAppend* append = GTIMEOUT(src);
	longclock_t	lnow = time_longclock();
	longclock_t	remain;
	
	g_assert(IS_TIMEOUTSRC(append));
	if (cmp_longclock(lnow, append->nexttime) >= 0) {
		*timeout = 0L;
		return TRUE;
	}
	/* This is safe - we will always have a positive result */
	remain = sub_longclock(append->nexttime, lnow);
	/* This is also safe - we started out in 'ms' */
	*timeout = longclockto_ms(remain);
	return ((*timeout) == 0);
}
Example #11
0
/*
 *	For  IPC_CHANNEL events, enable output checking when needed
 *	and note when unread input is already queued.
 *
 *	Note that we don't modify 'timeout' either.
 */
gboolean
G_CH_prepare_int(GSource* source,
	     gint* timeout)
{
	GCHSource* chp = (GCHSource*)source;
	longclock_t	funstart;
	gboolean	ret;
	
	g_assert(IS_CHSOURCE(chp));
	SAVESTART;
	
	
	if (chp->ch->ops->is_sending_blocked(chp->ch)) {
		if (chp->fd_fdx) {
			chp->infd.events |= OUTPUT_EVENTS;
		}else{
			chp->outfd.events |= OUTPUT_EVENTS;
		}
	}

	if (chp->ch->recv_queue->current_qlen < chp->ch->recv_queue->max_qlen) {
		chp->infd.events |= INPUT_EVENTS;
	}else{
		/*
		 * This also disables EOF events - until we 
		 * read some of the packets we've already gotten
		 * This prevents a tight loop in poll(2).
		 */
		chp->infd.events &= ~INPUT_EVENTS;
	}

	if (chp->dontread){
		return FALSE;
	}
	ret = chp->ch->ops->is_message_pending(chp->ch);
	if (ret) {
		lc_store((chp->detecttime), time_longclock());
	}
	CHECKEND(chp);
	return ret;
}
Example #12
0
/* g_main_loop-style dispatch function */
static gboolean
Gmain_timeout_dispatch(GSource* src, GSourceFunc func, gpointer user_data)
{
	struct GTimeoutAppend* append = GTIMEOUT(src);
	longclock_t	dispstart;
	gboolean	ret;

	g_assert(IS_TIMEOUTSRC(append));
	lc_store(append->detecttime, append->nexttime);
	CHECK_DISPATCH_DELAY(append);
	

	/* Schedule our next dispatch */
	append->nexttime = add_longclock(time_longclock()
	,	msto_longclock(append->interval));

	/* Then call the user function */
	ret = func(user_data);

	CHECK_DISPATCH_TIME(append);
	return ret;
}
Example #13
0
static gboolean
G_SIG_prepare(GSource* source, gint* timeoutms)
{
	GSIGSource* sig_src = (GSIGSource*)source;
	
	g_assert(IS_SIGSOURCE(sig_src));
	
	/* Don't let a timing window keep us in poll() forever
	 *
	 * The timing window in question looks like this:
	 * No signal has occurred up to the point of prepare being called.
	 * Signal comes in _after_ prepare was called, but _before_ poll.
	 * signal_detected gets set, but no one checks it before going into poll
	 * We wait in poll forever...  It's not a pretty sight :-(.
	 */
	*timeoutms = 1000;	/* Sigh... */

	if (sig_src->signal_triggered) {
		clock_t			now;
		clock_t			diff;

		/* detecttime is reset in the dispatch function */
		if (cmp_longclock(lc_fetch(sig_src->detecttime), zero_longclock) != 0) {
			cl_log(LOG_ERR, "%s: detecttime already set?", __FUNCTION__);
			return TRUE;
		}
		/* Otherwise, this is when it was first detected */
		now = cl_times();
		diff = now - sig_src->sh_detecttime;	/* How long since signal occurred? */
		lc_store(
			sig_src->detecttime,
			sub_longclock(time_longclock(), (longclock_t)diff)
		);
		return TRUE;
	}
	return FALSE;
}
Example #14
0
guint
Gmain_timeout_add_full(gint priority
,	guint interval
,	GSourceFunc	function
,	gpointer	data
,	GDestroyNotify	notify)
{
	
	struct GTimeoutAppend* append;
	
	GSource* source = g_source_new( &Gmain_timeout_funcs, 
					sizeof(struct GTimeoutAppend));
	
	append = GTIMEOUT(source);
	append->magno = MAG_GTIMEOUTSRC;
	append->maxdispatchms = DEFAULT_MAXDISPATCH;
	append->maxdispatchdelayms = DEFAULT_MAXDELAY;
	append->description = "(timeout)";
	lc_store((append->detecttime), zero_longclock);
	append->udata = NULL;
	
	append->nexttime = add_longclock(time_longclock()
	,	msto_longclock(interval));
  	append->interval = interval; 
	
	g_source_set_priority(source, priority);
	
	g_source_set_can_recurse(source, FALSE);
	
	g_source_set_callback(source, function, data, notify); 

	append->gsourceid = g_source_attach(source, NULL);
	g_source_unref(source);
	return append->gsourceid;

}
Example #15
0
int
LogToLoggingDaemon(int priority, const char * buf, 
		   int bufstrlen, gboolean use_pri_str)
{
	IPC_Channel*		chan = logging_daemon_chan;
	static longclock_t	nexttime = 0;
	IPC_Message*		msg;
	int			sendrc = IPC_FAIL;
	int			intval = conn_logd_time;
	
	if (chan == NULL) {
		longclock_t	lnow = time_longclock();
		
		if (cmp_longclock(lnow,  nexttime) >= 0){
			nexttime = add_longclock(
				lnow,  msto_longclock(intval));
			
			logging_daemon_chan = chan = create_logging_channel();
		}
	}

	if (chan == NULL){
		cl_direct_log(
			priority, buf, TRUE, NULL, cl_process_pid, NULLTIME);
		return HA_FAIL;
	}

	msg = ChildLogIPCMessage(priority, buf, bufstrlen, use_pri_str, chan);	
	if (msg == NULL) {
		drop_msg_num++;
		return HA_FAIL;
	}
	
	if (chan->ch_status == IPC_CONNECT){		
		
		if (chan->ops->is_sending_blocked(chan)) {
			chan->ops->resume_io(chan);
		}
		/* Make sure there is room for the drop message _and_ the
		 * one we wish to log.  Otherwise there is no point.
		 *
		 * Try to avoid bouncing on the limit by additionally
		 * waiting until there is room for QUEUE_SATURATION_FUZZ
		 * messages.
		 */
		if (drop_msg_num > 0
		    && chan->send_queue->current_qlen
		    < (chan->send_queue->max_qlen -1 -QUEUE_SATURATION_FUZZ)) {
			/* have to send it this way so the order is correct */
			send_dropped_message(use_pri_str, chan);
		}
	
		sendrc =  chan->ops->send(chan, msg);
	}
	
	if (sendrc == IPC_OK) {		
		return HA_OK;
		
	} else {
		
		if (chan->ops->get_chan_status(chan) != IPC_CONNECT) {
			if (!logging_chan_in_main_loop){
				chan->ops->destroy(chan);
			}
			logging_daemon_chan = NULL;
			cl_direct_log(priority, buf, TRUE, NULL, cl_process_pid, NULLTIME);

			if (drop_msg_num > 0){
				/* Direct logging here is ok since we're
				 *    switching to that for everything
				 *    "for a while"
				 */
				cl_log(LOG_ERR,
				       "cl_log: %d messages were dropped"
				       " : channel destroyed", drop_msg_num);
			}
			
			drop_msg_num=0;
			FreeChildLogIPCMessage(msg);
			return HA_FAIL;
		}

		drop_msg_num++;

	}
	
	FreeChildLogIPCMessage(msg);
	return HA_FAIL;
}
Example #16
0
/*
 *	Some kind of event occurred - notify the user.
 */
gboolean
G_CH_dispatch_int(GSource * source,
	      GSourceFunc callback,
	      gpointer user_data)
{
	GCHSource* chp = (GCHSource*)source;
	longclock_t	dispstart;
	longclock_t	resume_start = zero_longclock;

	g_assert(IS_CHSOURCE(chp));
	CHECK_DISPATCH_DELAY(chp);


	if (chp->dontread){
		return TRUE;
	}

	/* Is output now unblocked? 
	 *
	 * If so, turn off OUTPUT_EVENTS to avoid going into
	 * a tight poll(2) loop.
	 */
	if (chp->fd_fdx) {
		if (chp->infd.revents & OUTPUT_EVENTS) {
			chp->infd.events &= ~OUTPUT_EVENTS;
		}
	}else if (chp->outfd.revents & OUTPUT_EVENTS) {
		chp->outfd.events &= ~OUTPUT_EVENTS;
	}
		
	if (ANYDEBUG) {
		resume_start = time_longclock();
	}

	chp->ch->ops->resume_io(chp->ch);

	if (ANYDEBUG) {
		longclock_t resume_end = time_longclock();
		unsigned long	ms;
		ms = longclockto_ms(sub_longclock(resume_end
		,	resume_start));
		if (ms > 10) {
			cl_log(LOG_WARNING
			,	"%s: resume_io() for %s took %lu ms"
			,	__FUNCTION__
			,	chp->description, ms);
		}
	}


	if(chp->dispatch && chp->ch->ops->is_message_pending(chp->ch)) {
		if(!(chp->dispatch(chp->ch, chp->udata))){
			g_source_remove_poll(source, &chp->infd);
			if (!chp->fd_fdx) {
				g_source_remove_poll(source, &chp->outfd);
			}
			CHECK_DISPATCH_TIME(chp);
			g_source_unref(source);
			return FALSE;
		}
	}
	CHECK_DISPATCH_TIME(chp);

	if (chp->ch->ch_status == IPC_DISCONNECT){
		return FALSE;
	}
	return TRUE;
}