DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T t

⟦c03f9cfa4⟧ TextFile

    Length: 10751 (0x29ff)
    Types: TextFile
    Names: »task_select.c«

Derivation

└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« 
        └─⟦de7628f85⟧ 
            └─⟦this⟧ »isode-6.0/quipu/task_select.c« 

TextFile

/* task_select.c - tidy connection mesh and select next DSA activity */

#ifndef lint
static char *rcsid = "$Header: /f/osi/quipu/RCS/task_select.c,v 7.1 89/12/19 16:20:51 mrose Exp $";
#endif

/*
 * $Header: /f/osi/quipu/RCS/task_select.c,v 7.1 89/12/19 16:20:51 mrose Exp $
 *
 *
 * $Log:	task_select.c,v $
 * Revision 7.1  89/12/19  16:20:51  mrose
 * sync
 * 
 * Revision 7.0  89/11/23  22:18:15  mrose
 * Release 6.0
 * 
 */

/*
 *                                NOTICE
 *
 *    Acquisition, use, and distribution of this module and related
 *    materials are subject to the restrictions of a license agreement.
 *    Consult the Preface in the User's Manual for the full terms of
 *    this agreement.
 *
 */


#include "quipu/util.h"
#include "quipu/connection.h"

extern LLog * log_dsap;
extern time_t	conn_timeout;
extern time_t	nsap_timeout;
extern time_t	slave_timeout;
extern time_t	time();
time_t lastedb_update;

