|
|
1.1 root 1: /* task_select.c - tidy connection mesh and select next DSA activity */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/quipu/RCS/task_select.c,v 7.2 90/07/09 14:46:43 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/quipu/RCS/task_select.c,v 7.2 90/07/09 14:46:43 mrose Exp $
9: *
10: *
11: * $Log: task_select.c,v $
12: * Revision 7.2 90/07/09 14:46:43 mrose
13: * sync
14: *
15: * Revision 7.1 89/12/19 16:20:51 mrose
16: * sync
17: *
18: * Revision 7.0 89/11/23 22:18:15 mrose
19: * Release 6.0
20: *
21: */
22:
23: /*
24: * NOTICE
25: *
26: * Acquisition, use, and distribution of this module and related
27: * materials are subject to the restrictions of a license agreement.
28: * Consult the Preface in the User's Manual for the full terms of
29: * this agreement.
30: *
31: */
32:
33:
34: #include "quipu/util.h"
35: #include "quipu/connection.h"
36:
37: extern LLog * log_dsap;
38: extern time_t conn_timeout;
39: extern time_t nsap_timeout;
40: extern time_t slave_timeout;
41: extern time_t time();
42: extern time_t timenow;
43: time_t lastedb_update;
44:
45: struct task_act * task_select(secs_p)
46: int * secs_p;
47: {
48: struct connection * cn;
49: struct connection * cn_tmp;
50: struct connection **next_cn;
51: struct task_act * tk;
52: struct task_act **next_tk;
53: struct oper_act * edbon;
54: struct oper_act **next_edbon = (struct oper_act **)NULL;
55: struct oper_act * on;
56: int timeout_tmp;
57: char process_edbs = TRUE;
58: char do_timeout;
59: int suspended = FALSE;
60: struct task_act * ret_tk = NULLTASK;
61: extern char startup_update;
62:
63: (void) time (&timenow);
64: (*secs_p) = NOTOK;
65: conns_used = 0;
66:
67: /*
68: DLOG(log_dsap, LLOG_DEBUG, ("task_select connections:"));
69: conn_list_log(connlist);
70: */
71:
72: for(cn=connlist; cn!=NULLCONN; cn=cn_tmp)
73: {
74: cn_tmp = cn->cn_next; /* Nasty but necessary in conn_extract()
75: manages to get itself called somehow */
76:
77: do_timeout = FALSE;
78:
79: conn_log(cn);
80:
81: next_tk = &(cn->cn_tasklist);
82: for(tk=cn->cn_tasklist; tk!=NULLTASK; tk=(*next_tk))
83: {
84: if(tk->tk_timed)
85: {
86: if(tk->tk_timeout <= timenow)
87: {
88: #ifdef DEBUG
89: struct UTCtime ut;
90: struct UTCtime ut2;
91:
92: DLOG(log_dsap, LLOG_TRACE, ("task has timelimit of %ld", tk->tk_timeout));
93: tm2ut(gmtime(&(tk->tk_timeout)), &ut);
94: DLOG(log_dsap, LLOG_DEBUG, ("converted timelimit = %s", utct2str(&(ut))));
95: tm2ut(gmtime(&(timenow)), &ut2);
96: DLOG(log_dsap, LLOG_DEBUG, ("time now = %s", utct2str(&(ut2))));
97: #endif
98: (*next_tk) = tk->tk_next;
99: timeout_task(tk);
100: continue;
101: }
102: else
103: {
104: timeout_tmp = (int) tk->tk_timeout - timenow;
105: if(((*secs_p) == NOTOK) || ((*secs_p) > timeout_tmp))
106: {
107: (*secs_p) = timeout_tmp;
108: }
109: }
110: }
111:
112: next_tk = &(tk->tk_next);
113: }
114:
115: if(cn->cn_state == CN_OPEN)
116: {
117: next_tk = &(cn->cn_tasklist);
118: for(tk=cn->cn_tasklist; tk!=NULLTASK; tk=(*next_tk))
119: {
120: next_tk = &(tk->tk_next);
121:
122: if(tk->tk_state == TK_ACTIVE)
123: {
124: if( (ret_tk == NULLTASK)
125: || (tk->tk_prio > ret_tk->tk_prio)
126: || ( (tk->tk_prio == ret_tk->tk_prio)
127: && ( (!ret_tk->tk_timed)
128: || ( (tk->tk_timed)
129: && (tk->tk_timeout < ret_tk->tk_timeout)
130: )
131: )
132: )
133: )
134: {
135: ret_tk = tk;
136: }
137: }
138:
139: if(tk->tk_state == TK_SUSPEND)
140: {
141: /*
142: * A task suspended to allow the network to be polled.
143: * Set suspended to force polling.
144: */
145: tk->tk_state = TK_ACTIVE;
146: suspended = TRUE;
147: }
148: }
149:
150: if(cn->cn_tasklist == NULLTASK)
151: {
152: if(cn->cn_initiator)
153: {
154: if(cn->cn_operlist == NULLOPER)
155: {
156: if((cn->cn_last_used + conn_timeout) <= timenow)
157: {
158: do_timeout = TRUE;
159: }
160: else
161: {
162: timeout_tmp = (int) (cn->cn_last_used + conn_timeout) - timenow;
163: if(((*secs_p) == NOTOK) || ((*secs_p) > timeout_tmp))
164: {
165: (*secs_p) = timeout_tmp;
166: }
167: }
168: }
169: else
170: {
171: timeout_tmp = conn_timeout; /* safety catch */
172: if ((tk = cn->cn_operlist->on_task) != NULLTASK) {
173: if (tk->tk_timed) {
174: timeout_tmp = (int) tk->tk_timeout - timenow;
175: if (timeout_tmp < 0)
176: timeout_tmp = 0;
177: }
178: }
179: if(((*secs_p) == NOTOK) || ((*secs_p) > timeout_tmp))
180: {
181: (*secs_p) = timeout_tmp;
182: }
183: cn->cn_last_used = timenow;
184: }
185: }
186: }
187: else
188: {
189: cn->cn_last_used = timenow;
190: process_edbs = FALSE;
191: }
192: } else {
193: if((cn->cn_last_used + nsap_timeout) <= timenow)
194: {
195: if ((cn->cn_state == CN_CONNECTING1) || (cn->cn_state == CN_CONNECTING2))
196: conn_retry(cn);
197: else if (cn->cn_state == CN_CLOSING) {
198: if (conn_release_retry(cn) == NOTOK) {
199: /* had its chance - abort */
200: do_ds_unbind(cn);
201: conn_rel_abort (cn);
202: conn_extract(cn);
203: }
204: } else if (cn->cn_state == CN_OPENING) {
205: /* something started to associate - then gave up !!! */
206: conn_rel_abort (cn);
207: conn_extract (cn);
208: }
209: (*secs_p) = nsap_timeout;
210: }
211: else
212: {
213: timeout_tmp = (int) (cn->cn_last_used + nsap_timeout) - timenow;
214: if(((*secs_p) == NOTOK) || ((*secs_p) > timeout_tmp))
215: {
216: (*secs_p) = timeout_tmp;
217: }
218: }
219: }
220:
221: if(do_timeout)
222: {
223: LLOG(log_dsap, LLOG_NOTICE, ("Timing out connection %d",cn->cn_ad));
224: if (conn_release(cn) == NOTOK) {
225: (*secs_p) = nsap_timeout;
226: conns_used++;
227: }
228: }
229: else
230: {
231: conns_used++;
232: }
233: }
234:
235: /*
236: * Open the connection with the highest priority operation
237: * waiting on it...
238: *
239: * Get DSA Info operations are highest priority, followed by
240: * BIND_COMPARE, and X500, and finally GetEDB operations.
241: */
242: next_cn = &(connwaitlist);
243: for(cn=connwaitlist; cn!=NULLCONN; cn=(*next_cn))
244: {
245: if(conns_used >= MAX_CONNS)
246: break;
247:
248: for(on=cn->cn_operlist; on!=NULLOPER; on=on->on_next_conn)
249: {
250: if(on->on_type == ON_TYPE_GET_DSA_INFO)
251: {
252: (*next_cn) = cn->cn_next;
253: if(conn_request(cn) == OK)
254: {
255: conns_used++;
256: cn->cn_next = connlist;
257: connlist = cn;
258: cn->cn_last_used = timenow;
259: /* Do something with the operations */
260: }
261: else
262: {
263: /* Do something with the operations */
264: }
265: break;
266: }
267: }
268: if(on == NULLOPER)
269: next_cn = &(cn->cn_next);
270: }
271:
272: next_cn = &(connwaitlist);
273: for(cn=connwaitlist; cn!=NULLCONN; cn=(*next_cn))
274: {
275: if(conns_used >= (MAX_CONNS - CONNS_RESERVED_DI))
276: break;
277:
278: for(on=cn->cn_operlist; on!=NULLOPER; on=on->on_next_conn)
279: {
280: if(on->on_type != ON_TYPE_GET_EDB)
281: {
282: (*next_cn) = cn->cn_next;
283: if(conn_request(cn) == OK)
284: {
285: conns_used++;
286: cn->cn_next = connlist;
287: connlist = cn;
288: cn->cn_last_used = timenow;
289: /* Do something with the operations */
290: }
291: else
292: {
293: /* Do something with the operations */
294: }
295: break;
296: }
297: }
298: if(on == NULLOPER)
299: next_cn = &(cn->cn_next);
300: }
301:
302: next_cn = &(connwaitlist);
303: for(cn=connwaitlist; cn!=NULLCONN; cn=(*next_cn))
304: {
305: if(conns_used >= (MAX_CONNS - CONNS_RESERVED_DI - CONNS_RESERVED_X500))
306: break;
307:
308: (*next_cn) = cn->cn_next;
309: if(conn_request(cn) == OK)
310: {
311: conns_used++;
312: cn->cn_next = connlist;
313: connlist = cn;
314: cn->cn_last_used = timenow;
315: /* Do something with the operations */
316: }
317: else
318: {
319: /* Do something with the operations */
320: }
321: }
322:
323: if(process_edbs)
324: {
325: /*
326: * Nothing is happening that would be disturbed by writing back
327: * a retrieved EDB so it is a good time to process them.
328: */
329:
330: next_edbon = &(get_edb_ops);
331: for(edbon=get_edb_ops; edbon!=NULLOPER; edbon=(*next_edbon))
332: {
333: if(edbon->on_state == ON_COMPLETE)
334: {
335: (*next_edbon) = edbon->on_next_task;
336: process_edb(edbon);
337: oper_conn_extract(edbon);
338: oper_free(edbon);
339:
340: (*secs_p) = 0; /* Give edb op's conn a chance to time out */
341:
342: continue;
343: } else if (edbon->on_state == ON_ABANDONED) {
344: LLOG (log_dsap,LLOG_NOTICE,("Get edb has been abandoned"));
345: (*next_edbon) = edbon->on_next_task;
346: oper_free(edbon);
347: }
348:
349: next_edbon = &(edbon->on_next_task);
350: }
351:
352: if ((get_edb_ops == NULLOPER) && startup_update ) {
353: /* see if cache timer has expired - if so resend edb ops... */
354: if ( (timenow - lastedb_update) >= slave_timeout )
355: slave_update();
356: }
357: }
358:
359: if ((get_edb_ops == NULLOPER) && startup_update ) {
360: /* make sure we are awake for the next EDB update */
361: if ((timeout_tmp = lastedb_update + slave_timeout - timenow) >= 0)
362: if (((*secs_p) == NOTOK) || ((*secs_p) > timeout_tmp))
363: (*secs_p) = timeout_tmp;
364: }
365:
366: if(suspended)
367: {
368: /*
369: * A task suspended in order for the network to be checked.
370: * Force this to happen by setting the selected task to NULL
371: * and the polling time of the network to 0 secs.
372: */
373: ret_tk = NULLTASK;
374: (*secs_p) = 0;
375: }
376:
377: return(ret_tk);
378: }
379:
380: timeout_task(tk)
381: struct task_act * tk;
382: {
383: struct oper_act * on;
384: struct DSError * err = &(tk->tk_resp.di_error.de_err);
385: struct ds_search_task *tmp;
386:
387: DLOG(log_dsap, LLOG_TRACE, ("timeout_task"));
388: for(on=tk->tk_operlist; on!=NULLOPER; on=on->on_next_task)
389: {
390: /* Time out operations started by task */
391: on->on_state = ON_ABANDONED;
392: on->on_task = NULLTASK;
393: }
394:
395: if(tk->tk_dx.dx_arg.dca_dsarg.arg_type != OP_SEARCH)
396: {
397: err->dse_type = DSE_SERVICEERROR;
398: if (tk->tk_timed == TRUE)
399: err->ERR_SERVICE.DSE_sv_problem = DSE_SV_TIMELIMITEXCEEDED;
400: else /* tk->tk_timed == 2 */
401: err->ERR_SERVICE.DSE_sv_problem = DSE_SV_ADMINLIMITEXCEEDED;
402: task_error(tk);
403: task_extract(tk);
404: }
405: else
406: {
407: /* Do search collation */
408: if ((tk->tk_state == TK_ACTIVE) && (tk->local_st == NULL_ST)) {
409: /* nothing happened yet... */
410: err->dse_type = DSE_SERVICEERROR;
411: if (tk->tk_timed == TRUE)
412: err->ERR_SERVICE.DSE_sv_problem = DSE_SV_TIMELIMITEXCEEDED;
413: else /* tk->tk_timed == 2 */
414: err->ERR_SERVICE.DSE_sv_problem = DSE_SV_ADMINLIMITEXCEEDED;
415: task_error(tk);
416: } else {
417: /* send the results we have got... */
418: tk->tk_result = &(tk->tk_resp.di_result.dr_res);
419: tk->tk_result->dcr_dsres.result_type = tk->tk_dx.dx_arg.dca_dsarg.arg_type;
420: tk->tk_resp.di_type = DI_RESULT;
421: if (tk->tk_timed == TRUE)
422: tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr.CSR_limitproblem = LSR_TIMELIMITEXCEEDED;
423: else /* tk->tk_timed == 2 */
424: tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr.CSR_limitproblem = LSR_ADMINSIZEEXCEEDED;
425:
426: /* Go through sub-tasks and add a POQ for each */
427: for(tmp=tk->referred_st; tmp!= NULL_ST; tmp=tmp->st_next)
428: add_cref2poq (&tk->tk_result->dcr_dsres.res_sr,tmp->st_cr);
429:
430: task_result(tk);
431: }
432: task_extract(tk);
433: }
434:
435: }
436:
437:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.