diff --git a/src/ca/access.c b/src/ca/access.c index 4e28f6758..b4f23cbcb 100644 --- a/src/ca/access.c +++ b/src/ca/access.c @@ -628,6 +628,9 @@ int ca_task_initialize() assert(status == OK); } #endif /*vxWorks*/ +#ifdef VMS + setupConnectionTimer(); +#endif } return ECA_NORMAL; } @@ -971,6 +974,9 @@ LOCAL void ca_process_exit() ca_printf("CAC: entering the exit handler 2 %x\n", tid); # endif +#ifdef VMS + removeConnectionTimer(); +#endif # if defined(vxWorks) ca_temp = (struct ca_static *) @@ -1261,25 +1267,7 @@ LOCAL void ca_process_exit() /* * free beacon hash table */ - { - int len; - bhe **ppBHE; - bhe *pBHE; - - len = NELEMENTS(ca_temp->ca_beaconHash); - for( ppBHE = ca_temp->ca_beaconHash; - ppBHE < &ca_temp->ca_beaconHash[len]; - ppBHE++){ - pBHE = *ppBHE; - while(pBHE){ - bhe *pOld; - - pOld = pBHE; - pBHE = pBHE->pNext; - free(pOld); - } - } - } + freeBeaconHash(ca_temp); free((char *)ca_temp); ca_static = (struct ca_static *) NULL; @@ -3063,8 +3051,6 @@ int early; return ECA_EVDISALLOW; } - manage_conn(TRUE); - /* * Flush the send buffers */ @@ -3147,8 +3133,6 @@ int early; return ECA_TIMEOUT; } } - - manage_conn(TRUE); } } @@ -3424,13 +3408,38 @@ struct ioc_in_use *piiu; piiu->send_needed = TRUE; } + +/* + * + * echo_request (lock must be on) + * + */ +#ifdef __STDC__ +void echo_request(struct ioc_in_use *piiu) +#else /*__STDC__*/ +void echo_request(piiu) +struct ioc_in_use *piiu; +#endif /*__STDC__*/ +{ + struct extmsg hdr; + + hdr.m_cmmd = htons(IOC_ECHO); + hdr.m_type = htons(0); + hdr.m_count = htons(0); + hdr.m_cid = htons(0); + hdr.m_available = htons(0); + hdr.m_postsize = 0; + + cac_push_msg(piiu, &hdr, NULL); + + piiu->send_needed = TRUE; +} + /* * * NOOP_MSG (lock must be on) * - * now allows variable size NOOP message - * */ #ifdef __STDC__ void noop_msg(struct ioc_in_use *piiu) diff --git a/src/ca/conn.c b/src/ca/conn.c index 96e72cf20..bcbc3a6bf 100644 --- a/src/ca/conn.c +++ b/src/ca/conn.c @@ -59,14 +59,74 @@ void manage_conn(silent) int silent; #endif { - struct ioc_in_use *piiu; - chid chix; - unsigned int retry_cnt = 0; - unsigned int retry_cnt_no_handler = 0; - ca_time current; + IIU *piiu; + chid chix; + unsigned int retry_cnt = 0; + unsigned int retry_cnt_no_handler = 0; + ca_time current; + int sendBytesPending; + int sendBytesAvailable; + int stmo; + int rtmo; current = time(NULL); + /* + * issue connection heartbeat + */ + LOCK; + for( piiu = (IIU *) iiuList.node.next; + piiu; + piiu = (IIU *) piiu->node.next){ + + if(piiu == piiuCast || !piiu->conn_up){ + continue; + } + + stmo = (current-piiu->timeAtLastSend)>CA_RETRY_PERIOD; + sendBytesPending = cacRingBufferReadSize(&piiu->send, TRUE); + + /* + * mark connection for shutdown if outgoing messages + * are not accepted by TCP/IP for several seconds + */ + if(sendBytesPending && stmo){ + piiu->conn_up = FALSE; + } + + rtmo = (current-piiu->timeAtLastRecv)>CA_RETRY_PERIOD; + sendBytesAvailable = cacRingBufferWriteSize(&piiu->send, TRUE); + + /* + * remain backwards compatible with old servers + */ + if(!CA_V43(CA_PROTOCOL_VERSION, piiu->minor_version_number)){ + if(stmo && rtmo && !sendBytesPending){ + noop_msg(piiu); + } + continue; + } + + if(piiu->echoPending){ + if((current-piiu->timeAtEchoRequest)>CA_ECHO_TIMEOUT){ + /* + * mark connection for shutdown + */ + piiu->conn_up = FALSE; + } + } + else{ + if((current-piiu->timeAtLastRecv)>CA_CONN_VERIFY_PERIOD && + sendBytesAvailable>sizeof(struct extmsg)){ + piiu->echoPending = TRUE; + piiu->timeAtEchoRequest = current; + echo_request(piiu); + } + } + + } + UNLOCK; + if(!piiuCast){ return; } @@ -128,16 +188,17 @@ int silent; */ #ifdef __STDC__ void mark_server_available(struct in_addr *pnet_addr) -#else +#else /*__STDC__*/ void mark_server_available(pnet_addr) struct in_addr *pnet_addr; -#endif +#endif /*__STDC__*/ { int currentPeriod; int currentTime; bhe *pBHE; unsigned index; unsigned port; + int netChange = FALSE; /* * if timers have expired take care of them @@ -151,39 +212,27 @@ struct in_addr *pnet_addr; currentTime = time(NULL); + LOCK; /* * look for it in the hash table */ - index = ntohl(pnet_addr->s_addr); - index &= BHT_INET_ADDR_MASK; - LOCK; - pBHE = ca_static->ca_beaconHash[index]; - while(pBHE){ - if(pBHE->inetAddr.s_addr == - pnet_addr->s_addr){ - - break; - } - pBHE = pBHE->pNext; - } - - /* - * if we have seen the beacon before ignore it - * (unless there is an unusual change in its period) - */ + pBHE = lookupBeaconInetAddr(pnet_addr); if(pBHE){ - int netChange = FALSE; + + /* + * if we have seen the beacon before ignore it + * (unless there is an unusual change in its period) + */ /* * update time stamp and average period */ currentPeriod = currentTime - pBHE->timeStamp; - pBHE->averagePeriod = - (currentPeriod + pBHE->averagePeriod)>>1; + pBHE->averagePeriod = (currentPeriod + pBHE->averagePeriod)>>1; pBHE->timeStamp = currentTime; - + if((currentPeriod>>2)>=pBHE->averagePeriod){ -#ifdef DEBUG +#ifdef DEBUG ca_printf( "net resume seen %x cur=%d avg=%d\n", pnet_addr->s_addr, @@ -203,43 +252,23 @@ struct in_addr *pnet_addr; #endif netChange = TRUE; } - + if(pBHE->piiu){ + pBHE->piiu->timeAtLastRecv = currentTime; + } if(!netChange){ UNLOCK; return; } } else{ - - /* - * create the hash entry - */ - pBHE = (bhe *)calloc(1,sizeof(*pBHE)); + pBHE = createBeaconHashEntry(pnet_addr); if(!pBHE){ UNLOCK; return; } - -#ifdef DEBUG - ca_printf("new IOC %x\n", pnet_addr->s_addr); -#endif - /* - * store the inet address - */ - pBHE->inetAddr = *pnet_addr; - - /* - * start the average at zero - */ - pBHE->averagePeriod = 0; - pBHE->timeStamp = currentTime; - - /* - * install in the hash table - */ - pBHE->pNext = ca_static->ca_beaconHash[index]; - ca_static->ca_beaconHash[index] = pBHE; } + + #ifdef DEBUG ca_printf("CAC: <%s> ",host_from_addr(pnet_addr)); @@ -301,5 +330,160 @@ struct in_addr *pnet_addr; # endif UNLOCK; - } + + +/* + * createBeaconHashEntry() + * + * LOCK must be applied + */ +#ifdef __STDC__ +bhe *createBeaconHashEntry(struct in_addr *pnet_addr) +#else +bhe *createBeaconHashEntry(pnet_addr) +struct in_addr *pnet_addr; +#endif +{ + bhe *pBHE; + unsigned index; + + pBHE = lookupBeaconInetAddr(pnet_addr); + if(pBHE){ + return pBHE; + } + + index = ntohl(pnet_addr->s_addr); + index &= BHT_INET_ADDR_MASK; + + assert(indexca_beaconHash)); + + pBHE = (bhe *)calloc(1,sizeof(*pBHE)); + if(!pBHE){ + return NULL; + } + +#ifdef DEBUG + ca_printf("new IOC %x\n", pnet_addr->s_addr); +#endif + /* + * store the inet address + */ + pBHE->inetAddr = *pnet_addr; + + /* + * start the average at zero + */ + pBHE->averagePeriod = 0; + pBHE->timeStamp = time(NULL); + + /* + * install in the hash table + */ + pBHE->pNext = ca_static->ca_beaconHash[index]; + ca_static->ca_beaconHash[index] = pBHE; + + return pBHE; +} + + +/* + * lookupBeaconInetAddr() + * + * LOCK must be applied + */ +#ifdef __STDC__ +bhe *lookupBeaconInetAddr(struct in_addr *pnet_addr) +#else +bhe *lookupBeaconInetAddr(pnet_addr) +struct in_addr *pnet_addr; +#endif +{ + bhe *pBHE; + unsigned index; + + index = ntohl(pnet_addr->s_addr); + index &= BHT_INET_ADDR_MASK; + + assert(indexca_beaconHash)); + + pBHE = ca_static->ca_beaconHash[index]; + while(pBHE){ + if(pBHE->inetAddr.s_addr == pnet_addr->s_addr){ + break; + } + pBHE = pBHE->pNext; + } + return pBHE; +} + + + +/* + * removeBeaconInetAddr() + * + * LOCK must be applied + */ +#ifdef __STDC__ +void removeBeaconInetAddr(struct in_addr *pnet_addr) +#else /*__STDC__*/ +void removeBeaconInetAddr(pnet_addr) +struct in_addr *pnet_addr; +#endif /*__STDC__*/ +{ + bhe *pBHE; + bhe **ppBHE; + unsigned index; + + index = ntohl(pnet_addr->s_addr); + index &= BHT_INET_ADDR_MASK; + + assert(indexca_beaconHash)); + + ppBHE = &ca_static->ca_beaconHash[index]; + pBHE = *ppBHE; + while(pBHE){ + if(pBHE->inetAddr.s_addr == pnet_addr->s_addr){ + *ppBHE = pBHE->pNext; + free(pBHE); + return; + } + ppBHE = &pBHE->pNext; + pBHE = *ppBHE; + } + assert(0); +} + + +/* + * freeBeaconHash() + * + * LOCK must be applied + */ +#ifdef __STDC__ +void freeBeaconHash(struct ca_static *ca_temp) +#else /*__STDC__*/ +void freeBeaconHash(ca_temp) +struct ca_static *ca_temp; +#endif /*__STDC__*/ +{ + bhe *pBHE; + bhe **ppBHE; + int len; + + len = NELEMENTS(ca_temp->ca_beaconHash); + for( ppBHE = ca_temp->ca_beaconHash; + ppBHE < &ca_temp->ca_beaconHash[len]; + ppBHE++){ + + pBHE = *ppBHE; + while(pBHE){ + bhe *pOld; + + pOld = pBHE; + pBHE = pBHE->pNext; + free(pOld); + } + } +} + diff --git a/src/ca/iocinf.c b/src/ca/iocinf.c index 4cdedbe57..f8579b044 100644 --- a/src/ca/iocinf.c +++ b/src/ca/iocinf.c @@ -138,42 +138,38 @@ struct ioc_in_use **ppiiu; caAddrNode *pNode; struct ioc_in_use *piiu; int status; + bhe *pBHE; /* * look for an existing connection - * - * quite a bottle neck with increasing connection count - * */ LOCK; - for( piiu = (struct ioc_in_use *) iiuList.node.next; - piiu; - piiu = (struct ioc_in_use *) piiu->node.next){ - - if(piiu->sock_proto!=IPPROTO_TCP){ - continue; - } - - pNode = (caAddrNode *)piiu->destAddr.node.next; - assert(pNode); - assert(pNode->destAddr.sockAddr.sa_family == AF_INET); - if(pnet_addr->s_addr == - pNode->destAddr.inetAddr.sin_addr.s_addr){ - - if(!piiu->conn_up){ - continue; - } - - *ppiiu = piiu; + pBHE = lookupBeaconInetAddr(pnet_addr); + if(!pBHE){ + pBHE = createBeaconHashEntry(pnet_addr); + if(!pBHE){ UNLOCK; - return ECA_NORMAL; + return ECA_ALLOCMEM; } - } + } + + if(pBHE->piiu){ + *ppiiu = pBHE->piiu; + status = ECA_NORMAL; + } + else{ + status = create_net_chan( + ppiiu, + pnet_addr, + IPPROTO_TCP); + if(status == ECA_NORMAL){ + pBHE->piiu = *ppiiu; + } + } + UNLOCK; - status = create_net_chan(ppiiu, pnet_addr, IPPROTO_TCP); return status; - } @@ -209,8 +205,6 @@ int net_proto; return ECA_ALLOCMEM; } - piiu->active = FALSE; - piiu->pcas = ca_static; ellInit(&piiu->chidlist); ellInit(&piiu->destAddr); @@ -404,6 +398,10 @@ int net_proto; pnet_addr, piiu->host_name_str, sizeof(piiu->host_name_str)); + + piiu->timeAtLastSend = time(NULL); + piiu->timeAtLastRecv = time(NULL); + break; case IPPROTO_UDP: @@ -706,6 +704,7 @@ struct ioc_in_use *piiu; if(status>=0){ assert(status<=sendCnt); + piiu->timeAtLastSend = time(NULL); CAC_RING_BUFFER_READ_ADVANCE(&piiu->send, status); sendCnt = cacRingBufferReadSize(&piiu->send, FALSE); @@ -829,6 +828,11 @@ int flags; unsigned long minfreespace; unsigned long freespace; + /* + * manage search timers and detect disconnects + */ + manage_conn(TRUE); + LOCK; piiu=(IIU *)iiuList.node.next; while(piiu){ @@ -1291,7 +1295,7 @@ int tid; */ while(TRUE){ timeout.tv_usec = 0; - timeout.tv_sec = 20; + timeout.tv_sec = 1; ca_mux_io(&timeout, CA_DO_RECVS); } } @@ -1373,9 +1377,9 @@ LOCAL void close_ioc(piiu) struct ioc_in_use *piiu; #endif /*__STDC__*/ { - chid chix; - int status; - + caAddrNode *pNode; + chid chix; + int status; /* * dont close twice @@ -1402,7 +1406,6 @@ struct ioc_in_use *piiu; * prior to calling handlers incase the * handler tries to use a channel before * I mark it disconnected. - * */ chix = (chid) &piiu->chidlist.node.next; while(chix = (chid) chix->node.next){ @@ -1414,31 +1417,16 @@ struct ioc_in_use *piiu; chix->ar.write_access = FALSE; } + if(piiu->chidlist.count){ + ca_signal(ECA_DISCONN,piiu->host_name_str); + } + /* * remove IOC from the hash table */ - { - caAddrNode *pNode; - bhe *pBHE; - bhe **ppBHE; - unsigned index; - - pNode = (caAddrNode *) piiu->destAddr.node.next; - index = ntohl(pNode->destAddr.inetAddr.sin_addr.s_addr); - index &= BHT_INET_ADDR_MASK; - ppBHE = &ca_static->ca_beaconHash[index]; - pBHE = *ppBHE; - while(pBHE){ - if(pBHE->inetAddr.s_addr == - pNode->destAddr.inetAddr.sin_addr.s_addr){ - *ppBHE = pBHE->pNext; - free(pBHE); - break; - } - ppBHE = &pBHE->pNext; - pBHE = *ppBHE; - } - } + pNode = (caAddrNode *) piiu->destAddr.node.next; + assert(pNode); + removeBeaconInetAddr(&pNode->destAddr.inetAddr.sin_addr); /* * call their connection handler as required diff --git a/src/ca/iocinf.h b/src/ca/iocinf.h index 4f3071d34..77f2b8b7d 100644 --- a/src/ca/iocinf.h +++ b/src/ca/iocinf.h @@ -83,6 +83,7 @@ static char *iocinfhSccsId = "$Id$"; /* * CA private includes */ +#include "addrList.h" #include "iocmsg.h" #ifndef min @@ -136,36 +137,36 @@ struct pending_io_event{ void *io_done_arg; }; -union caAddr{ - struct sockaddr_in inetAddr; - struct sockaddr sockAddr; -}; - -typedef struct { - ELLNODE node; - union caAddr srcAddr; - union caAddr destAddr; -}caAddrNode; - typedef unsigned long ca_time; -#define MAXCONNTRIES 60 /* N conn retries on unchanged net */ -#define CA_RETRY_PERIOD 5 /* int sec to next keepalive */ -#define CA_RECAST_DELAY 1 /* initial int sec to next recast */ -#define CA_RECAST_PORT_MASK 0x3 /* random retry interval off port */ -#define CA_RECAST_PERIOD 5 /* ul on retry period long term */ +/* + * dont adjust + */ #define CA_CURRENT_TIME 0 /* - * for the beacon's recvd hash table + * these control the duration and period of name resolution + * broadcasts */ -#define BHT_INET_ADDR_MASK 0x7f -typedef struct beaconHashEntry{ - struct beaconHashEntry *pNext; - struct in_addr inetAddr; - int timeStamp; - int averagePeriod; -}bhe; +#define MAXCONNTRIES 60 /* N conn retries on unchanged net */ +#define CA_RECAST_DELAY 1 /* initial int sec to next recast */ +#define CA_RECAST_PORT_MASK 0x3 /* random retry interval off port */ +#define CA_RECAST_PERIOD 5 /* ul on retry period long term */ + +/* + * these two control the period of connection verifies + * (echo requests) - CA_CONN_VERIFY_PERIOD - and how + * long we will wait for an echo reply before we + * give up and flag the connection for disconnect + * - CA_ECHO_TIMEOUT. + */ +#define CA_ECHO_TIMEOUT 5 /* disconn if no echo reply tmo */ +#define CA_CONN_VERIFY_PERIOD 30 /* how often to request echo */ + +/* + * only used when communicating with old servers + */ +#define CA_RETRY_PERIOD 5 /* int sec to next keepalive */ #ifdef vxWorks typedef struct caclient_put_notify{ @@ -289,7 +290,6 @@ typedef struct ioc_in_use{ unsigned minor_version_number; unsigned contiguous_msg_count; unsigned client_busy; - char active; struct ca_buffer send; struct ca_buffer recv; struct extmsg curMsg; @@ -298,6 +298,9 @@ typedef struct ioc_in_use{ unsigned long curDataMax; unsigned long curDataBytes; ca_time timeAtLastRecv; + ca_time timeAtLastSend; + int echoPending; + ca_time timeAtEchoRequest; #ifdef __STDC__ void (*sendBytes)(struct ioc_in_use *); void (*recvBytes)(struct ioc_in_use *); @@ -328,6 +331,17 @@ typedef struct ioc_in_use{ }IIU; +/* + * for the beacon's recvd hash table + */ +#define BHT_INET_ADDR_MASK 0x7f +typedef struct beaconHashEntry{ + struct beaconHashEntry *pNext; + IIU *piiu; + struct in_addr inetAddr; + int timeStamp; + int averagePeriod; +}bhe; struct ca_static{ IIU *ca_piiuCast; @@ -426,6 +440,7 @@ int ca_request_event(evid monix); void ca_busy_message(struct ioc_in_use *piiu); void ca_ready_message(struct ioc_in_use *piiu); void noop_msg(struct ioc_in_use *piiu); +void echo_request(struct ioc_in_use *piiu); void issue_claim_channel(struct ioc_in_use *piiu, chid pchan); void issue_identify_client(struct ioc_in_use *piiu); void issue_client_host_name(struct ioc_in_use *piiu); @@ -505,6 +520,11 @@ int net_proto int ca_check_for_fp(); +void freeBeaconHash(struct ca_static *ca_temp); +void removeBeaconInetAddr(struct in_addr *pnet_addr); +bhe *lookupBeaconInetAddr(struct in_addr *pnet_addr); +bhe *createBeaconHashEntry(struct in_addr *pnet_addr); + #else /*__STDC__*/ int ca_defunct(); int repeater_installed(); @@ -514,6 +534,7 @@ int broadcast_addr(); int local_addr(); void manage_conn(); void noop_msg(); +void echo_request(); void ca_busy_message(); void ca_ready_message(); void flow_control(); @@ -545,6 +566,10 @@ void caAddConfiguredAddr(); void caPrintAddrList(); int create_net_chan(); int ca_check_for_fp(); +void freeBeaconHash(); +void removeBeaconInetAddr(); +bhe *lookupBeaconInetAddr(); +bhe *createBeaconHashEntry(); #endif /*__STDC__*/ /* diff --git a/src/ca/iocmsg.h b/src/ca/iocmsg.h index 285eeb452..881422deb 100644 --- a/src/ca/iocmsg.h +++ b/src/ca/iocmsg.h @@ -15,18 +15,29 @@ * .05 011294 joh New command added - write notify * * .06 020194 joh New command added for CA V4.1 - client name + * + * .07 041194 joh New command added for CA V4.2 - access rights + * + * .08 050594 joh New command added for CA V4.3 - echo request */ #define __IOCMSG__ -static char *iocmsghSccsId = "$Id$ CA version 4.2"; +static char *iocmsghSccsId = "$Id$ CA version 4.3"; /* TCP/UDP port number (bumped each protocol change) */ #define CA_PROTOCOL_VERSION 4 -#define CA_MINOR_VERSION 2 +#define CA_MINOR_VERSION 3 #define CA_UKN_MINOR_VERSION 0 /* unknown minor version */ -#define CA_V41(MAJOR,MINOR) ( ((MAJOR)==4&&(MINOR)>=1) || (MAJOR)>4 ) -#define CA_V42(MAJOR,MINOR) ( ((MAJOR)==4&&(MINOR)>=2) || (MAJOR)>4 ) +#if CA_PROTOCOL_VERSION == 4 +#define CA_V41(MAJOR,MINOR) ((MINOR)>=1) +#define CA_V42(MAJOR,MINOR) ((MINOR)>=2) +#define CA_V43(MAJOR,MINOR) ((MINOR)>=3) +#else +#define CA_V41(MAJOR,MINOR) ( 1 ) +#define CA_V42(MAJOR,MINOR) ( 1 ) +#define CA_V43(MAJOR,MINOR) ( 1 ) +#endif #define CA_PORT_BASE IPPORT_USERRESERVED + 56 #define CA_SERVER_PORT (CA_PORT_BASE+CA_PROTOCOL_VERSION*2) #define CA_CLIENT_PORT (CA_PORT_BASE+CA_PROTOCOL_VERSION*2+1) @@ -60,7 +71,8 @@ static char *iocmsghSccsId = "$Id$ CA version 4.2"; #define IOC_WRITE_NOTIFY 19 /* notify after write chan value */ #define IOC_CLIENT_NAME 20 /* CA V4.1 identify client */ #define IOC_HOST_NAME 21 /* CA V4.1 identify client */ -#define IOC_ACCESS_RIGHTS 22 /* CA V4.1 asynch access rights chg */ +#define IOC_ACCESS_RIGHTS 22 /* CA V4.2 asynch access rights chg */ +#define IOC_ECHO 23 /* CA V4.3 connection verify */ /* * for use with build and search and not_found (if search fails and diff --git a/src/ca/service.c b/src/ca/service.c index 2e4d27387..94477284c 100644 --- a/src/ca/service.c +++ b/src/ca/service.c @@ -257,6 +257,10 @@ struct in_addr *pnet_addr; case IOC_NOOP: break; + case IOC_ECHO: + piiu->echoPending = FALSE; + break; + case IOC_WRITE_NOTIFY: { /* diff --git a/src/ca/syncgrp.c b/src/ca/syncgrp.c index 19bce5bfa..6ce09f9c9 100644 --- a/src/ca/syncgrp.c +++ b/src/ca/syncgrp.c @@ -289,7 +289,6 @@ float timeout; * at least once. */ ca_flush_io(); - manage_conn(TRUE); status = ECA_NORMAL; beg_time = time(NULL); @@ -339,7 +338,6 @@ float timeout; status = ECA_TIMEOUT; break; } - manage_conn(TRUE); } pcasg->opPendCount = 0; pcasg->seqNo++; diff --git a/src/ca/vms_depen.c b/src/ca/vms_depen.c index ce4ecd460..9ea8c3f8c 100644 --- a/src/ca/vms_depen.c +++ b/src/ca/vms_depen.c @@ -47,6 +47,44 @@ #include "iocinf.h" +#define CONNECTION_TIMER_ID 56 + +void connectionTimer(void *astarg); + +struct time{ + int lval; + int hval; +} + +struct time timer = {-10000000,-1}; + + +/* + * + */ +void setupConnectionTimer() +{ + struct time tmo; + int status; + + status = sys$setimr(NULL, &timer, connectionTimer, CONNECTION_TIMER_ID, 0); + assert(status == SS$_NORMAL); +} + + +/* + * connectionTimer() + */ +LOCAL void connectionTimer(void *astarg); + struct time tmo; + int status; + + manage_conn(TRUE); + + status = sys$setimr(NULL, &timer, connectionTimer, CONNECTION_TIMER_ID, 0); + assert(status == SS$_NORMAL); +} + /* * diff --git a/src/rsrv/camessage.c b/src/rsrv/camessage.c index cccfac78b..024b2522c 100644 --- a/src/rsrv/camessage.c +++ b/src/rsrv/camessage.c @@ -241,6 +241,18 @@ struct message_buffer *recv case IOC_NOOP: /* verify TCP */ break; + case IOC_ECHO: /* verify TCP */ + { + struct extmsg *reply; + + SEND_LOCK(client); + reply = ALLOC_MSG(client, 0); + assert (reply); + *reply = *mp; + END_MSG(client); + SEND_UNLOCK(client); + break; + } case IOC_CLIENT_NAME: client_name_action(mp, client); break; @@ -316,13 +328,13 @@ struct message_buffer *recv else{ status = ECA_PUTFAIL; } - LOCK_CLIENT(client); + SEND_LOCK(client); send_err( mp, status, client, RECORD_NAME(&pciu->addr)); - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); break; } status = db_put_field( @@ -331,13 +343,13 @@ struct message_buffer *recv mp + 1, mp->m_count); if (status < 0) { - LOCK_CLIENT(client); + SEND_LOCK(client); send_err( mp, ECA_PUTFAIL, client, RECORD_NAME(&pciu->addr)); - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); } break; @@ -370,9 +382,9 @@ struct message_buffer *recv * most clients dont recover * from this */ - LOCK_CLIENT(client); + SEND_LOCK(client); send_err(mp, ECA_INTERNAL, client, "Invalid Msg"); - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); /* * returning ERROR here disconnects * the client with the bad message @@ -409,8 +421,6 @@ struct client *client char *pMalloc; int status; - LOCK_CLIENT(client); - pName = (char *)(mp+1); size = strlen(pName)+1; /* @@ -425,15 +435,18 @@ struct client *client ""); return; } - if(client->pHostName){ - free(client->pHostName); - } - client->pHostName = pMalloc; strncpy( - client->pHostName, + pMalloc, pName, size-1); - client->pHostName[size-1]='\0'; + pMalloc[size-1]='\0'; + + FASTLOCK(&client->addrqLock); + pName = client->pHostName; + client->pHostName = pMalloc; + if(pName){ + free(pName); + } pciu = (struct channel_in_use *) client->addrq.node.next; while(pciu){ @@ -443,14 +456,13 @@ struct client *client client->pUserName, client->pHostName); if(status != 0 && status != S_asLib_asNotActive){ - UNLOCK_CLIENT(prsrv_cast_client); + FASTUNLOCK(&client->addrqLock); free_client(client); exit(0); } pciu = (struct channel_in_use *) pciu->node.next; } - - UNLOCK_CLIENT(client); + FASTUNLOCK(&client->addrqLock); } @@ -468,8 +480,6 @@ struct client *client char *pMalloc; int status; - LOCK_CLIENT(client); - pName = (char *)(mp+1); size = strlen(pName)+1; /* @@ -484,15 +494,18 @@ struct client *client ""); return; } - if(client->pUserName){ - free(client->pUserName); - } - client->pUserName = pMalloc; strncpy( - client->pUserName, + pMalloc, pName, size-1); - client->pUserName[size-1]='\0'; + pMalloc[size-1]='\0'; + + FASTLOCK(&client->addrqLock); + pName = client->pUserName; + client->pUserName = pMalloc; + if(pName){ + free(pName); + } pciu = (struct channel_in_use *) client->addrq.node.next; while(pciu){ @@ -502,14 +515,13 @@ struct client *client client->pUserName, client->pHostName); if(status != 0 && status != S_asLib_asNotActive){ - UNLOCK_CLIENT(prsrv_cast_client); + FASTUNLOCK(&client->addrqLock); free_client(client); exit(0); } pciu = (struct channel_in_use *) pciu->node.next; } - - UNLOCK_CLIENT(client); + FASTUNLOCK(&client->addrqLock); } @@ -526,7 +538,7 @@ struct client *client struct channel_in_use *pciu; - LOCK_CLIENT(prsrv_cast_client); + FASTLOCK(&prsrv_cast_client->addrqLock); /* * clients which dont claim their @@ -542,7 +554,7 @@ struct client *client NULL, NULL, NULL); - UNLOCK_CLIENT(prsrv_cast_client); + FASTUNLOCK(&prsrv_cast_client->addrqLock); free_client(client); exit(0); } @@ -556,7 +568,7 @@ struct client *client ellDelete( &prsrv_cast_client->addrq, &pciu->node); - UNLOCK_CLIENT(prsrv_cast_client); + FASTUNLOCK(&prsrv_cast_client->addrqLock); /* * Any other client attachment is a severe error @@ -569,7 +581,6 @@ struct client *client NULL, NULL, NULL); - UNLOCK_CLIENT(prsrv_cast_client); free_client(client); exit(0); } @@ -584,9 +595,9 @@ struct client *client client->pUserName, client->pHostName); if(status != 0 && status != S_asLib_asNotActive){ - LOCK_CLIENT(client); + SEND_LOCK(client); send_err(mp, ECA_ALLOCMEM, client, "No room for security table"); - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); free_client(client); exit(0); } @@ -597,10 +608,10 @@ struct client *client */ asPutClientPvt(pciu->asClientPVT, pciu); - LOCK_CLIENT(client); + FASTLOCK(&prsrv_cast_client->addrqLock); pciu->client = client; ellAdd(&client->addrq, &pciu->node); - UNLOCK_CLIENT(client); + FASTUNLOCK(&prsrv_cast_client->addrqLock); /* * The available field is used (abused) @@ -634,7 +645,7 @@ struct client *client if(v42){ struct extmsg *claim_reply; - LOCK_CLIENT(client); + SEND_LOCK(client); claim_reply = (struct extmsg *) ALLOC_MSG(client, 0); assert (claim_reply); @@ -644,7 +655,7 @@ struct client *client claim_reply->m_count = pciu->addr.no_elements; claim_reply->m_cid = pciu->cid; END_MSG(client); - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); } } @@ -706,7 +717,7 @@ void write_notify_reply(void *pArg) pClient = pArg; - LOCK_CLIENT(pClient); + SEND_LOCK(pClient); while(TRUE){ /* * independent lock used here in order to @@ -766,7 +777,7 @@ void write_notify_reply(void *pArg) END_MSG(pClient); ppnb->busy = FALSE; } - UNLOCK_CLIENT(pClient); + SEND_UNLOCK(pClient); /* * wakeup the TCP thread if it is waiting for a cb to complete @@ -888,7 +899,7 @@ LOCAL void putNotifyErrorReply(struct client *client, struct extmsg *mp, int sta { struct extmsg *preply; - LOCK_CLIENT(client); + SEND_LOCK(client); preply = ALLOC_MSG(client, 0); if(!preply){ logMsg("Fatal Error:%s, %d\n", @@ -908,7 +919,7 @@ LOCAL void putNotifyErrorReply(struct client *client, struct extmsg *mp, int sta */ preply->m_cid = statusCA; END_MSG(client); - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); } @@ -927,18 +938,18 @@ struct client *client client->eventsoff = FALSE; - LOCK_CLIENT(client); - + FASTLOCK(&client->addrqLock); pciu = (struct channel_in_use *) client->addrq.node.next; while (pciu) { + FASTLOCK(&client->eventqLock); pevext = (struct event_ext *) pciu->eventq.node.next; while (pevext){ if (pevext->modified) { evext = *pevext; - evext.send_lock = FALSE; + evext.send_lock = TRUE; evext.get = TRUE; read_reply( &evext, @@ -950,11 +961,12 @@ struct client *client pevext = (struct event_ext *) pevext->node.next; } + FASTUNLOCK(&client->eventqLock); pciu = (struct channel_in_use *) pciu->node.next; } - UNLOCK_CLIENT(client); + FASTUNLOCK(&client->addrqLock); } @@ -987,13 +999,13 @@ struct client *client if (!pevext) { pevext = (struct event_ext *) malloc(size); if (!pevext) { - LOCK_CLIENT(client); + SEND_LOCK(client); send_err( mp, ECA_ALLOCMEM, client, RECORD_NAME(&pciu->addr)); - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); return; } } @@ -1005,9 +1017,9 @@ struct client *client pevext->mask = ((struct monops *) mp)->m_info.m_mask; pevext->get = FALSE; - LOCK_CLIENT(client); + FASTLOCK(&client->eventqLock); ellAdd( &pciu->eventq, &pevext->node); - UNLOCK_CLIENT(client); + FASTUNLOCK(&client->eventqLock); pevext->pdbev = (struct event_block *)(pevext+1); @@ -1020,13 +1032,13 @@ struct client *client pevext->pdbev); if (status == ERROR) { pevext->pdbev = NULL; - LOCK_CLIENT(client); + SEND_LOCK(client); send_err( mp, ECA_ADDFAIL, client, RECORD_NAME(&pciu->addr)); - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); return; } @@ -1107,9 +1119,9 @@ struct client *client } while (TRUE){ - LOCK_CLIENT(client); + FASTLOCK(&client->eventqLock); pevext = (struct event_ext *) ellGet(&pciu->eventq); - UNLOCK_CLIENT(client); + FASTUNLOCK(&client->eventqLock); if(!pevext){ break; @@ -1136,17 +1148,20 @@ struct client *client /* * send delete confirmed message */ - LOCK_CLIENT(client); + SEND_LOCK(client); reply = (struct extmsg *) ALLOC_MSG(client, 0); if (!reply) { - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); taskSuspend(0); } *reply = *mp; END_MSG(client); + SEND_UNLOCK(client); + + FASTLOCK(&client->addrqLock); ellDelete(&client->addrq, &pciu->node); - UNLOCK_CLIENT(client); + FASTUNLOCK(&client->addrqLock); /* * remove from access control list @@ -1204,7 +1219,7 @@ struct client *client * search events on this channel for a match * (there are usually very few monitors per channel) */ - LOCK_CLIENT(client); + FASTLOCK(&client->eventqLock); for (pevext = (struct event_ext *) ellFirst(&pciu->eventq); pevext; pevext = (struct event_ext *) ellNext(&pevext->node)){ @@ -1214,15 +1229,15 @@ struct client *client break; } } - UNLOCK_CLIENT(client); + FASTUNLOCK(&client->eventqLock); /* * Not Found- return an exception event */ if(!pevext){ - LOCK_CLIENT(client); + SEND_LOCK(client); send_err(mp, ECA_BADMONID, client, RECORD_NAME(&pciu->addr)); - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); return; } @@ -1238,17 +1253,17 @@ struct client *client /* * send delete confirmed message */ - LOCK_CLIENT(client); + SEND_LOCK(client); reply = (struct extmsg *) ALLOC_MSG(client, 0); if (!reply) { - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); assert(0); } *reply = pevext->msg; reply->m_postsize = 0; END_MSG(client); - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); FASTLOCK(&rsrv_free_eventq_lck); ellAdd(&rsrv_free_eventq, &pevext->node); @@ -1287,7 +1302,7 @@ db_field_log *pfl return; } if (pevext->send_lock) - LOCK_CLIENT(client); + SEND_LOCK(client); reply = (struct extmsg *) ALLOC_MSG(client, pevext->size); if (!reply) { @@ -1295,7 +1310,7 @@ db_field_log *pfl if (!eventsRemaining) cas_send_msg(client,!pevext->send_lock); if (pevext->send_lock) - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); return; } @@ -1333,7 +1348,7 @@ db_field_log *pfl if (!eventsRemaining) cas_send_msg(client,!pevext->send_lock); if (pevext->send_lock){ - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); } return; } @@ -1414,7 +1429,7 @@ db_field_log *pfl cas_send_msg(client,!pevext->send_lock); if (pevext->send_lock) - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); return; } @@ -1495,7 +1510,7 @@ struct client *client { FAST struct extmsg *reply; - LOCK_CLIENT(client); + SEND_LOCK(client); reply = (struct extmsg *) ALLOC_MSG(client, 0); if (!reply) taskSuspend(0); @@ -1504,7 +1519,7 @@ struct client *client END_MSG(client); - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); return; } @@ -1530,6 +1545,16 @@ struct client *client unsigned long sid; + /* + * set true if max memory block drops below MAX_BLOCK_THRESHOLD + */ + if(casDontAllowSearchReplies){ + SEND_LOCK(client); + send_err(mp, ECA_ALLOCMEM, client, "below MAX_BLOCK_THRESHOLD"); + SEND_UNLOCK(client); + return; + } + /* Exit quickly if channel not on this node */ status = db_name_to_addr( mp->m_cmmd == IOC_BUILD ? mp + 2 : mp + 1, @@ -1556,9 +1581,9 @@ struct client *client if (!pchannel) { pchannel = (struct channel_in_use *) malloc(sizeof(*pchannel)); if (!pchannel) { - LOCK_CLIENT(client); + SEND_LOCK(client); send_err(mp, ECA_ALLOCMEM, client, RECORD_NAME(&tmp_addr)); - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); return; } } @@ -1581,9 +1606,9 @@ struct client *client if (mp->m_cmmd == IOC_BUILD) { printf("Build access security bypassed\n"); #endif - LOCK_CLIENT(client); + SEND_LOCK(client); send_err(mp, ECA_NORDACCESS, client, RECORD_NAME(&tmp_addr)); - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); FASTLOCK(&rsrv_free_addrq_lck); ellAdd(&rsrv_free_addrq, &pchannel->node); FASTUNLOCK(&rsrv_free_addrq_lck); @@ -1600,9 +1625,9 @@ printf("Build access security bypassed\n"); status = bucketAddItem(pCaBucket, sid, pchannel); FASTUNLOCK(&rsrv_free_addrq_lck); if(status!=BUCKET_SUCCESS){ - LOCK_CLIENT(client); + SEND_LOCK(client); send_err(mp, ECA_ALLOCMEM, client, "No room for hash table"); - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); FASTLOCK(&rsrv_free_addrq_lck); ellAdd(&rsrv_free_addrq, &pchannel->node); FASTUNLOCK(&rsrv_free_addrq_lck); @@ -1613,7 +1638,7 @@ printf("Build access security bypassed\n"); * UDP reliability schemes rely on both msgs in same reply Therefore * the send buffer locked while both messages are placed */ - LOCK_CLIENT(client); + SEND_LOCK(client); if (mp->m_cmmd == IOC_BUILD) { @@ -1635,14 +1660,12 @@ printf("Build access security bypassed\n"); if (!get_reply) { /* tell them that their request is to large */ send_err(mp, ECA_TOLARGE, client, RECORD_NAME(&tmp_addr)); - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); FASTLOCK(&rsrv_free_addrq_lck); bucketRemoveItem( pCaBucket, pchannel->sid, pchannel); - FASTUNLOCK(&rsrv_free_addrq_lck); - FASTLOCK(&rsrv_free_addrq_lck); ellAdd(&rsrv_free_addrq, &pchannel->node); FASTUNLOCK(&rsrv_free_addrq_lck); return; @@ -1694,11 +1717,13 @@ printf("Build access security bypassed\n"); *pMinorVersion = htons(CA_MINOR_VERSION); END_MSG(client); + SEND_UNLOCK(client); /* store the addr block on the cast queue until it is claimed */ + FASTLOCK(&client->addrqLock); ellAdd(&client->addrq, &pchannel->node); + FASTUNLOCK(&client->addrqLock); - UNLOCK_CLIENT(client); return; } @@ -1718,7 +1743,7 @@ struct client *client { FAST struct extmsg *reply; - LOCK_CLIENT(client); + SEND_LOCK(client); reply = (struct extmsg *) ALLOC_MSG(client, 0); if (!reply) { taskSuspend(0); @@ -1728,7 +1753,7 @@ struct client *client reply->m_postsize = 0; END_MSG(client); - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); } @@ -1857,7 +1882,7 @@ unsigned lineno ) { log_header(mp,0); - LOCK_CLIENT(client); + SEND_LOCK(client); send_err( mp, ECA_INTERNAL, @@ -1865,7 +1890,7 @@ unsigned lineno "Bad Resource ID at %s.%d", pFileName, lineno); - UNLOCK_CLIENT(client); + SEND_UNLOCK(client); } @@ -1985,11 +2010,10 @@ LOCAL void casAccessRightsCB(ASCLIENTPVT ascpvt, asClientStatus type) access_rights_reply(pciu); - LOCK_CLIENT(pclient); - /* * Update all event call backs */ + FASTLOCK(&pclient->eventqLock); for (pevext = (struct event_ext *) ellFirst(&pciu->eventq); pevext; pevext = (struct event_ext *) ellNext(&pevext->node)){ @@ -2006,8 +2030,7 @@ LOCAL void casAccessRightsCB(ASCLIENTPVT ascpvt, asClientStatus type) db_post_single_event(pevext->pdbev); } } - - UNLOCK_CLIENT(pclient); + FASTUNLOCK(&pclient->eventqLock); break; @@ -2047,7 +2070,7 @@ LOCAL void access_rights_reply(struct channel_in_use *pciu) ar |= CA_ACCESS_RIGHT_WRITE; } - LOCK_CLIENT(pclient); + SEND_LOCK(pclient); reply = (struct extmsg *)ALLOC_MSG(pclient, 0); assert(reply); @@ -2056,5 +2079,5 @@ LOCAL void access_rights_reply(struct channel_in_use *pciu) reply->m_cid = pciu->cid; reply->m_available = ar; END_MSG(pclient); - UNLOCK_CLIENT(pclient); + SEND_UNLOCK(pclient); } diff --git a/src/rsrv/caserverio.c b/src/rsrv/caserverio.c index 2edc9a631..935a7751a 100644 --- a/src/rsrv/caserverio.c +++ b/src/rsrv/caserverio.c @@ -93,7 +93,7 @@ int lock_needed; } if(lock_needed){ - LOCK_CLIENT(pclient); + SEND_LOCK(pclient); } if(pclient->send.stk){ @@ -147,7 +147,7 @@ int lock_needed; if(lock_needed){ - UNLOCK_CLIENT(pclient); + SEND_UNLOCK(pclient); } return; diff --git a/src/rsrv/caservertask.c b/src/rsrv/caservertask.c index 1b93fc0e9..3c5c99c69 100644 --- a/src/rsrv/caservertask.c +++ b/src/rsrv/caservertask.c @@ -274,9 +274,9 @@ LOCAL int terminate_one_client(struct client *client) } while(TRUE){ - LOCK_CLIENT(client); + FASTLOCK(&client->addrqLock); pciu = (struct channel_in_use *) ellGet(&client->addrq); - UNLOCK_CLIENT(client); + FASTUNLOCK(&client->addrqLock); if(!pciu){ break; } @@ -294,9 +294,9 @@ LOCAL int terminate_one_client(struct client *client) /* * AS state change could be using this list */ - LOCK_CLIENT(client); + FASTLOCK(&client->eventqLock); pevext = (struct event_ext *) ellGet(&pciu->eventq); - UNLOCK_CLIENT(client); + FASTUNLOCK(&client->eventqLock); if(!pevext){ break; } @@ -356,6 +356,26 @@ LOCAL int terminate_one_client(struct client *client) NULL, NULL); + if(FASTLOCKFREE(&client->eventqLock)<0){ + logMsg("CAS: couldnt free sem\n", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL); + } + + if(FASTLOCKFREE(&client->addrqLock)<0){ + logMsg("CAS: couldnt free sem\n", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL); + } + if(FASTLOCKFREE(&client->putNotifyLock)<0){ logMsg("CAS: couldnt free sem\n", NULL, @@ -499,7 +519,8 @@ LOCAL void log_one_client(struct client *client) bytes_reserved = 0; bytes_reserved += sizeof(struct client); - LOCK_CLIENT(client); + + FASTLOCK(&client->addrqLock); pciu = (struct channel_in_use *) client->addrq.node.next; while (pciu){ bytes_reserved += sizeof(struct channel_in_use); @@ -512,7 +533,7 @@ LOCAL void log_one_client(struct client *client) } pciu = (struct channel_in_use *) ellNext(&pciu->node); } - UNLOCK_CLIENT(client); + FASTUNLOCK(&client->addrqLock); psaddr = &client->addr; printf("\tRemote address %u.%u.%u.%u Remote port %d state=%s\n", @@ -525,7 +546,7 @@ LOCAL void log_one_client(struct client *client) printf( "\tChannel count %d\n", ellCount(&client->addrq)); printf( "\t%d bytes allocated\n", bytes_reserved); - LOCK_CLIENT(client); + FASTLOCK(&client->addrqLock); pciu = (struct channel_in_use *) client->addrq.node.next; i=0; while (pciu){ @@ -539,7 +560,7 @@ LOCAL void log_one_client(struct client *client) printf("\n"); } } - UNLOCK_CLIENT(client); + FASTUNLOCK(&client->addrqLock); printf("\n"); diff --git a/src/rsrv/cast_server.c b/src/rsrv/cast_server.c index ed5a9edee..1621dd28c 100644 --- a/src/rsrv/cast_server.c +++ b/src/rsrv/cast_server.c @@ -82,7 +82,7 @@ static char *sccsId = "$Id$"; #include -LOCAL void clean_addrq(struct client *pclient); +LOCAL void clean_addrq(); @@ -298,7 +298,7 @@ int cast_server(void) if(nchars == 0){ cas_send_msg(prsrv_cast_client, TRUE); - clean_addrq(prsrv_cast_client); + clean_addrq(); } } } @@ -311,8 +311,7 @@ int cast_server(void) */ #define TIMEOUT 60 /* sec */ -LOCAL void -clean_addrq(struct client *pclient) +LOCAL void clean_addrq() { struct channel_in_use *pciu; struct channel_in_use *pnextciu; @@ -325,9 +324,9 @@ clean_addrq(struct client *pclient) current = tickGet(); - LOCK_CLIENT(prsrv_cast_client); + FASTLOCK(&prsrv_cast_client->addrqLock); pnextciu = (struct channel_in_use *) - pclient->addrq.node.next; + prsrv_cast_client->addrq.node.next; while(pciu = pnextciu){ pnextciu = (struct channel_in_use *)pciu->node.next; @@ -342,7 +341,7 @@ clean_addrq(struct client *pclient) if (delay > timeout) { int status; - ellDelete(&pclient->addrq, &pciu->node); + ellDelete(&prsrv_cast_client->addrq, &pciu->node); FASTLOCK(&rsrv_free_addrq_lck); s = bucketRemoveItem(pCaBucket, pciu->sid, pciu); if(s != BUCKET_SUCCESS){ @@ -361,7 +360,7 @@ clean_addrq(struct client *pclient) maxdelay = max(delay, maxdelay); } } - UNLOCK_CLIENT(prsrv_cast_client); + FASTUNLOCK(&prsrv_cast_client->addrqLock); # ifdef DEBUG if(ndelete){ @@ -471,6 +470,8 @@ struct client *create_udp_client(unsigned sock) FASTLOCKINIT(&client->lock); FASTLOCKINIT(&client->putNotifyLock); + FASTLOCKINIT(&client->addrqLock); + FASTLOCKINIT(&client->eventqLock); client->recv.maxstk = MAX_UDP; diff --git a/src/rsrv/online_notify.c b/src/rsrv/online_notify.c index 1112f8c4e..be818fab2 100644 --- a/src/rsrv/online_notify.c +++ b/src/rsrv/online_notify.c @@ -52,19 +52,17 @@ static char *sccsId = "$Id$\t$Date$"; #include #include #include +#include + +#define MAX_BLOCK_THRESHOLD 100000 /* * EPICS includes */ -#include -#if 0 -#include -#include -#include -#include #include -#endif - +#include "server.h" +#include +#include /* * RSRV_ONLINE_NOTIFY_TASK @@ -91,7 +89,7 @@ int rsrv_online_notify_task() int sock; int true = TRUE; - taskwdInsert((int)taskIdCurrent,NULL,NULL); + taskwdInsert(taskIdSelf(),NULL,NULL); /* * Open the socket. @@ -143,6 +141,20 @@ int rsrv_online_notify_task() # endif while(TRUE){ + int maxBlock; + + /* + * check max block and disable new channels + * if its to small + */ + maxBlock = memFindMax(); + if(maxBlocklock);\ } -#define UNLOCK_CLIENT(CLIENT)\ +#define SEND_UNLOCK(CLIENT)\ { \ FASTUNLOCK(&(CLIENT)->lock);\ }