diff --git a/src/rsrv/camessage.c b/src/rsrv/camessage.c index 457cc8ed5..5028a6b16 100644 --- a/src/rsrv/camessage.c +++ b/src/rsrv/camessage.c @@ -65,12 +65,13 @@ static char *sccsId = "%W% %G%"; #include #include -#include -#include -#include -#include +#include "db_access.h" +#include "task_params.h" +#include "ellLib.h" +#include "freeList.h" +#include "caerr.h" -#include +#include "server.h" static caHdr nill_msg; @@ -187,12 +188,13 @@ struct dbAddr *pAddr, unsigned cid ); +LOCAL void *casCalloc (size_t count, size_t size); + +LOCAL void *casMalloc (size_t size); /* * CAMESSAGE() - * - * */ int camessage( struct client *client, @@ -360,7 +362,7 @@ struct message_buffer *recv } #ifdef CONVERSION_REQUIRED - if (mp->m_type > DBR_CTRL_DOUBLE) { + if (mp->m_type >= NELEMENTS(cac_dbr_cvrt)) { SEND_LOCK(client); send_err( mp, @@ -479,7 +481,7 @@ struct client *client /* * user name will not change if there isnt enough memory */ - pMalloc = casMalloc(size); + pMalloc = malloc(size); if(!pMalloc){ send_err( mp, @@ -542,7 +544,7 @@ struct client *client /* * user name will not change if there isnt enough memory */ - pMalloc = casMalloc(size); + pMalloc = malloc(size); if(!pMalloc){ send_err( mp, @@ -657,6 +659,23 @@ struct client *client exit(0); } + /* + * duplicate claim message are unacceptable + * (so we disconnect the client) + */ + if (pciu->client!=prsrv_cast_client) { + logMsg("CAS: double claim disconnect id=%d\n", + mp->m_cid, + NULL, + NULL, + NULL, + NULL, + NULL); + FASTUNLOCK(&prsrv_cast_client->addrqLock); + free_client(client); + exit(0); + } + /* * remove channel in use block from * the UDP client where it could time @@ -668,11 +687,6 @@ struct client *client &pciu->node); FASTUNLOCK(&prsrv_cast_client->addrqLock); - /* - * Any other client attachment is a severe error - */ - assert (pciu->client==prsrv_cast_client); - FASTLOCK(&prsrv_cast_client->addrqLock); pciu->client = client; ellAdd(&client->addrq, &pciu->node); @@ -914,7 +928,7 @@ struct client *client return; } - if (mp->m_type > DBR_CTRL_DOUBLE) { + if (mp->m_type > LAST_BUFFER_TYPE) { putNotifyErrorReply(client, mp, ECA_BADTYPE); return; } @@ -961,8 +975,8 @@ struct client *client * if there isnt enough memory left */ if(!pciu->pPutNotify){ - pciu->pPutNotify = - (RSRVPUTNOTIFY *) casCalloc(1, sizeof(*pciu->pPutNotify)+size); + pciu->pPutNotify = (RSRVPUTNOTIFY *) + casCalloc(1, sizeof(*pciu->pPutNotify)+size); if(!pciu->pPutNotify){ putNotifyErrorReply(client, mp, ECA_ALLOCMEM); return; @@ -1112,23 +1126,17 @@ struct client *client return; } + pevext = (struct event_ext *) freeListMalloc(rsrvEventFreeList); size = db_sizeof_event_block() + sizeof(*pevext); - FASTLOCK(&rsrv_free_eventq_lck); - pevext = (struct event_ext *) - ellGet(&rsrv_free_eventq); - FASTUNLOCK(&rsrv_free_eventq_lck); if (!pevext) { - pevext = (struct event_ext *) casMalloc(size); - if (!pevext) { - SEND_LOCK(client); - send_err( - mp, - ECA_ALLOCMEM, - client, - RECORD_NAME(&pciu->addr)); - SEND_UNLOCK(client); - return; - } + SEND_LOCK(client); + send_err( + mp, + ECA_ALLOCMEM, + client, + RECORD_NAME(&pciu->addr)); + SEND_UNLOCK(client); + return; } #ifdef CONVERSION_REQUIRED @@ -1268,9 +1276,7 @@ struct client *client status = db_cancel_event(pevext->pdbev); assert(status == OK); } - FASTLOCK(&rsrv_free_eventq_lck); - ellAdd(&rsrv_free_eventq, &pevext->node); - FASTUNLOCK(&rsrv_free_eventq_lck); + freeListFree(rsrvEventFreeList, pevext); } status = db_flush_extra_labor_event(client->evuser); @@ -1278,8 +1284,8 @@ struct client *client taskSuspend(0); } - if(pciu->pPutNotify){ - free(pciu->pPutNotify); + if (pciu->pPutNotify) { + free (pciu->pPutNotify); } /* @@ -1309,14 +1315,14 @@ struct client *client errMessage(status, RECORD_NAME(&pciu->addr)); } - FASTLOCK(&rsrv_free_addrq_lck); + FASTLOCK(&clientQlock); status = bucketRemoveItemUnsignedId (pCaBucket, &pciu->sid); if(status != S_bucket_success){ errMessage (status, "Bad resource id during channel clear"); logBadId(client, mp); } - ellAdd(&rsrv_free_addrq, &pciu->node); - FASTUNLOCK(&rsrv_free_addrq_lck); + FASTUNLOCK(&clientQlock); + freeListFree(rsrvChanFreeList, pciu); return; } @@ -1403,9 +1409,7 @@ struct client *client END_MSG(client); SEND_UNLOCK(client); - FASTLOCK(&rsrv_free_eventq_lck); - ellAdd(&rsrv_free_eventq, &pevext->node); - FASTUNLOCK(&rsrv_free_eventq_lck); + freeListFree (rsrvEventFreeList, pevext); } @@ -1547,7 +1551,7 @@ db_field_log *pfl * assert() is safe here because the type was * checked by db_get_field() */ - assert (pevext->msg.m_type <= DBR_CTRL_DOUBLE); + assert (mp->m_type < NELEMENTS(cac_dbr_cvrt)); /* use type as index into conversion jumptable */ (* cac_dbr_cvrt[pevext->msg.m_type]) @@ -1715,8 +1719,9 @@ struct client *client * stop further use of server if max block drops * below MAX_BLOCK_THRESHOLD */ - spaceAvailOnFreeList = ellCount(&rsrv_free_clientQ)>0 - && ellCount(&rsrv_free_addrq)>0; + spaceAvailOnFreeList = freeListItemsAvail(rsrvClientFreeList)>0 + && freeListItemsAvail(rsrvChanFreeList)>0 + && freeListItemsAvail(rsrvEventFreeList)>0; if (casBelowMaxBlockThresh && !spaceAvailOnFreeList) { SEND_LOCK(client); send_err(mp, @@ -1806,17 +1811,11 @@ unsigned cid int status; /* get block off free list if possible */ - FASTLOCK(&rsrv_free_addrq_lck); - pchannel = (struct channel_in_use *) ellGet(&rsrv_free_addrq); - FASTUNLOCK(&rsrv_free_addrq_lck); + pchannel = (struct channel_in_use *) + freeListCalloc(rsrvChanFreeList); if (!pchannel) { - pchannel = (struct channel_in_use *) - casMalloc(sizeof(*pchannel)); - if (!pchannel) { - return NULL; - } + return NULL; } - memset((char *)pchannel, 0, sizeof(*pchannel)); ellInit(&pchannel->eventq); pchannel->ticks_at_creation = tickGet(); pchannel->addr = *pAddr; @@ -1836,7 +1835,7 @@ unsigned cid * The lock is applied here because on some architectures the * ++ operator isnt atomic. */ - FASTLOCK(&rsrv_free_addrq_lck); + FASTLOCK(&clientQlock); do { /* @@ -1854,12 +1853,10 @@ unsigned cid pchannel); } while (status != S_bucket_success); - FASTUNLOCK(&rsrv_free_addrq_lck); + FASTUNLOCK(&clientQlock); if(status!=S_bucket_success){ - FASTLOCK(&rsrv_free_addrq_lck); - ellAdd(&rsrv_free_addrq, &pchannel->node); - FASTUNLOCK(&rsrv_free_addrq_lck); + freeListFree(rsrvChanFreeList, pchannel); errMessage (status, "Unable to allocate server id"); return NULL; } @@ -2120,9 +2117,9 @@ LOCAL struct channel_in_use *MPTOPCIU (caHdr *mp) struct channel_in_use *pciu; const unsigned id = mp->m_cid; - FASTLOCK(&rsrv_free_addrq_lck); + FASTLOCK(&clientQlock); pciu = bucketLookupItemUnsignedId (pCaBucket, &id); - FASTUNLOCK(&rsrv_free_addrq_lck); + FASTUNLOCK(&clientQlock); return pciu; } @@ -2235,25 +2232,25 @@ LOCAL void access_rights_reply(struct channel_in_use *pciu) * * (dont drop below some max block threshold) */ -void *casCalloc(size_t count, size_t size) +LOCAL void *casCalloc(size_t count, size_t size) { - if (casBelowMaxBlockThresh) { - return NULL; - } - return calloc(count, size); + if (casBelowMaxBlockThresh) { + return NULL; + } + return calloc(count, size); } - + /* * casMalloc() * * (dont drop below some max block threshold) */ -void *casMalloc(size_t size) +LOCAL void *casMalloc(size_t size) { - if (casBelowMaxBlockThresh) { - return NULL; - } - return malloc(size); + if (casBelowMaxBlockThresh) { + return NULL; + } + return malloc(size); } diff --git a/src/rsrv/camsgtask.c b/src/rsrv/camsgtask.c index e4da7567e..53cead80f 100644 --- a/src/rsrv/camsgtask.c +++ b/src/rsrv/camsgtask.c @@ -46,7 +46,6 @@ static char *sccsId = "@(#) $Id$"; #include -#include #include #include #include @@ -60,10 +59,11 @@ static char *sccsId = "@(#) $Id$"; #include #include -#include -#include -#include -#include +#include "ellLib.h" +#include "taskwd.h" +#include "task_params.h" +#include "db_access.h" +#include "server.h" /* diff --git a/src/rsrv/caserverio.c b/src/rsrv/caserverio.c index 6c4b49439..88ccec37c 100644 --- a/src/rsrv/caserverio.c +++ b/src/rsrv/caserverio.c @@ -41,7 +41,7 @@ static char *sccsId = "@(#) $Id$"; #include #include -#include +#include "ellLib.h" #include #include #include @@ -54,7 +54,7 @@ static char *sccsId = "@(#) $Id$"; #include #include -#include +#include "server.h" diff --git a/src/rsrv/caservertask.c b/src/rsrv/caservertask.c index cb7cd5d1b..55e55a3fa 100644 --- a/src/rsrv/caservertask.c +++ b/src/rsrv/caservertask.c @@ -61,12 +61,13 @@ static char *sccsId = "@(#) $Id$"; #include #include -#include -#include -#include -#include -#include -#include +#include "ellLib.h" +#include "taskwd.h" +#include "db_access.h" +#include "task_params.h" +#include "envDefs.h" +#include "freeList.h" +#include "server.h" LOCAL int terminate_one_client(struct client *client); LOCAL void log_one_client(struct client *client, unsigned level); @@ -223,9 +224,7 @@ int free_client(struct client *client) terminate_one_client(client); - LOCK_CLIENTQ; - ellAdd(&rsrv_free_clientQ, &client->node); - UNLOCK_CLIENTQ; + freeListFree(rsrvClientFreeList, client); return OK; } @@ -310,20 +309,18 @@ LOCAL int terminate_one_client(struct client *client) status = db_cancel_event(pevext->pdbev); assert(status == OK); } - FASTLOCK(&rsrv_free_eventq_lck); - ellAdd(&rsrv_free_eventq, &pevext->node); - FASTUNLOCK(&rsrv_free_eventq_lck); + freeListFree(rsrvEventFreeList, pevext); } status = db_flush_extra_labor_event(client->evuser); assert(status==OK); if(pciu->pPutNotify){ free(pciu->pPutNotify); } - FASTLOCK(&rsrv_free_addrq_lck); + FASTLOCK(&clientQlock); status = bucketRemoveItemUnsignedId ( pCaBucket, &pciu->sid); - FASTUNLOCK(&rsrv_free_addrq_lck); + FASTUNLOCK(&clientQlock); if(status != S_bucket_success){ errPrintf ( status, @@ -342,9 +339,7 @@ LOCAL int terminate_one_client(struct client *client) * place per channel block onto the * free list */ - FASTLOCK(&rsrv_free_addrq_lck); - ellAdd(&rsrv_free_addrq, &pciu->node); - FASTUNLOCK(&rsrv_free_addrq_lck); + freeListFree (rsrvChanFreeList, pciu); } if (client->evuser) { @@ -440,7 +435,7 @@ int client_stat(unsigned level) */ void casr (unsigned level) { - int bytes_reserved; + size_t bytes_reserved; struct client *client; printf( "Channel Access Server V%d.%d\n", @@ -464,26 +459,26 @@ void casr (unsigned level) log_one_client(prsrv_cast_client, level); } - if (level >=2u) { - bytes_reserved = 0; - bytes_reserved += sizeof(struct client)* - ellCount(&rsrv_free_clientQ); - bytes_reserved += sizeof(struct channel_in_use)* - ellCount(&rsrv_free_addrq); - bytes_reserved += (sizeof(struct event_ext)+db_sizeof_event_block())* - ellCount(&rsrv_free_eventq); - printf( "There are currently %d bytes on the server's free list\n", + if (level>=2u) { + bytes_reserved = 0u; + bytes_reserved += sizeof (struct client) * + freeListItemsAvail (rsrvClientFreeList); + bytes_reserved += sizeof (struct channel_in_use) * + freeListItemsAvail (rsrvChanFreeList); + bytes_reserved += (sizeof(struct event_ext)+db_sizeof_event_block()) * + freeListItemsAvail (rsrvEventFreeList); + printf( "There are currently %u bytes on the server's free list\n", bytes_reserved); - printf( "%d client(s), %d channel(s), and %d event(s) (monitors)\n", - ellCount(&rsrv_free_clientQ), - ellCount(&rsrv_free_addrq), - ellCount(&rsrv_free_eventq)); + printf( "%u client(s), %u channel(s), and %u event(s) (monitors)\n", + freeListItemsAvail (rsrvClientFreeList), + freeListItemsAvail (rsrvChanFreeList), + freeListItemsAvail (rsrvEventFreeList)); if(pCaBucket){ printf( "The server's resource id conversion table:\n"); - FASTLOCK(&rsrv_free_addrq_lck); + FASTLOCK(&clientQlock); bucketShow (pCaBucket); - FASTUNLOCK(&rsrv_free_addrq_lck); + FASTUNLOCK(&clientQlock); } caPrintAddrList (&beaconAddrList); diff --git a/src/rsrv/cast_server.c b/src/rsrv/cast_server.c index ca8163892..f1c05a314 100644 --- a/src/rsrv/cast_server.c +++ b/src/rsrv/cast_server.c @@ -61,7 +61,6 @@ static char *sccsId = "@(#) $Id$"; #include #include -#include #include #include #include @@ -76,11 +75,13 @@ static char *sccsId = "@(#) $Id$"; #include #include -#include -#include -#include -#include -#include +#include "ellLib.h" +#include "taskwd.h" +#include "db_access.h" +#include "task_params.h" +#include "envDefs.h" +#include "freeList.h" +#include "server.h" LOCAL void clean_addrq(); @@ -136,6 +137,32 @@ int cast_server(void) taskSuspend(taskIdSelf()); } + { + /* + * + * this allows for faster connects by queuing + * additional incomming UDP search frames + * + * this allocates a 32k buffer + * (uses a power of two) + */ + int size = 1u<<15u; + status = setsockopt( + IOC_cast_sock, + SOL_SOCKET, + SO_RCVBUF, + (char *)&size, + sizeof(size)); + if (status<0) { + logMsg("CAS: unable to set cast socket size\n", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL); + } + } /* Zero the sock_addr structure */ bfill((char *)&sin, sizeof(sin), 0); @@ -173,7 +200,7 @@ int cast_server(void) NULL, NULL, NULL); - if(status<0){ + if(status==ERROR){ logMsg("CAS: couldnt start up online notify task\n", NULL, NULL, @@ -349,15 +376,15 @@ LOCAL void clean_addrq() if (delay > timeout) { ellDelete(&prsrv_cast_client->addrq, &pciu->node); - FASTLOCK(&rsrv_free_addrq_lck); + FASTLOCK(&clientQlock); s = bucketRemoveItemUnsignedId ( pCaBucket, &pciu->sid); if(s){ errMessage (s, "Bad id at close"); } - ellAdd(&rsrv_free_addrq, &pciu->node); - FASTUNLOCK(&rsrv_free_addrq_lck); + FASTUNLOCK(&clientQlock); + freeListFree(rsrvChanFreeList, pciu); ndelete++; maxdelay = max(delay, maxdelay); } @@ -388,22 +415,16 @@ struct client *create_udp_client(unsigned sock) { struct client *client; - LOCK_CLIENTQ; - client = (struct client *)ellGet(&rsrv_free_clientQ); - UNLOCK_CLIENTQ; - + client = freeListMalloc(rsrvClientFreeList); if(!client){ - client = (struct client *)casMalloc(sizeof(struct client)); - if(!client){ - logMsg("CAS: no mem for new client\n", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); - return NULL; - } + logMsg("CAS: no spae in pool for a new client\n", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL); + return NULL; } if(CASDEBUG>2) @@ -424,17 +445,17 @@ struct client *create_udp_client(unsigned sock) client->blockSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); if(!client->blockSem){ - free(client); + freeListFree(rsrvClientFreeList, client); return NULL; } /* * user name initially unknown */ - client->pUserName = casMalloc(1); + client->pUserName = malloc(1); if(!client->pUserName){ semDelete(client->blockSem); - free(client); + freeListFree(rsrvClientFreeList, client); return NULL; } client->pUserName[0] = '\0'; @@ -442,11 +463,11 @@ struct client *create_udp_client(unsigned sock) /* * host name initially unknown */ - client->pHostName = casMalloc(1); + client->pHostName = malloc(1); if(!client->pHostName){ semDelete(client->blockSem); free(client->pUserName); - free(client); + freeListFree(rsrvClientFreeList, client); return NULL; } client->pHostName[0] = '\0'; diff --git a/src/rsrv/caswatchdog.c b/src/rsrv/caswatchdog.c index 30a0e726c..b34a25f38 100644 --- a/src/rsrv/caswatchdog.c +++ b/src/rsrv/caswatchdog.c @@ -40,7 +40,7 @@ static char *sccsId = "@(#)caswatchdog.c 1.3\t7/28/92"; #define CA_WD_DELAY 10 -#include +#include "ellLib.h" void ca_watchdog_check(); static diff --git a/src/rsrv/globalsource.c b/src/rsrv/globalsource.c index 1232961a6..4fdfcb1fa 100644 --- a/src/rsrv/globalsource.c +++ b/src/rsrv/globalsource.c @@ -33,9 +33,11 @@ static char *sccsId = "@(#) $Id$"; #include -#include #include #include #include -#include -#include + +#include "ellLib.h" +#include "db_access.h" +#include "server.h" + diff --git a/src/rsrv/online_notify.c b/src/rsrv/online_notify.c index 503d89b9d..f92bb8354 100644 --- a/src/rsrv/online_notify.c +++ b/src/rsrv/online_notify.c @@ -58,9 +58,9 @@ static char *sccsId = "@(#) $Id$"; /* * EPICS includes */ -#include +#include "envDefs.h" #include "server.h" -#include +#include "task_params.h" /* * RSRV_ONLINE_NOTIFY_TASK diff --git a/src/rsrv/rsrv_init.c b/src/rsrv/rsrv_init.c index ba7616a11..d62a674e6 100644 --- a/src/rsrv/rsrv_init.c +++ b/src/rsrv/rsrv_init.c @@ -33,7 +33,7 @@ static char *sccsId = "@(#) $Id$"; #include -#include +#include "ellLib.h" #include #include #include @@ -41,9 +41,10 @@ static char *sccsId = "@(#) $Id$"; #include #include -#include -#include -#include +#include "db_access.h" +#include "task_params.h" +#include "freeList.h" +#include "server.h" #define DELETE_TASK(TID)\ if(taskIdVerify(TID)==OK)taskDelete(TID); @@ -51,20 +52,16 @@ if(taskIdVerify(TID)==OK)taskDelete(TID); /* * rsrv_init() - * - * - * */ int rsrv_init() { - FASTLOCKINIT(&rsrv_free_addrq_lck); - FASTLOCKINIT(&rsrv_free_eventq_lck); FASTLOCKINIT(&clientQlock); ellInit(&clientQ); - ellInit(&rsrv_free_clientQ); - ellInit(&rsrv_free_addrq); - ellInit(&rsrv_free_eventq); + freeListInitPvt(&rsrvClientFreeList, sizeof(struct client), 8); + freeListInitPvt(&rsrvChanFreeList, sizeof(struct channel_in_use), 512); + freeListInitPvt(&rsrvEventFreeList, + sizeof(struct event_ext)+db_sizeof_event_block(), 512); ellInit(&beaconAddrList); prsrv_cast_client = NULL; pCaBucket = NULL; diff --git a/src/rsrv/server.h b/src/rsrv/server.h index 760618c28..aa33f7a33 100644 --- a/src/rsrv/server.h +++ b/src/rsrv/server.h @@ -53,27 +53,27 @@ static char *serverhSccsId = "@(#) $Id$"; #define APIENTRY -#include +#include "epicsAssert.h" #include -#include -#include +#include "ellLib.h" +#include "fast_lock.h" -#include -#include -#include -#include -#include -#include +#include "dbDefs.h" +#include "db_access.h" +#include "dbEvent.h" +#include "caProto.h" +#include "bucketLib.h" +#include "taskwd.h" -#include -#include +#include "asLib.h" +#include "asDbLib.h" #include -#include +#include "addrList.h" -#include +#include "net_convert.h" /* * !! buf must be the first item in this structure !! @@ -207,16 +207,14 @@ GLBLTYPE int CASDEBUG; GLBLTYPE int IOC_sock; GLBLTYPE int IOC_cast_sock; GLBLTYPE unsigned short ca_server_port; -GLBLTYPE ELLLIST clientQ; /* locked by clientQlock */ -GLBLTYPE ELLLIST rsrv_free_clientQ; /* locked by clientQlock */ -GLBLTYPE ELLLIST rsrv_free_addrq; -GLBLTYPE ELLLIST rsrv_free_eventq; +GLBLTYPE ELLLIST clientQ; /* locked by clientQlock */ GLBLTYPE ELLLIST beaconAddrList; GLBLTYPE FAST_LOCK clientQlock; -GLBLTYPE FAST_LOCK rsrv_free_addrq_lck; -GLBLTYPE FAST_LOCK rsrv_free_eventq_lck; GLBLTYPE struct client *prsrv_cast_client; GLBLTYPE BUCKET *pCaBucket; +GLBLTYPE void *rsrvClientFreeList; +GLBLTYPE void *rsrvChanFreeList; +GLBLTYPE void *rsrvEventFreeList; #define CAS_HASH_TABLE_SIZE 4096 @@ -281,9 +279,6 @@ struct client *pc void write_notify_reply(void *pArg); -void *casMalloc(size_t size); -void *casCalloc(size_t count, size_t size); - /* * !!KLUDGE!! *