diff --git a/src/rsrv/caswatchdog.c b/src/rsrv/caswatchdog.c new file mode 100644 index 000000000..30a0e726c --- /dev/null +++ b/src/rsrv/caswatchdog.c @@ -0,0 +1,211 @@ +/* + * Author: Jeffrey O. Hill + * hill@atdiv.lanl.gov + * (505) 665 1831 + * Date: 5-92 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * Modification Log: + * ----------------- + * + * Improvements + * ------------ + * + * + * + */ + +static char *sccsId = "@(#)caswatchdog.c 1.3\t7/28/92"; + + +#define CA_WD_DELAY 10 + +#include + +void ca_watchdog_check(); +static +unsigned long clk_rate; +static +unsigned long wd_delay; + +#define MAX_TICK (~((unsigned long)0)) + +int +ca_watchdog_task() +{ + clk_rate = sysClkRateGet(); + wd_delay = clk_rate * CA_WD_DELAY; + + while(TRUE){ + taskDelay(clk_rate); + ca_watchdog_check(); + } +} + +/* + * + * !!!!!!! This will hang if there is a hung client + * + * !!!!!!! cant leave the client queue lock on while + * doing the send !!!!!! + * + * + */ +static void +ca_watchdog_check() +{ + struct client *pc; + unsigned long current; + + current = tickGet(); + + LOCK_CLIENTQ; + pc = (struct client *) ellNext(&clientQ); + while (pc) { + + if(pc->ticks_at_last_io > current){ + elapsed = (MAX_TICK - pc->ticks_at_last_io) + current; + } + + if(elapsed > wd_delay){ + LOCK_CLIENT(pc); + cac_send_heartbeat(pc); + cas_send_msg(pc, FALSE); + UNLOCK_CLIENT(pc); + } + + pc = (struct client *) ellNext(pc); + } + UNLOCK_CLIENTQ; +} + + + + + + + +} +/* + * Author: Jeffrey O. Hill + * hill@atdiv.lanl.gov + * (505) 665 1831 + * Date: 5-92 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * Modification Log: + * ----------------- + * + * Improvements + * ------------ + * + * + * + */ + + +#define CA_WD_DELAY 10 + +void ca_watchdog_check(); +static +unsigned clk_rate; +static +unsigned wd_delay; + +#define MAX_TICK (~((unsigned long)0)) + +int +ca_watchdog_task() +{ + clk_rate = sysClkRateGet(); + wd_delay = clk_rate * CA_WD_DELAY; + + while(TRUE){ + taskDelay(clk_rate); + ca_watchdog_check(); + } +} + +/* + * + * !!!!!!! This will hang if there is a hung client + * + * !!!!!!! cant leave the client queue lock on while + * doing the send !!!!!! + * + * + */ +static void +ca_watchdog_check() +{ + struct client *pc; + unsigned current; + + current = tickGet(); + + LOCK_CLIENTQ; + pc = (struct client *) ellNext(&clientQ); + while (pc) { + if(pc->ticks_at_last_io < current){ + elapsed = pc->ticks_at_last_io + + (-(int)current); + } + if(current - pc->ticks_at_last_io > wd_delay){ + LOCK_CLIENT(pc); + cac_send_heartbeat(pc); + cas_send_msg(pc, FALSE); + UNLOCK_CLIENT(pc); + } + + pc = (struct client *) ellNext(pc); + } + UNLOCK_CLIENTQ; +} + + + + + + + +} diff --git a/src/rsrv/existing_client.c b/src/rsrv/existing_client.c new file mode 100644 index 000000000..3e6981025 --- /dev/null +++ b/src/rsrv/existing_client.c @@ -0,0 +1,130 @@ +/* + * E X I S I T I N G _ C L I E N T . C + * + * + * @(#)existing_client.c + * @(#)existing_client.c 1.3 6/27/91 + * Author: Jeffrey O. Hill + * hill@luke.lanl.gov + * (505) 665 1831 + * Date: 5-88 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * History + * .01 120690 joh added code to avoid overflow of the client timeout + * timer after one year of continuous operation + * .02 071291 joh all of this code eliminate by mods in other files + * .03 021292 joh Better diagnostics + * + */ +#ifdef JUNKYARD + +#include +#include +#include +#include +#include +#include +#include + + +/* + * existing_client() + * + * does this client exist + * + * NOTE: The clientQ should be locked while in this routine + */ +struct client * +existing_client(netaddr) + FAST struct sockaddr_in *netaddr; +{ + FAST struct client *client; + FAST struct in_addr addr; + FAST u_short port = netaddr->sin_port; + + addr.s_addr = netaddr->sin_addr.s_addr; + + client = (struct client *) & clientQ; + + while (client = (struct client *) client->node.next) + if (client->addr.sin_addr.s_addr == addr.s_addr) + if (client->addr.sin_port == port) + break; + + return client; +} + +/* + * clean_clientq() + * + * remove all leftover UDP clients + * + * NOTE: The clientQ should be locked while in this routine + */ +clean_clientq(timeout) + FAST unsigned long timeout; +{ + FAST struct client *client, *nextclient; + FAST unsigned long current = tickGet(); + unsigned long delay; + + nextclient = (struct client *) & clientQ; + + while (client = nextclient) { + nextclient = (struct client *) client->node.next; + + if (client->proto == IPPROTO_UDP) { + + /* + * compute delay, but avoid overflow + */ + if (current >= client->ticks_at_creation) { + delay = current - client->ticks_at_creation; + } else { + delay = current + + (~0 - client->ticks_at_creation); + } + +#ifdef DEBUG + if (delay) + logMsg("CAS: %d sec wait for client conn\n", + delay / sysClkRateGet()); + if (timeout) + logMsg("CAS: UDP client timeout was %d sec\n", + timeout / sysClkRateGet()); +#endif + if (delay > timeout) { + ellDelete(&clientQ, client); + logMsg("CAS: UDP client expired after %d sec\n", + delay / sysClkRateGet()); + terminate_one_client(client); + ellAdd(&rsrv_free_clientQ, client); + } + } + } + + return OK; +} + +#endif