40 #define epicsExportSharedSymbols 44 #include "db_access_routines.h" 45 #include "dbChannel.h" 48 #include "db_field_log.h" 54 #define RECORD_NAME(CHAN) (dbChannelRecord(CHAN)->name) 56 static EVENTFUNC read_reply;
58 #define logBadId(CLIENT, MP, PPL)\ 59 logBadIdWithFileAndLineno(CLIENT, MP, PPL, __FILE__, __LINE__) 102 static void *casCalloc(
size_t count,
size_t size)
104 if ( UINT_MAX / size >= count ) {
108 return calloc(count, size);
123 const unsigned id = mp->
m_cid;
139 static void vsend_err(
162 pciu = MPTOPCIU(curp);
189 (
void * ) &pReqOut );
191 errlogPrintf (
"caserver: Unable to deliver err msg \"%s\" to client because \"%s\"\n",
207 pReqOut->
m_count = htons ( 0u );
211 pLW[1] = htonl ( curp->
m_count );
212 pMsgString = (
char * ) ( pLW + 2 );
213 size =
sizeof (
caHdr ) + 2 *
sizeof ( *pLW );
222 pMsgString = (
char * ) ( pReqOut + 1 );
223 size =
sizeof (
caHdr );
229 localStatus =
epicsVsnprintf ( pMsgString, maxDiagLen - size, pformat, args );
230 if ( localStatus >= 1 ) {
231 unsigned diagLen = ( unsigned ) localStatus;
232 if ( diagLen < maxDiagLen - size ) {
237 "caserver: vsend_err: epicsVsnprintf detected " 238 "error message truncation, pFormat = \"%s\"\n",
241 pMsgString [ maxDiagLen - 1 ] =
'\0';
254 static void send_err (
257 struct client *client,
262 va_start ( args, pformat );
263 vsend_err ( curp,
status, client, pformat, args );
272 static void log_header (
273 const char *pContext,
274 struct client *client,
276 const void *pPayLoad,
292 epicsPrintf (
"CAS: Request from %s => cmmd=%d cid=0x%x type=%d count=%d postsize=%u\n",
295 epicsPrintf (
"CAS: Request from %s => available=0x%x \tN=%u paddr=%p\n",
299 epicsPrintf (
"CAS: Request from %s => Wrote string \"%s\"\n",
300 hostName, (
char *)pPayLoad );
307 static void logBadIdWithFileAndLineno(
308 struct client *client,
310 const void *pPayload,
315 log_header (
"bad resource ID", client, mp, pPayload, 0 );
317 send_err ( mp,
ECA_INTERNAL, client,
"Bad Resource ID at %s.%d",
326 void *pPayload,
struct client *pClient )
329 log_header (
"invalid (damaged?) request code from UDP",
330 pClient, mp, pPayload, 0);
338 struct client *client )
340 const char *pCtx =
"invalid (damaged?) request code from TCP";
341 log_header ( pCtx, client, mp, pPayload, 0 );
358 struct client *client )
361 unsigned epicsPriorityNew;
362 unsigned epicsPrioritySelf;
367 DLOG ( 2, (
"CAS: Ignore version from unsupported client %u\n", mp->
m_count ) );
379 epicsPriorityNew = (unsigned) tmp;
381 if ( epicsPriorityNew != epicsPrioritySelf ) {
383 unsigned priorityOfEvents;
386 priorityOfEvents = epicsPriorityNew;
389 if ( epicsPriorityNew > epicsPrioritySelf ) {
391 db_event_change_priority ( client->
evuser, priorityOfEvents );
394 db_event_change_priority ( client->
evuser, priorityOfEvents );
406 void *pPayload,
struct client *pClient )
413 (
void * ) &pPayloadOut );
415 memcpy ( pPayloadOut, pPayload, mp->
m_postsize );
426 void *pPayload,
struct client *pClient )
428 db_event_flow_ctrl_mode_off ( pClient->
evuser );
436 void *pPayload,
struct client *pClient )
438 db_event_flow_ctrl_mode_on ( pClient->
evuser );
450 static void no_read_access_event (
struct client *pClient,
472 memset ( pPayloadOut, 0, pevext->
size );
476 send_err ( &pevext->
msg, status, pClient,
477 "server unable to load read access denied response into protocol buffer PV=\"%s\" dbf=%u count=%u avail=%u max bytes=%u",
485 static void read_reply (
void *pArg,
struct dbChannel *
dbch,
486 int eventsRemaining, db_field_log *pfl )
491 struct client *pClient = pevext->
pciu->
client;
499 dbAddr *paddr=&
dbch->addr;
510 autosize ? paddr->no_elements : pevext->
msg.
m_count;
513 pClient, pevext->
msg.
m_cmmd, payload_size,
517 send_err ( &pevext->
msg, status, pClient,
518 "server unable to load read (or subscription update) response " 519 "into protocol buffer PV=\"%s\" dbf=%u count=%ld avail=%u max bytes=%u",
521 if ( ! eventsRemaining )
530 if ( ! readAccess ) {
531 no_read_access_event ( pClient, pevext );
532 if ( ! eventsRemaining )
540 pfl = db_create_read_log(
dbch);
543 pfl = dbChannelRunPreChain(
dbch, pfl);
544 pfl = dbChannelRunPostChain(
dbch, pfl);
549 pPayload, &item_count, pfl);
551 if (local_fl) db_delete_field_log(pfl);
567 memset ( pPayload, 0, payload_size );
579 payload_size = data_size;
582 else if (payload_size > data_size)
584 (
char *) pPayload + data_size, 0, payload_size - data_size);
591 memset ( pPayload, 0, payload_size );
601 if ( ! eventsRemaining )
612 static int read_action (
caHdrLargeArray *mp,
void *pPayloadIn,
struct client *pClient )
620 db_field_log *pfl =
NULL;
640 send_err ( mp, status, pClient,
641 "server unable to load read response into protocol buffer PV=\"%s\" dbf=%u count=%u avail=%u max bytes=%u",
650 if ( ! readAccess ) {
652 send_err ( mp, status,
660 pfl = db_create_read_log(pciu->
dbch);
663 pfl = dbChannelRunPreChain(pciu->
dbch, pfl);
664 pfl = dbChannelRunPostChain(pciu->
dbch, pfl);
671 if (local_fl) db_delete_field_log(pfl);
693 char * pStr = (
char *) pPayload;
695 if ( strcnt < payloadSize ) {
699 pStr[payloadSize-1] =
'\0';
701 "caserver: read_action: detected DBR_STRING w/o nill termination " 702 "in response from db_get_field, pPayload = \"%s\"\n",
716 static int read_notify_action (
caHdrLargeArray *mp,
void *pPayload,
struct client *client )
725 pciu = MPTOPCIU ( mp );
754 void *pPayload,
struct client *client )
783 log_header (
"invalid data type", client, mp, pPayload, 0);
799 dbStatus = dbChannel_put(
824 struct client *client )
837 if ( chanCount != 0 ) {
843 "attempts to use protocol to set host name " 844 "after creating first channel ignored by server" );
849 pName = (
char *) pPayload;
852 log_header (
"bad (very long) host name",
853 client, mp, pPayload, 0 );
859 "bad (very long) host name");
867 DLOG (2, (
"CAS: host_name_action for \"%s\" ignores client provided host name\n",
875 pMalloc = malloc(size);
877 log_header (
"no space in pool for new host name",
878 client, mp, pPayload, 0 );
884 "no space in pool for new host name");
892 pMalloc[size-1]=
'\0';
900 DLOG (2, (
"CAS: host_name_action for \"%s\"\n",
911 struct client *client )
924 if ( chanCount != 0 ) {
930 "attempts to use protocol to set user name " 931 "after creating first channel ignored by server" );
936 pName = (
char *) pPayload;
939 log_header (
"a very long user name was specified",
940 client, mp, pPayload, 0);
946 "a very long user name was specified");
954 pMalloc = malloc(size);
956 log_header (
"no memory for new user name",
957 client, mp, pPayload, 0);
963 "no memory for new user name");
971 pMalloc[size-1]=
'\0';
986 struct client *client,
987 struct dbChannel *
dbch,
991 static unsigned bucketID;
1009 pCID = (
unsigned *) &pchannel->
cid;
1027 pCID = (
unsigned *) &pchannel->
sid;
1067 struct client * pclient;
1077 if(pclient->
proto==IPPROTO_UDP){
1086 unsigned sigReq = 0;
1111 if ( pevext->
pdbev ) {
1113 db_event_enable ( pevext->
pdbev );
1114 db_post_single_event ( pevext->
pdbev );
1117 db_post_single_event ( pevext->
pdbev );
1118 db_event_disable ( pevext->
pdbev );
1125 db_post_extra_labor( pclient->
evuser );
1156 0, 0, pciu->
cid, ar, 0 );
1175 access_rights_reply ( pciu );
1178 dbElem = dbChannelFinalElements(pciu->
dbch);
1184 if ( dbElem >= 0xffff ) {
1197 dbChannelFinalCAType(pciu->
dbch), nElem, pciu->
cid,
1209 void *pPayload, client *client )
1213 struct dbChannel *dbch;
1214 char *pName = (
char *) pPayload;
1231 log_header (
"empty PV name in UDP search request?",
1232 client, mp, pPayload, 0 );
1237 dbch = dbChannel_create (pName);
1248 DLOG ( 2, (
"CAS: claim_ciu_action found '%s', type %d, count %d\n",
1249 pName, dbChannelCAType(dbch), dbChannelElements(dbch)) );
1251 pciu = casCreateChannel (
1256 log_header (
"no memory to create new channel",
1257 client, mp, pPayload, 0);
1264 dbChannelDelete(dbch);
1278 log_header (
"No room for security table",
1279 client, mp, pPayload, 0);
1281 send_err(mp,
ECA_ALLOCMEM, client,
"No room for security table");
1305 claim_ciu_reply ( pciu );
1307 else if (status!=0) {
1308 log_header (
"No room for access security state change subscription",
1309 client, mp, pPayload, 0);
1312 "No room for access security state change subscription");
1329 if(ppn->status==notifyCanceled)
return 0;
1337 return db_put_process(ppn,type,
1338 pNotify->dbrType,pNotify->pbuffer,pNotify->nRequest);
1349 struct client * pClient;
1378 db_post_extra_labor(pClient->
evuser);
1385 static void write_notify_reply (
struct client * pClient )
1389 void * asWritePvtTmp;
1442 errlogPrintf(
"CA server corrupted - put call back(s) discarded\n");
1461 static void sendAllUpdateAS (
struct client *client )
1471 claim_ciu_reply ( pciu );
1474 access_rights_reply ( pciu );
1481 "%s at %d: corrupt channel state detected durring AR update\n",
1482 __FILE__, __LINE__);
1499 struct client * pClient = pArg;
1500 write_notify_reply ( pClient );
1501 sendAllUpdateAS ( pClient );
1508 static void putNotifyErrorReply (
struct client *client,
caHdrLargeArray *mp,
int statusCA )
1522 errlogPrintf (
"%s at %d: should always get sufficent space for put notify error reply\n",
1523 __FILE__, __LINE__);
1557 pNotify->
dbPutNotify.requestType = putProcessRequest;
1566 static int rsrvExpandPutNotify (
1571 if ( sizeNeeded > pNotify->
valueSize ) {
1581 pNotify->
pbuffer = casCalloc(1,sizeNeeded);
1584 booleanStatus =
TRUE;
1594 booleanStatus =
FALSE;
1598 booleanStatus =
TRUE;
1601 return booleanStatus;
1606 unsigned size =
sizeof ( *pNotify );
1621 void * asWritePvtTmp = 0;
1624 busyTmp = pNotify->
busy;
1640 busyTmp = pNotify->
busy;
1661 struct client *client )
1667 pciu = MPTOPCIU(mp);
1674 log_header (
"bad put notify data type", client, mp, pPayload, 0);
1697 void * asWritePvtTmp = 0;
1724 log_header(
"put call back time out", client,
1735 pciu->
pPutNotify = rsrvAllocPutNotify ( pciu );
1741 log_header (
"no memory to initiate put notify",
1742 client, mp, pPayload, 0 );
1748 if ( ! rsrvExpandPutNotify ( pciu->
pPutNotify, size ) ) {
1749 log_header (
"no memory to initiate vector put notify",
1750 client, mp, pPayload, 0 );
1764 log_header (
"invalid data type", client, mp, pPayload, 0);
1765 putNotifyErrorReply ( client, mp, status );
1788 static int event_add_action (
caHdrLargeArray *mp,
void *pPayload,
struct client *client)
1791 int spaceAvailOnFreeList;
1799 pciu = MPTOPCIU ( mp );
1817 log_header (
"no memory to add subscription",
1818 client, mp, pPayload, 0);
1839 read_reply, pevext, pevext->
mask);
1841 log_header (
"no memory to add subscription to db",
1842 client, mp, pPayload, 0);
1845 "subscription install into record %s failed",
1877 DLOG ( 3, (
"event_add_action: db_post_single_event (0x%X)\n",
1879 db_post_single_event(pevext->
pdbev);
1885 db_event_enable(pevext->
pdbev);
1888 DLOG ( 3, (
"Disable event because cannot read\n" ) );
1898 void *pPayload,
struct client *client )
1909 pciu = MPTOPCIU(mp);
1926 if (pevext->
pdbev) {
1927 db_cancel_event (pevext->
pdbev);
1932 db_flush_extra_labor_event ( client->
evuser );
1976 "channel was in strange state or corrupted during cleanup");
1986 errMessage (status,
"Bad resource id during channel clear");
1993 dbChannelDelete(pciu->
dbch);
2007 static int event_cancel_reply (
caHdrLargeArray *mp,
void *pPayload,
struct client *client )
2018 pciu = MPTOPCIU(mp);
2052 if (pevext->
pdbev) {
2053 db_cancel_event (pevext->
pdbev);
2079 static int read_sync_reply (
caHdrLargeArray *mp,
void *pPayload,
struct client *client )
2101 static void search_fail_reply (
caHdrLargeArray *mp,
void *pPayload,
struct client *client)
2109 errlogPrintf (
"%s at %d: should always get sufficent space for search fail reply?\n",
2110 __FILE__, __LINE__ );
2120 static int udp_version_action (
caHdrLargeArray *mp,
void *pPayload,
struct client *client )
2125 DLOG ( 2, (
"CAS: Ignore version from unsupported client %u\n", mp->
m_count ) );
2165 static int search_reply_udp (
caHdrLargeArray *mp,
void *pPayload,
struct client *client )
2168 char *pName = (
char *) pPayload;
2173 int spaceAvailOnFreeList;
2175 size_t reasonableMonitorSpace = 10;
2178 DLOG ( 2, (
"CAS: Ignore search from unsupported client %u\n", mp->
m_count ) );
2186 log_header (
"empty PV name in UDP search request?",
2187 client, mp, pPayload, 0);
2193 if (dbChannelTest(pName)) {
2194 DLOG ( 2, (
"CAS: Lookup for channel \"%s\" failed\n", pPayLoad ) );
2204 reasonableMonitorSpace *
sizeof (
struct event_ext);
2231 sizeof(*pMinorVersion), type, count,
2233 (
void * ) &pMinorVersion );
2255 static int search_reply_tcp (
2258 char *pName = (
char *) pPayload;
2260 int spaceAvailOnFreeList;
2262 size_t reasonableMonitorSpace = 10;
2265 DLOG ( 2, (
"CAS: Ignore search from unsupported client %u\n", mp->
m_count ) );
2273 log_header (
"empty PV name in UDP search request?",
2274 client, mp, pPayload, 0);
2280 if (dbChannelTest(pName)) {
2281 DLOG ( 2, (
"CAS: Lookup for channel \"%s\" failed\n", pPayLoad ) );
2283 search_fail_reply ( mp, pPayload, client );
2293 reasonableMonitorSpace *
sizeof (
struct event_ext);
2296 send_err ( mp,
ECA_ALLOCMEM, client,
"Server memory exhausted" );
2334 clear_channel_reply,
2341 write_notify_action,
2395 unsigned bytes_left;
2413 DLOG ( 2, (
"CAS: Parsing %d(decimal) bytes\n",
recv->
cnt ) );
2423 if ( bytes_left <
sizeof(*mp) ) {
2438 if ( bytes_left <
sizeof(*mp) + 2 *
sizeof(*pLW) ) {
2443 msg.
m_count = ntohl ( pLW[1] );
2444 msgsize = msg.
m_postsize +
sizeof(*mp) + 2 *
sizeof ( *pLW );
2445 pBody = (
void * ) ( pLW + 2 );
2449 pBody = (
void * ) ( mp + 1 );
2454 if (client->
proto==IPPROTO_TCP) {
2462 log_header (
"CAS: Client version too old",
2463 client, &msg, 0, nmsg );
2478 if ( msgsize & 0x7 ) {
2479 if (client->
proto==IPPROTO_TCP) {
2482 "CAS: Missaligned protocol rejected" );
2484 log_header (
"CAS: Missaligned protocol rejected",
2485 client, &msg, 0, nmsg );
2500 if (client->
proto==IPPROTO_TCP) {
2503 "CAS: Server unable to load large request message. Max bytes=%lu",
2506 log_header (
"CAS: server unable to load large request message",
2507 client, &msg, 0, nmsg );
2510 assert ( msgsize >= bytes_left );
2521 if ( msgsize > bytes_left ) {
2529 log_header (
NULL, client, &msg, pBody, nmsg);
2531 if ( client->
proto==IPPROTO_UDP ) {
2533 status = ( *udpJumpTable[msg.
m_cmmd] )( &msg, pBody, client );
2540 status = bad_udp_cmd_action ( &msg, pBody, client );
2546 status = ( *tcpJumpTable[msg.
m_cmmd] ) ( &msg, pBody, client );
2553 return bad_tcp_cmd_action ( &msg, pBody, client );
epicsTimeStamp time_at_creation
LIBCOM_API void *epicsStdCall freeListCalloc(void *pvt)
void rsrvFreePutNotify(client *pClient, struct rsrv_put_notify *pNotify)
struct message_buffer recv
int rsrv_version_reply(struct client *client)
int(* pProtoStubUDP)(caHdrLargeArray *mp, void *pPayload, struct client *client)
#define assert(exp)
Declare that a condition should be true.
#define CA_PROTO_CREATE_CHAN
LIBCOM_API int asCheckClientIP
#define ellCount(PLIST)
Report the number of nodes in a list.
#define CA_PROTO_EVENT_ADD
processNotify dbPutNotify
struct rsrv_put_notify RSRVPUTNOTIFY
#define asCheckPut(asClientPvt)
#define asCheckGet(asClientPvt)
int rsrvCheckPut(const struct channel_in_use *pciu)
LIBCOM_API void *epicsStdCall bucketLookupItemUnsignedId(BUCKET *prb, const unsigned *pId)
Find an item identified by an unsigned int in the table.
LIBCOM_API int epicsStdCall LIBCOM_API int epicsStdCall epicsVsnprintf(char *str, size_t size, const char *format, va_list ap)
#define logBadId(CLIENT, MP, PPL)
struct rsrv_put_notify * pPutNotify
#define CA_PROTO_WRITE_NOTIFY
int caNetConvert(unsigned type, const void *pSrc, void *pDest, int hton, arrayElementCount count)
int errlogVprintf(const char *pFormat, va_list pvar)
#define CA_PROTO_EVENT_CANCEL
LOCAL int write_notify_put_callback(processNotify *ppn, notifyPutType type)
LIBCOM_API long epicsStdCall asAddClient(ASCLIENTPVT *asClientPvt, ASMEMBERPVT asMemberPvt, int asl, const char *user, char *host)
void casExpandRecvBuffer(struct client *pClient, ca_uint32_t size)
LIBCOM_API long epicsStdCall asRegisterClientCallback(ASCLIENTPVT asClientPvt, ASCLIENTCALLBACK pcallback)
pvd::StructureConstPtr type
ELLNODE * ellGet(ELLLIST *pList)
Deletes and returns the first node from a list.
#define asTrapWriteWithData(asClientPvt, user, host, addr, type, count, data)
#define INVALID_DB_REQ(x)
LIBCOM_API void epicsStdCall asPutClientPvt(ASCLIENTPVT asClientPvt, void *userPvt)
#define errMessage(S, PM)
LIBCOM_API epicsEventStatus epicsEventWaitWithTimeout(epicsEventId id, double timeOut)
Wait an the event or until the specified timeout period is over.
Functions to check the state of the system memory pool.
LIBCOM_API void epicsStdCall freeListInitPvt(void **ppvt, int size, int nmalloc)
LIBCOM_API int epicsStdCall osiSufficentSpaceInPool(size_t contiguousBlockSize)
Checks if a memory block of a specific size can be safely allocated.
#define asTrapWriteAfter(pvt)
void initializePutNotifyFreeList(void)
#define CA_PROTO_EVENTS_OFF
LIBCOM_API int epicsStdCall bucketAddItemUnsignedId(BUCKET *prb, const unsigned *pId, const void *pApp)
Add an item identified by an unsigned int to the table.
unsigned short ca_uint16_t
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
#define CA_PROTO_READ_SYNC
#define CA_MINOR_PROTOCOL_REVISION
#define CA_PROTO_ACCESS_RIGHT_READ
void ellAdd(ELLLIST *pList, ELLNODE *pNode)
Adds a node to the end of a list.
#define ellNext(PNODE)
Find the next node in list.
#define SEND_UNLOCK(CLIENT)
epicsMutexId chanListLock
#define epicsEventSignal(ID)
A synonym for epicsEventTrigger().
#define CA_PROTO_SNAPSHOT
LOCAL void write_notify_done_callback(processNotify *ppn)
APIs for the epicsMutex mutual exclusion semaphore.
unsigned recvBytesToDrain
#define RECORD_NAME(CHAN)
LIBCOM_API void epicsStdCall freeListFree(void *pvt, void *pmem)
int epicsStdCall epicsTimeGetCurrent(epicsTimeStamp *pDest)
Get current time into *pDest.
#define CA_PROTO_PRIORITY_MIN
LIBCOM_API size_t epicsStdCall freeListItemsAvail(void *pvt)
LIBCOM_API int epicsStdCall bucketRemoveItemUnsignedId(BUCKET *prb, const unsigned *pId)
Remove an item identified by a string from the table.
int camessage(struct client *client)
epicsFloat64 dbr_double_t
LIBCOM_API long epicsStdCall asRemoveClient(ASCLIENTPVT *asClientPvt)
LIBCOM_API void *epicsStdCall asGetClientPvt(ASCLIENTPVT asClientPvt)
GLBLTYPE BUCKET * pCaBucket
epicsOldString dbr_string_t
#define CA_PROTO_NOT_FOUND
int errlogPrintf(const char *pFormat,...)
#define CA_PROTO_CLEAR_CHANNEL
int cas_copy_in_header(struct client *pclient, ca_uint16_t response, ca_uint32_t payloadSize, ca_uint16_t dataType, ca_uint32_t nElem, ca_uint32_t cid, ca_uint32_t responseSpecific, void **ppPayload)
APIs for the epicsEvent binary semaphore.
GLBLTYPE void * rsrvChanFreeList
GLBLTYPE unsigned rsrvSizeofLargeBufTCP
union rsrv_put_notify::@1 dbrScalarValue
GLBLTYPE void * rsrvEventFreeList
#define epicsThreadPriorityCAServerHigh
LIBCOM_API epicsThreadBooleanStatus epicsStdCall epicsThreadHighestPriorityLevelBelow(unsigned int priority, unsigned *pPriorityJustBelow)
#define CA_PROTO_CREATE_CH_FAIL
LIBCOM_API unsigned int epicsStdCall epicsThreadGetPrioritySelf(void)
#define epicsThreadPriorityCAServerLow
const char *epicsStdCall ca_message(long ca_status)
#define CA_PROTO_READ_NOTIFY
size_t epicsStrnLen(const char *s, size_t maxlen)
#define CA_PROTO_ACCESS_RIGHT_WRITE
#define LOCAL
Deprecated synonym for static.
ELLLIST chanPendingUpdateARList
void cas_set_header_cid(struct client *pClient, ca_uint32_t cid)
void cas_commit_msg(struct client *pClient, ca_uint32_t size)
#define DLOG(LEVEL, ARGSINPAREN)
void * asDbGetMemberPvt(struct dbChannel *chan)
#define CA_VSUPPORTED(MINOR)
#define dbr_size_n(TYPE, COUNT)
int(* pProtoStubTCP)(caHdrLargeArray *mp, void *pPayload, struct client *client)
int asDbGetAsl(struct dbChannel *chan)
#define ellInit(PLIST)
Initialize a list type.
#define epicsEventWaitOK
Old name provided for backwards compatibility.
GLBLTYPE unsigned short ca_server_port
#define S_bucket_idInUse
Identifier already in use.
struct channel_in_use * pciu
unsigned minor_version_number
#define CA_PROTO_ACCESS_RIGHTS
#define CA_PROTO_EVENTS_ON
EPICS time-stamps (epicsTimeStamp), epicsTime C++ class and C functions for handling wall-clock times...
epicsMutexId putNotifyLock
C++ and C descriptions for a thread.
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
void ellDelete(ELLLIST *pList, ELLNODE *pNode)
Deletes a node from a list.
void rsrv_extra_labor(void *pArg)
struct event_block * pdbev
ELLNODE node
Pointers to the first and last nodes on list.
#define S_bucket_success
Success, must be 0.
GLBLTYPE unsigned rsrvChannelCount
void cas_send_bs_msg(struct client *pclient, int lock_needed)
#define S_asLib_asNotActive
void cas_set_header_count(struct client *pClient, ca_uint32_t count)
unsigned rsrvSizeOfPutNotify(struct rsrv_put_notify *pNotify)
LIBCOM_API void epicsStdCall epicsThreadSetPriority(epicsThreadId id, unsigned int priority)
GLBLTYPE void * rsrvPutNotifyFreeList
#define SEND_LOCK(CLIENT)
#define CA_PROTO_PRIORITY_MAX
unsigned epicsStdCall ipAddrToDottedIP(const struct sockaddr_in *paddr, char *pBuf, unsigned bufSize)
#define ellFirst(PLIST)
Find the first node in list.
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)