|
|
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.