struct task_act	* task_select(secs_p)
int		* secs_p;
{
    struct connection	* cn;
    struct connection	* cn_tmp;
    struct connection	**next_cn;
    struct task_act	* tk;
    struct task_act	**next_tk;
    struct oper_act	* edbon;
    struct oper_act	**next_edbon = (struct oper_act **)NULL;
    struct oper_act	* on;
    time_t		  time_now;
    int			  timeout_tmp;
    char		  process_edbs = TRUE;
    char		  do_timeout;
    int			  suspended = FALSE;
    struct task_act	* ret_tk = NULLTASK;
    extern char	  startup_update;


    time_now = time((time_t *) 0);
    (*secs_p) = NOTOK;
    conns_used = 0;

/*
    DLOG(log_dsap, LLOG_DEBUG, ("task_select connections:"));
    conn_list_log(connlist);
*/

    for(cn=connlist; cn!=NULLCONN; cn=cn_tmp)
    {
	cn_tmp = cn->cn_next;	/* Nasty but necessary in conn_extract()
				   manages to get itself called somehow */

	do_timeout = FALSE;

	conn_log(cn);

	next_tk = &(cn->cn_tasklist);
	for(tk=cn->cn_tasklist; tk!=NULLTASK; tk=(*next_tk))
	    {
		if(tk->tk_timed)
		{
		    if(tk->tk_timeout <= time_now)
		    {
#ifdef DEBUG
			long		  clock;
			struct UTCtime	  ut;
			struct UTCtime	  ut2;

			DLOG(log_dsap, LLOG_TRACE, ("task has timelimit of %ld", tk->tk_timeout));
			tm2ut(gmtime(&(tk->tk_timeout)), &ut);
			DLOG(log_dsap, LLOG_DEBUG, ("converted timelimit = %s", utct2str(&(ut))));
			(void) time(&clock);
			tm2ut(gmtime(&(clock)), &ut2);
			DLOG(log_dsap, LLOG_DEBUG, ("time now = %s", utct2str(&(ut2))));
#endif
			(*next_tk) = tk->tk_next;
			timeout_task(tk);
			continue;
		    }
		    else
		    {
			timeout_tmp = (int) tk->tk_timeout - time_now;
			if(((*secs_p) == NOTOK) || ((*secs_p) > timeout_tmp))
			{
			    (*secs_p) = timeout_tmp;
			}
		    }
		}

		next_tk = &(tk->tk_next);
	}

	if(cn->cn_state == CN_OPEN)
	{
	    next_tk = &(cn->cn_tasklist);
	    for(tk=cn->cn_tasklist; tk!=NULLTASK; tk=(*next_tk))
	    {
		next_tk = &(tk->tk_next);

		if(tk->tk_state == TK_ACTIVE)
		{
		    if(   (ret_tk == NULLTASK)
		       || (tk->tk_prio > ret_tk->tk_prio)
		       || (   (tk->tk_prio == ret_tk->tk_prio)
			   && (   (!ret_tk->tk_timed)
			       || (   (tk->tk_timed)
				   && (tk->tk_timeout < ret_tk->tk_timeout)
				  )
			      )
			  )
		      )
		    {
			ret_tk = tk;
		    }
		}

		if(tk->tk_state == TK_SUSPEND)
		{
		    /*
		    *  A task suspended to allow the network to be polled.
		    *  Set suspended to force polling.
		    */
		    tk->tk_state = TK_ACTIVE;
		    suspended = TRUE;
		}
	    }

	    if(cn->cn_tasklist == NULLTASK)
	    {
		if(cn->cn_initiator == INITIATED_BY_THIS)
		{
		    if(cn->cn_operlist == NULLOPER)
		    {
			if((cn->cn_last_used + conn_timeout) <= time_now)
			{
			    do_timeout = TRUE;
			}
			else
			{
			    timeout_tmp = (int) (cn->cn_last_used + conn_timeout) - time_now;
			    if(((*secs_p) == NOTOK) || ((*secs_p) > timeout_tmp))
			    {
				(*secs_p) = timeout_tmp;
			    }
			}
		    }
		    else
		    {
			timeout_tmp = conn_timeout;	/* safety catch */
			if ((tk = cn->cn_operlist->on_task) != NULLTASK) {
				if (tk->tk_timed)
					timeout_tmp = (int) tk->tk_timeout - time_now;
			} else {
				char alive = FALSE;
				/* is there still an operation active ? */
				for(on=cn->cn_operlist; on!=NULLOPER; on=on->on_next_conn) {
					if (on->on_state != ON_ABANDONED) {
						alive = TRUE;
						break;
					}
				}
				if (!alive) {
					oper_free (cn->cn_operlist);
					cn->cn_operlist = NULLOPER;
				}
			}
			if(((*secs_p) == NOTOK) || ((*secs_p) > timeout_tmp))
			{
				(*secs_p) = timeout_tmp;
			}
			cn->cn_last_used = time_now;
		    }
		}
	    }
	    else
	    {
		cn->cn_last_used = time_now;
		process_edbs = FALSE;
	    }
	} else  {
		if((cn->cn_last_used + nsap_timeout) <= time_now)
		{
		    if ((cn->cn_state == CN_CONNECTING1) || (cn->cn_state == CN_CONNECTING2))
			    conn_retry(cn);
		    else if (cn->cn_state == CN_CLOSING) {
			    if (conn_release_retry(cn) == NOTOK) {
				/* had its chance - abort */
				do_ds_unbind(cn);
		    		conn_rel_abort (cn);
				conn_extract(cn);
			    } 
		    } else if (cn->cn_state == CN_OPENING) {
			/* something started to associate - then gave up !!! */
			conn_rel_abort (cn);
			conn_extract (cn);
		    }
		    (*secs_p) = nsap_timeout;
		}
		else
		{
		    timeout_tmp = (int) (cn->cn_last_used + nsap_timeout) - time_now;
		    if(((*secs_p) == NOTOK) || ((*secs_p) > timeout_tmp))
		    {
			(*secs_p) = timeout_tmp;
		    }
		}
	}

	if(do_timeout)
	{
    	    LLOG(log_dsap, LLOG_NOTICE, ("Timing out connection %d",cn->cn_ad));
    	    if (conn_release(cn) == NOTOK) {
		    (*secs_p) = nsap_timeout;
		    conns_used++;
	    }
	}
	else
	{
	    conns_used++;
	}
    }

/*
*  Open the connection with the highest priority operation
*  waiting on it...
*
*  Get DSA Info operations are highest priority, followed by
*  NameService, BIND_COMPARE, and X500, and finally GetEDB
*  operations.
*/
    next_cn = &(connwaitlist);
    for(cn=connwaitlist; cn!=NULLCONN; cn=(*next_cn))
    {
	if(conns_used >= MAX_CONNS)
	    break;

	for(on=cn->cn_operlist; on!=NULLOPER; on=on->on_next_conn)
	{
	    if(on->on_type == ON_TYPE_GET_DSA_INFO)
	    {
		(*next_cn) = cn->cn_next;
		if(conn_request(cn) == OK)
		{
		    conns_used++;
		    cn->cn_next = connlist;
		    connlist = cn;
		    cn->cn_last_used = time_now;
		    /* Do something with the operations */
		}
		else
		{
		    /* Do something with the operations */
		}
		break;
	    }
	}
	if(on == NULLOPER)
	    next_cn = &(cn->cn_next);
    }

    next_cn = &(connwaitlist);
    for(cn=connwaitlist; cn!=NULLCONN; cn=(*next_cn))
    {
	if(conns_used >= (MAX_CONNS - CONNS_RESERVED_DI))
	    break;

	for(on=cn->cn_operlist; on!=NULLOPER; on=on->on_next_conn)
	{
	    if(on->on_type != ON_TYPE_GET_EDB)
	    {
		(*next_cn) = cn->cn_next;
		if(conn_request(cn) == OK)
		{
		    conns_used++;
		    cn->cn_next = connlist;
		    connlist = cn;
		    cn->cn_last_used = time_now;
		    /* Do something with the operations */
		}
		else
		{
		    /* Do something with the operations */
		}
		break;
	    }
	}
	if(on == NULLOPER)
	    next_cn = &(cn->cn_next);
    }

    next_cn = &(connwaitlist);
    for(cn=connwaitlist; cn!=NULLCONN; cn=(*next_cn))
    {
	if(conns_used >= (MAX_CONNS - CONNS_RESERVED_DI - CONNS_RESERVED_X500))
	    break;

	(*next_cn) = cn->cn_next;
	if(conn_request(cn) == OK)
	{
	    conns_used++;
	    cn->cn_next = connlist;
	    connlist = cn;
	    cn->cn_last_used = time_now;
	    /* Do something with the operations */
	}
	else
	{
	    /* Do something with the operations */
	}
    }

    if(process_edbs)
    {
	/*
	*  Nothing is happening that would be disturbed by writing back
	*  a retrieved EDB so it is a good time to process them.
	*/

	next_edbon = &(get_edb_ops);
	for(edbon=get_edb_ops; edbon!=NULLOPER; edbon=(*next_edbon))
	{
	    if(edbon->on_state == ON_COMPLETE)
	    {
		(*next_edbon) = edbon->on_next_task;
		process_edb(edbon);
		oper_conn_extract(edbon);
		oper_free(edbon);

		(*secs_p) = 0; /* Give edb op's conn a chance to time out */

		continue;
	    } else if (edbon->on_state == ON_ABANDONED) {
		LLOG (log_dsap,LLOG_NOTICE,("Get edb has been abandoned"));
		(*next_edbon) = edbon->on_next_task;
		oper_free(edbon);
	    }

	    next_edbon = &(edbon->on_next_task);
	}

	if ((get_edb_ops == NULLOPER) && startup_update ) {
		/* see if cache timer has expired - if so resend edb ops... */
		if ( (time_now - lastedb_update) >= slave_timeout )
			slave_update();
	}
    }

    if ((get_edb_ops == NULLOPER) && startup_update ) {
	/* make sure we are awake for the next EDB update */
	if ((timeout_tmp = lastedb_update + slave_timeout - time_now) >= 0)
	    	if (((*secs_p) == NOTOK) || ((*secs_p) > timeout_tmp)) 
			(*secs_p) = timeout_tmp;
    }

    if(suspended)
    {
	/*
	*  A task suspended in order for the network to be checked.
	*  Force this to happen by setting the selected task to NULL
	*  and the polling time of the network to 0 secs.
	*/
	ret_tk = NULLTASK;
	(*secs_p) = 0;
    }

    return(ret_tk);
}

