|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T c
Length: 6232 (0x1858)
Types: TextFile
Names: »conn_select.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
└─⟦eba4602b1⟧ »./isode-5.0.tar.Z«
└─⟦d3ac74d73⟧
└─⟦this⟧ »isode-5.0/quipu/conn_select.c«
/* conn_select.c - tidy connection mesh and choose next activity */
#ifndef lint
static char *rcsid = "$Header: /f/osi/quipu/RCS/conn_select.c,v 6.0 89/03/18 23:41:10 mrose Rel $";
#endif
/*
* $Header: /f/osi/quipu/RCS/conn_select.c,v 6.0 89/03/18 23:41:10 mrose Rel $
*
*
* $Log: conn_select.c,v $
* Revision 6.0 89/03/18 23:41:10 mrose
* Release 5.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 time();
/*
* New strategy is to,
* do any activity for a connection with state INIT,
* extract any connection with state FAIL,
* select any activity for the DSA with the following priority:
* priority as given for state OPEN,
* priority plus highest priority for state EXIT.
*/
int conn_select(act_p)
register struct activity **act_p;
{
int priority;
int action;
struct connection * cn;
struct connection **cn_last;
struct activity * tk;
struct activity * on;
time_t time_now;
char no_block;
DLOG (log_dsap,LLOG_TRACE, ("conn_select"));
/*
* Default action is to await network activity.
* Active read and write ad's are set as the connection mesh is scanned.
*/
no_block = FALSE;
action = ACTIVITY_NET_WAIT;
priority = 0;
(* act_p) = NULLACTIVITY;
id_st.nads = 0;
FD_ZERO(&id_st.iads);
FD_ZERO(&id_st.wads);
cn_last = &(id_st.connlist);
time_now = time((time_t *) 0);
/*
* Check existing connections for higher priority action.
* Set up association descriptors.
*/
for(cn=id_st.connlist; cn!=NULLCONN; cn=(*cn_last))
{
DLOG (log_dsap,LLOG_DEBUG, ("Checking cn with ad = %d", cn->cn_ad));
conn_log(cn);
if(cn->cn_state == CN_STATE_INIT)
{
cn->cn_last_used = time_now;
if(cn->cn_init_act.ia_class == ACTIVITY_NET_SEND)
{
net_send_init_request(cn);
}
if(cn->cn_init_act.ia_class == ACTIVITY_NET_WAIT)
{
if((cn->cn_tasklist != NULLACTIVITY)
&& (cn->cn_tasklist->act_class == ACTIVITY_COLLATE))
{ /* Remote compare in bind needs collating */
dsa_collate(cn->cn_tasklist);
if(cn->cn_init_act.ia_class == ACTIVITY_COLLATE)
{ /* Remote compare completed */
dsa_bind_collate(cn);
}
else
{ /* Do not block when compare has been referred */
no_block = TRUE;
}
}
}
}
if(cn->cn_state == CN_STATE_OPEN)
{
struct activity * next_on;
for(tk=cn->cn_tasklist; tk!=NULLACTIVITY; tk=tk->tk_next)
{
if(tk->act_class == ACTIVITY_NET_WAIT)
continue;
if(tk->act_class == ACTIVITY_NET_SEND)
{
net_send_open_response(tk);
continue;
}
if(tk->act_prio > priority)
{
(*act_p) = tk;
action = tk->act_class;
priority = tk->act_prio;
}
}
for(on=cn->cn_operlist; on!=NULLACTIVITY; on=next_on)
{
next_on = on->on_next_conn;
if(on->on_task == NULLACTIVITY)
{
LLOG(log_dsap, LLOG_DEBUG, ("Watch out for memory twists"));
oper_conn_extract(on);
act_free(on);
}
else
{
if(on->act_class == ACTIVITY_NET_SEND)
{
net_send_ro_invoke(on);
}
}
}
if(cn->cn_initiator == INITIATED_BY_THIS)
{
if((cn->cn_operlist == NULLACTIVITY) &&
(cn->cn_tasklist == NULLACTIVITY))
{
/*
* Should do some timing out here with hooks so that the
* network doesn't block while a connection is timing out.
*/
no_block = TRUE;
LLOG(log_dsap, LLOG_TRACE, ("timeout = %ld, last_used = %ld, time_now = %ld", conn_timeout, cn->cn_last_used, time_now));
if((time_now - cn->cn_last_used) > conn_timeout)
{
LLOG(log_dsap, LLOG_NOTICE, ("Timing out connection"));
cn->cn_state = CN_STATE_EXIT;
cn->cn_exit_act.exit_act_class = ACTIVITY_DSA_WORK;
}
}
else
{
cn->cn_last_used = time_now;
}
}
}
if(cn->cn_state == CN_STATE_EXIT)
{
for(tk=cn->cn_tasklist; tk!=NULLACTIVITY; tk=tk->tk_next)
{
if(tk->act_class == ACTIVITY_NET_WAIT)
continue;
if(tk->act_class == ACTIVITY_NET_SEND)
{
net_send_open_response(tk);
continue;
}
if((tk->act_prio + DSA_MAX_PRIO) > priority)
{
(*act_p) = tk;
action = tk->act_class;
priority = tk->act_prio + DSA_MAX_PRIO;
}
}
if(cn->cn_tasklist == NULLACTIVITY)
{
if(cn->cn_exit_act.exit_act_class == ACTIVITY_DSA_WORK)
{
if(cn->cn_initiator == INITIATED_BY_THIS)
dsa_work_exit_request(cn);
else
dsa_work_exit_response(cn);
}
if(cn->cn_initiator == INITIATED_BY_THIS)
net_send_ac_finish(cn);
else
net_send_ac_exit(cn);
}
}
if(cn->cn_state == CN_STATE_FAIL)
{
for(on=cn->cn_operlist; on!=NULLACTIVITY; on=on->on_next_conn)
{
on->act_class = ACTIVITY_COLLATE;
on->act_type = ACT_TYPE_RESP;
on->act_resp.resp_type = RESP_TYPE_REJ;
if(on->on_task == NULLACTIVITY)
{
DLOG(log_dsap, LLOG_DEBUG, ("Task already collated!"));
}
else
{
on->on_task->act_class = ACTIVITY_COLLATE;
}
}
(*cn_last) = cn->cn_next;
if(cn->cn_ad != 0)
net_send_abort(cn);
conn_extract(cn);
}
else
{
cn_last = &(cn->cn_next);
if((cn->cn_state == CN_STATE_INIT)
&& (cn->cn_init_act.ia_class == ACTIVITY_NET_WAIT)
&& (cn->cn_init_act.ia_type == ACT_TYPE_REQ))
{
FD_SET(cn->cn_ad, &id_st.wads);
}
else
{
FD_SET(cn->cn_ad, &id_st.iads);
}
if(id_st.nads <= cn->cn_ad)
id_st.nads = cn->cn_ad + 1;
}
} /* for each connection */
if((priority == 0) && no_block)
{ /* Poll the network unless something else comes up */
action = ACTIVITY_NET_WAIT;
(*act_p) = (struct activity *) -1;
}
DLOG (log_dsap,LLOG_TRACE, ("Action selected: %d; has priority %d.", action, priority));
return(action);
} /* conn_select() */