|
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() */