timeout_task(tk)
struct task_act	* tk;
{
    struct oper_act	* on;
    struct DSError	* err = &(tk->tk_resp.resp_err);
    struct ds_search_task *tmp;

    DLOG(log_dsap, LLOG_TRACE, ("timeout_task"));
    for(on=tk->tk_operlist; on!=NULLOPER; on=on->on_next_task)
    {
	/* Time out operations started by task */
	on->on_state = ON_ABANDONED;
	on->on_task = NULLTASK;
    }

    if(tk->tk_req.dca_dsarg.arg_type != OP_SEARCH)
    {
	err->dse_type = DSE_SERVICEERROR;
	if (tk->tk_timed == TRUE)
		err->ERR_SERVICE.DSE_sv_problem = DSE_SV_TIMELIMITEXCEEDED;
	else /* tk->tk_timed == 2 */
		err->ERR_SERVICE.DSE_sv_problem = DSE_SV_ADMINLIMITEXCEEDED;
	task_error(tk);
	task_extract(tk);
    }
    else
    {
	/* Do search collation */
	if ((tk->tk_state == TK_ACTIVE) && (tk->local_st == NULL_ST)) {
		/* nothing happened yet... */
		err->dse_type = DSE_SERVICEERROR;
		if (tk->tk_timed == TRUE)
			err->ERR_SERVICE.DSE_sv_problem = DSE_SV_TIMELIMITEXCEEDED;
		else /* tk->tk_timed == 2 */
			err->ERR_SERVICE.DSE_sv_problem = DSE_SV_ADMINLIMITEXCEEDED;
		task_error(tk);
	} else {
		/* send the results we have got... */
		tk->tk_result = &(tk->tk_resp.resp_res);
		tk->tk_result->dcr_dsres.result_type = tk->tk_req.dca_dsarg.arg_type;
		tk->tk_resp.resp_type = RESP_TYPE_RET;
		tk->tk_resp.ret_type = RET_TYPE_RES;
		if (tk->tk_timed == TRUE)
			tk->tk_resp.resp_res.dcr_dsres.res_sr.CSR_limitproblem = LSR_TIMELIMITEXCEEDED;
		else /* tk->tk_timed == 2 */
			tk->tk_resp.resp_res.dcr_dsres.res_sr.CSR_limitproblem = LSR_ADMINSIZEEXCEEDED;

		/* Go through sub-tasks and add a POQ for each */
		for(tmp=tk->referred_st; tmp!= NULL_ST; tmp=tmp->st_next)
			add_cref2poq (&tk->tk_result->dcr_dsres.res_sr,tmp->st_cr);

		task_result(tk);
    	}
	task_extract(tk);
    }

}