LCLS Controls

SLC-Aware IOC Design

 

 

SLC –Aware IOC Utility Routines

 

Quick Links

Introduction

SLC-aware Thread Utility Routines

Low-level Utilities for Global Data

slcCmlog Utilities

General Thread Utilities

Message Queue Utilities

Byte Swap Utilities

Floating point Conversion Utilities

Array Conversion Utilities

Time Conversion Utilities

TCP Utilities

1         Scope

The following document describes the software design for the SLC-aware IOC General Thread Utilities.  The utility routines covered by this document are general routines that are useful to, and available to, all SLC-aware threads.  This document includes a description of each utility, the calling parameters, error message generated, and the include files required to use them in a thread.

2         Introduction

When developing a multi-threaded application that there are many instances when many threads will require the same functionality.  For instance, the SLC-aware IOC threads perform the same functions when accessing message queues, converting data, and accessing TCP sockets. The following utility routines were developed to provide error checking, to provide consistent error reporting, and to reduce the overall volume of code needed to perform redundant functions within the SLC-aware IOC threads.

2.1      Background

2.2      References

2.3      Requirements

See the SLC-Aware IOC Functional Requirements document by Stephanie Alison.

3         Slc-Aware Thread Utility Routines

Several utility routines are available to all threads of the SLC-aware IOC. Unless otherwise noted, the utility source files reside under $EPICS/site/src/slc/util and are included in the util library build of the SLC-aware IOC threads.  They are listed and described in the following sections. The descriptions include all expected return values and error codes returned and logged. 

 

These utilities use many EPICS OSI library functions.  Error codes logged by any underlying EPICS library calls are not documented here.  See the EPICS OSI Library documentation and sources.

3.1      Low-level Utilities for Global Data

Low-level utilities for global data are defined in slcGlob.c and .h.  The following routines in this file are used by other utility routines to access global data and structures.

3.1.1      Void slcInitGlobals

Void slcInitGlobals(void);

 

This routine initializes all the slcIOC global variables to a known value.  It is called once before any slcIOC threads are started.

3.1.2      void slcCpyIOCName

void slcCpyIOCName(void);

 

This routine copies the IOC_NAME environment variable into the slcIocName_a global variable.  It is meant to be called once by the slcInitGlobals utility when slcIOC global variables are initialized.

3.1.3      char* slcGetIOCName

char* slcGetIOCName(void);

 

This routine returns a char* pointer to the slcIocName_a global variable.

3.1.4      void slcCpyProxyIPAddress

void slcSetProxyIPString(void);

 

This routine copies the SLC_PROXY_IP environment variable into the slcProxyIpAddr_a global variable.  It is meant to be called once by the slcInitGlobals utility when slcIOC global variables are initialized.

3.1.5      char* slcGetProxyIPAddress

char* slcGetProxyIPString(void);

 

This routine returns a char* pointer to the slcProxyIPAddr_a global variable. It is used by the socket connection utilities.

3.1.6      void slcSetDbExists

void slcSetDbExists(const epicsBoolean val);

 

This routine sets the dbExists global boolean to the value ‘val’.

3.1.7      epicsBoolean slcGetDbExists

epicsBoolean slcGetDbExists (void);

 

This routine returns the current value of the dbExists global boolean. The dbExists flag is used by the db utilities to verify the database is valid before using it.

3.1.8      void slcSetAsyncExists

void slcSetAsyncExists(const epicsBoolean val);

 

This routine sets the asyncExists global boolean to the value ‘val’.

3.1.9      epicsBoolean slcGetAsyncExists

epicsBoolean slcGetAsyncExists (void);

 

This routine returns the current value of the asyncExists global boolean. The asyncExists flag is used by the async utilities to verify the async global data is valid before using it.

3.1.10 epicsThreadId slcThreadGetTid

epicsThreadId slcThreadGetTid(const slcThread_te thrd_e);

 

This routine first checks that thrd_e is a valid thread enumeration value.  It then returns the thread id ‘slcThreads_as[thrd_e].tid_ps’ associated with the corresponding thread.  If there is an error the value NULL is returned.

3.1.11 epicsMessageQueueId slcThreadGetMqId

epicsMessageQueueId slcThreadGetMqId(const slcThread_te thrd_e)

 

This routine first checks that thrd_e is a valid thread enumeration value.  It then returns the thread message queue id ‘slcThreads_as[thrd_e].mqId_ps’ associated with the corresponding thread.  If there is an error the value NULL is returned.

3.1.12 unsigned long slcThreadGetDestination

unsigned long slcThreadGetDestination(const slcThread_te thrd_e);

 

This routine first checks that thrd_e is a valid thread enumeration value.  It then returns the ‘slcThreads_as[thrd_e].destination’ associated with the corresponding thread.  If there is an error the value 0 is returned.

 

This routine is a low-level routine used by other utilities.  It should not be confused with the slcGetThreadDestinationByTid general utility (see General Thread Utilities ).

3.2      slcCmlog Utilities

The slcIOC uses the IOC Cmlog Service to store and retrieve message for logging.  The slcCmlog utilities provide an interface between the slcIOC threads and the IOC Cmlog Service.  See the IOC Cmlog Service Design document for a description.

 

The slcCmlog utilities are defined in slcCmlog.c and .h. The following routines in this file are used by the SLC-Aware IOC threads for logging all messages.

3.2.1      int slcCmlogLogMsg

slcCmlogLogMsg(const unsigned long codeI, const char * const code_c,  const char * const format_c, …)

This routine calls slcCmlogVLogMsg with a null file name and line number set to 0.

3.2.2      int slcCmlogLogMsgFile

slcCmlogLogMsgFile(const unsigned long codeI, const char * const code_c,  const char * const  filename_c,  const unsigned long lineno,  const char * const format_c, …)

This routine calls slcCmlogVLogMsg, passing it the input file name and line number. The caller may provide filename_c and lineno using the C __FILE__ and __LINE__ preprocessor macros.

3.2.3      int slcCmlogVLogMsg

slcCmlogVLogMsg(const unsigned long codeI, const char * const code_c,  const char * const  filename_c,  const unsigned long lineno,  const char * const format_c,  va_list             format_args_p)

This routine first calls slcGetThreadDestinationByTid to get the destination previously set by the caller for this thread (normally set by msgQMsgRcv).  If there is an error from slcGetThreadDestinationByTid, then destination is set to “V017”.  It then calls iocCmlogVLogMsg and returns its status.  The facility argument is set to "SLC".

3.3      General Thread Utilities

General thread utilities that do not fall under a specific function are defined in slcUtil.c and .h.  The following routines in this file are used by many SLC-Aware IOC threads.

3.3.1      slcThread_te slcGetThreadEnumByTid

slcThread_te slcGetThreadEnum(const epicsThreadId tid_ps);

 

This routine finds the slcThreads_as[].tid_ps that matches tid_ps.  It returns the thread enumeration of the matching thread structure. If the input argument is NULL the calling thread id is used by calling the EPICS utility epicsThreadGetIdSelf(). If no matching tid_ps is found the slcInvalid thread enumeration is returned

3.3.2      slcThread_te slcGetThreadEnumByName

slcThread_te slcGetThreadEnumByName(const char* name_c);

 

This routine returns the thread enumeration of an slcIOC thread, given its name.

If the input argument is NULL the calling thread name is used by calling the EPICS utility epicsThreadGetNameSelf(). If no matching thread is found the slcInvalid thread enumeration is returned

3.3.3      int slcGetJobEnumByName

int slcGetJobEnumByName(const char * const name_pa);

 

Finds the slcJobs_as[]jobName_a that matches name_pa.  Returns the job enumeration into slcJobs_as if found, returns invalidJob enumeration if no matching name is found.

3.3.4      Unsigned long slcGetThreadDestinationByTid

Unsigned long slcGetThreadDestination( const epicsThreadId tid_ps)

 

This routine finds the slcThreads_as[].tid_ps that matches tid_ps.  It returns the destination field of the matching thread structure. If the input argument is NULL the calling thread id is used by calling the EPICS utility epicsThreadGetIdSelf(). If no matching tid_ps is found the value 0 is returned

 

This ‘destination’ field represents a 4 character string that is the name of an SLC Control System process.  The string is stored as an unsigned long, rather than an array of chars, to make it easier for threads to set and get the value.  The threads themselves rarely need to interpret the string, they simply copy it into a reply message, and the slcCmlogLogMsg utility uses it for reporting. See slcCmlog Utilities.

3.4      Message Queue Utilities

Message Queue utilities are defined in msgQUtil.c and .h.  The following routines in this file are used by the threads to create and use message queues to communicate between threads.  The message queue utilities return the vmsstat_t SLC Control System type errors, and log them via the slcCmlogLogMsg utility.  Logged errors are listed for each function.

3.4.1      vmsstat_t  messageQCreate

vmsstat_t  messageQCreate(const slcThread_te thrd_e, const int maxMsgs, const int maxMsgBytes );

 

Creates a message queue for the calling thread.  It calls the epicsMessageQueueCreate to create the queue large enough to hold maxMsgs messages of the size maxMsgBytes.  The slcThreads_as[].mqId_ps is set with the returned epicsMessageQueueID. The MICR_OKOK code is returned upon success.

 

If the calling thread has no associated thread enumeration (it is not an slcIOC thread) the MICR_EEXIST error is logged and returned.

If an error occurs and no message queue is created (mqId_ps ==NULL) then the MICR_CREMBX error is logged and returned.

3.4.2      vmsstat_t  messageQSend

vmsstat_t  messageQSend(const slcThread_te thrd_e, const epicsBoolean wait_at_queue, const int msgBytes, const void* msg_p,);

 

Sends a message to the thread indicated by the thrd_e thread enumeration.  This routine first checks that the thread enumeration value indicates a valid slcIOC thread, and that the thread has a message queue.  If the wait_at_queue flag is true it then calls epicsMessageQueueSend to send the message. If the wait_at_queue flag is false, it calls epicsMessageQueueTrySend to get a

 

 

If the thread enumeration is not valid (it is not an slcIOC thread) the MSG_NOJOBTOKEN error is logged. 

If the thread does not have a message queue, the MSG_NOMBX error is logged and returned.

If an error occurs with the epicsMessageQueueSend function and no message is sent, then the MICR_SENDMBX error is logged and returned.

3.4.3      vmsstat_t  messageQRecv

vmsstat_t  messageQRecv(const slcThread_te thrd_e, const int msgBytes, epicsTimeStamp* currentTime_ps, void* msg_p);

 

Receive a message from the calling thread message queue.  This routine first checks that the calling thread is a valid slcIOC thread, and that it has a message queue. It then calls epicsMessageQueueReceive to receive the message.  If the currentTime_ps is not NULL, this routine will call epicsTimeGetCurrent and returns the current time in epics format.

 

If the calling thread thread enumeration is not valid (it is not an slcIOC thread) the MSG_NOJOBTOKEN error is logged and returned.

If the thread does not have a message queue, the MSG_NOMBX error is logged and returned.

If an error occurs with the epicsMessageQueueReceive function and no message is received, then the MICR_READ_MBX error is logged and returned.

 

This routine waits forever for a message with no timeout.

3.4.4      void messageQDestroy

void messageQDestroy(const slcThread_te thrd_e)

 

Destroy the calling thread’s message queue and set the slcThreads_as[].mqId_ps global to NULL.  This routine first checks that the calling thread is a valid slcIOC thread, and that it has a message queue.  Then the slcThreads_as[].mqId_ps is copied to a local variable, set to NULL, and finally the local variable is used to call epicsMessageQueueDestroy.

3.4.5      void messageQRelease

void       messageQRelease(const slcThread_te thrd_e )

 

This routine goes through the message queue, reading out each message using the messageQRecv utility.  It releases each message buffer pointed to using the msgQReleaseBuffer utility.  Finally, when the queue is empty it will destroy the queue.

 

This routine should be used by all “job” threads that receive Message Service messages. It is used to release all Message Service memory pool buffers held by the thread within its message queue, before destroying the message queue.  This function is called in the thread “cleanup” routine, instead of the messageQDestroy utility.

3.4.6      vmsstat_t msgQMsgRecv

vmsstat_t  msgQMsgRecv(const slcThread_te thrd_e, epicsTimeStamp* currentTime_ps, void* rMsg_pp);

 

A higher level function for all threads involved with Message Service messages.  This routine gets the incoming message, and finds the destination of the reply message.  It calls the messageQRecv utility on the thrd_e thread’s message queue, and copies the incoming message source SLC job ID into the slcThreads_as[thrd_e].destination field to store the destination of the reply to this incoming message. If the currentTime_ps is not NULL, this routine will call epicsTimeGetCurrent and returns the current time in epics format.  This time may be useful for diagnostics calculations.

 

This routine passes back a pointer to the message buffer. That message buffer may be a small or large buffer, hence the void * pointer type.  The calling function must cast the pointer to the structure type expected.  The actual data length is figured from the msgheader.datalen field.

 

Generally this routine is called by a ‘job’ thread that processes the message.  That ‘job’ thread is responsible for releasing the message buffer back to the pool when done processing.  The ‘job’ thread should use the msgQFreeBuffer routine to accomplish this.

 

This routine returns the status code generated and logged by the messageQRecv utility. 

3.4.7      vmsstat_t msgQMsgReply

vmsstat_t  msgQSmallMsgReply(const slcThread_te thrd_e, const void* msg_p);

 

This routine sends a message buffer to the thread denoted by thrd_e.  After sending the message to the queue, it will reset the calling thread’s destination field to the default value V017.

 

This routine returns the status code generated and logged by the messageQSend utility. 

3.4.8      vmsstat_t msgQGetBuffer

vmsstat_t  msgQGetSmallBuffer(const unsigned long bytes, void **const msg_pp);

 

This routine gets a buffer from a Message Service message pool based on the number of bytes required.  It uses the feeListCalloc routine from the EPICS freeList OSI library.

 

This routine returns the MICR_MALLOC status code if no memory is available.

3.4.9      void msgQFreeBuffer

void       msgQFreeSmallBuffer(unsigned long bytes, const void* msg_ps)

 

Free a Message Service message buffer back to its pool using the freeListFree routine of the EPICS freeList OSI library. The routine chooses the correct buffer pool to return the buffer to based on the bytes parameter.

3.5      Byte Swap Utilities

Byte swapping utilities are defined in cvtUtil.c and .h. The following routines in this file are used by SLC-Aware IOC threads for byte swapping short and long words to/from little-endian format.

 

The SLC Control System runs on a VMS system that has little-endian byte order.  If the slcIOC runs on a big-endian system then all message from and to the control system must first have the byte order swapped. In these routines the global slcIocIsLittleEndian is checked to be sure that swapping is required. If slcIocIsLittleEndian is TRUE, then no swapping takes place – as the slcIOC host and the control system host have the same byte order.

3.5.1      ENDIAN_TEST_IS_LITTLE

The slcIocIsLittleEndian global is set according to the ENDIAN_TEST_IS_LITTLE macro, which is defined in the cvtMacr.h file.  This macro ( courtesy of Till Straumann, $EPICS_SITE/src/utils/basicIoOps.h) initializes a two-byte constant to 1, then tests the first byte (accessed as a char) to see its value.  If it is 1 then the processor is little-endian, else it is big-endian.

 

This macro is called once during initialization to set the slcIocIsLittleEndian variable.

3.5.2      void cvtSSwap

void cvtSSwap(const unsigned short* s_p);

 

If, according to slcIocIsLittleEndian, byte-swapping is required, then swap the bytes of an unsigned short, in place.

3.5.3      void cvtLSwap

void cvtLSwap(const unsigned long* l_p);

 

If, according to slcIocIsLittleEndian, byte-swapping is required, then swap the bytes of an unsigned long, in place.

3.5.4      void cvtSSwapMove

void cvtSSwapMove(const void* u2In_p, void* u2Out_p);

 

If, according to slcIocIsLittleEndian, byte-swapping is required, then swap the bytes of an unsigned short, placing the results in a new location.  The original variable is not changed.

 

This routine is useful for copying and swapping data simultaneously, from a message to a reply for instance.

3.5.5      void cvtLSwapMove

void cvtLSwapMove(const void* u4In_p, void* u4Out_p);

 

If, according to slcIocIsLittleEndian, byte-swapping is required, then swap the bytes of an unsigned long, placing the results in a new location.  The original variable is not changed.

 

This routine is useful for copying and swapping data simultaneously, from a message to a reply for instance.

3.6      Floating point Conversion Utilities

Floating Point utilities are also defined in cvtUtil.c and .h.  Threads that share floating point data with the SLC Control system can use these utilities to convert between the VMS floating point format and IEEE floating point format.  It is assumed that all SLC-aware IOC architectures support IEEE floating point format.

3.6.1      void cvtFloatVMSToIEEE

void cvtFloatVMSToIEEE(const void* r4In_p, void* r4Out_p);

 

Convert the floating point value from VMS floating point to IEEE floating point format. Swap bytes if required, swap words, then check the exponent for underflow and correct. Return the result in the location pointed to by r4Out_p. The original value at location r4In_p is not changed.

3.6.2      void cvtFloatIEEEToVMS

void cvtFloatIEEEToVMS(const void* r4In_p, void* r4Out_p);

 

Convert the floating point value from IEEE floating point to VMS floating point format. Correct the exponent (testing for NaN, infinity, neg. zero), swap bytes if required, then swap words. Return the result in the location pointed to by r4Out_p. The original value at location r4In_p is not changed.

3.7      Array Conversion Utilities

Array conversion utilities are also defined in cvtUtil.c and .h.  Threads that share arrays of data with the SLC Control system can use these utilities to convert the entire array between the VMS format and native format.  A single variable is converted when the array count is one.

 

3.7.1      cvtFromVMS

void cvtFromVMS(const char format, const int width, const int count, const void * vmsData_p, void * const nativeData_p)

 

Convert an array of VMS data to native format.  See the next section CvtToVMS.

3.7.2      cvtToVMS

void cvtToVMS(const char format, const int width, const int count, const void * nativeData_p, void * const vmsData_p)

 

convert an array of data from native to VMS format.

 

The format argument is a single character:

3.8      Time Conversion Utilities

Time conversion utilities are defined in timeUtil.c and .h.  Timestamp data is received from the SLC Control system in each Message Service message.  These utilities allow the programmer to work in VMS time, and convert epicsTime values into VMS time. 

 

Currently there is no conversion from VMS time to epicsTime.

3.8.1      int timeEpicsToVMS

int      timeEpicsToVMS(const epicsTimeStamp* eTime_p, vmsTimeStamp_ta dest_a);

 

Convert an epicsTimeStamp value into VMS format.  This routine accomplishes the conversion in a very roundabout way, as VMS time is stored in 100s of nanoseconds since Nov 17, 1858 (an auspicious date to be sure) and EPICS time is represented in seconds since Jan 1, 1970, plus a nanosecond count since the last second.  See the code for a detailed description of the conversion.

 

Returns epicsTimeError if error, epicsTimeOk if successful.

3.8.2      int      timeGetVMS

int      timeGetVMS(vmsTimeStamp_ta dest_a);

 

Get the current time in VMS format.  Gets the current epics time by calling epicsTimeGetCurrent, then converts to vms using timeEpicsToVMS (see above).

 

Returns epicsTimeError if error, epicsTimeOk if successful.

3.8.3      long int timeDiffVMS10usec

long int timeDiffVMS10usec(vmsTimeStamp_ta  ref_a, const vmsTimeStamp_ta later_a);

 

This routine gets the difference between to VMS format timestamps in 10 micro second units. The returned value is TRUNCATED – not rounded.

 

Returns epicsTimeError if error, epicsTimeOk if successful.

3.8.4      long int timeDiffVMS10msec

long int timeDiffVMS10msec(const vmsTimeStamp_ta  ref_a, const vmsTimeStamp_ta later_a);

 

This routine gets the difference between to VMS format timestamps in 10 millisecond units. The return value is TRUNCATED – not rounded.

 

Returns epicsTimeError if error, epicsTimeOk if successful.

3.8.5      double   timeVMSDouble

double   timeVMSDouble(const vmsTimeStamp_ta src_a);

 

This routine returns a VMS timestamp in a double type variable.

 

Returns epicsTimeError if error, epicsTimeOk if successful.

3.9      TCP Utilities

TCP utilities are defined in tcpUtil.c and .h.  The following routines in this file are used by other SLC-Aware IOC threads for TCP/IP socket related functions. The tcp utilities return the vmsstat_t SLC Control System type errors, and log them via the slcCmlogLogMsg utility.  Logged errors are listed for each function

3.9.1      vmsstat_t tcpGetBuffer

vmsstat_t tcpGetBuffer(const slcSocket_ts* sock_ps,

                                       const int            bytesReqd,

                                       int                     *bytesRcvd_p

                                       fwd_hdr_ts      *fwd_ps,

                                       void                 *buf_p);

 

Get a buffer of bytesReqd data bytes from the ‘sock_ps->sd’ socket.  Place the first bytes into the structure pointed to by fwd_ps, and the rest of the data bytes into the buf_p location.  The recv is performed in two steps.  The fwd_ps data is received first and checked for valid number of follow-on bytes, and a good crc.  If success, it will then read in the remaining bytes.  This routine waits forever for a buffer.

 

The following error codes may be returned:

MICR_EXNET_EOFERR – when 0 bytes are read

MICR_EXNET_RECVFAIL – failed on the recv socket call

MICR_EXNET_FWDCRC – forward header CRC did not pass

MICR_EXNET_FWDBCMAX – received a forward header with a bytecount greater than the allowed maximum

MICR_EXNET_FWDBCSHT – received a data buffer containing less bytes than indicated in the forward header.

3.9.2      Vmsstat_t tcpGetConnection

vmsstat_t    tcpGetConnection(const unsigned short proxyPort,

  const unsigned short srvcPort,

  slcSocket_ts* sock_ps);

 

Get a connection to the proxy at portnumber ‘proxyPort’ for the ‘srvcPort’ service.  The srvcPort is a constant that actually represents a name of the slcIOC service (eg: message service or dbex).

 

This routine creates a socket, sets the SO_REUSEADDR socket option, and connects to the Proxy using the slcGetProxyIPAddress function. In a debug mode it also binds to the socket and gets socket port information from the getsockname() function.  It makes one attempt to connect to the proxy.  If this routine connects successfully, it will send a ‘registration’ message to the proxy.  It sets the socket descriptor if successful, and sets it to INVALID_SOCKET if it fails.  The routine returns and logs the following error codes:

 

The following errors are logged and returned:

MICR_EXNET_SOCKFAIL, with an appropriate string, is logged on the following conditions:

MICR_EXNET_CONNFAIL – failed to connect the socket to the proxy port

MICR_EXNET_FWDREGFAIL – the registration with the proxy fails.

3.9.3      vmsstat_t tcpSendBuffer

vmsstat_t tcpSendBuffer(const slcSocket_ts* sock_ps,

                                         const int msgBytes,

                                         const void * msg_p);

 

Send a buffer of data out from socket sd.  The buffer has a byte count of msgBytes and is pointed to by msg_p. 

 

This routine sends a buffer of data using the send socket call.  If the returned cnt byte count is less than or equal to zero, then a MICR_EXNET_SENDFAIL code is returned, and logged.  This routine does not time out, and could possibly wait forever at the send call.

3.9.4      vmsstat_t tcpSockConnect

vmsstat_t tcpSockConnect(const slcThread_te thrd_e,

        const unsigned short proxyport,

                                            const unsigned short hostport,

                                            const float waitDeltaTime,

                                            unsigned long*elapsedCount,

        slcSocket_ts* sock_ps);

 

Attempts to connect to a socket until successful or a stop is requested.  Sleep for waitDeltaTime between connect attempts.  The recv threads in the SLC-IOC are responsible for creating and connecting sockets, so this routine should be called by any *Recv thread.  The elapsedCount is a counter to report the number of times the sleep was called.  This can be useful in diagnostics to calculate the overall elapsed time, if the function had to wait for awhile before successfully making a connection.  elapsedCount*waitDeltaTime = elapsedTime.

 

This routine checks that the socket is valid before attempting to connect.  If the tcpSockConnect call times out the MICR_EXNET_CONNFAIL code is returned and logged.  MICR_OKOK is returned upon successful completion.

3.9.5      Vmsstat_t tcpSockNonblockingConnect

vmsstat_t tcpSockNonblockingConnect(const slcThread_te thrd_e,

const unsigned short proxyport,

const unsigned short hostport,

const float waitDeltaTime,

unsigned long *elapsedCount_p,

slcSocket_ts* sock_ps);


Attempts to connect to a non-blocking socket until successful or a stop is requested.  Sleep for waitDeltaTime between connect attempts.  This is a special purpose routine only used for the Database Service dbCtl socket at this time. 

 

The elapsedCount is a counter to report the number of times the sleep was called.  This can be useful in diagnostics to calculate the overall elapsed time, if the function had to wait for awhile before successfully making a connection.  elapsedCount*waitDeltaTime = elapsedTime.

 

This routine checks that the socket is valid before attempting to connect.  If the tcpSockConnect call times out the MICR_EXNET_CONNFAIL code is returned and logged.  MICR_OKOK is returned upon successful completion.

 

3.9.6      Void tcpSockClose

void tcpSockClose(slcSocket_ts* sock_ps);

 

Destroy the socket if the socket descriptor is valid.  

 

This routine first checks that the socket descriptor sock_ps->sd is valid.  If so, it will first set sock_ps->sd = INVALID_SOCKET, then destroy the socket using the epicsSocketDestroy function.  The global socket descriptor is first set invalid so that no other thread will attempt to destroy the socket once this thread has started the process.  There is no return value or error logged.

3.9.7      epicsBoolean tcpSockCheck

epicsBoolean tcpSockCheck(const slcSocket_ts* sock_ps,

                                const slcThread_te recv_e,

                                const slcThread_te send_e,

                                const float waitDeltaTime,

                                unsigned long* elapsedCount);

 

This routine is used by the *Send threads to check for a valid socket connection before sending a buffer.  It will loop indefinitely until a valid connection is available, or the slcIOC is stopped.

 

tcpSockCheck will check the connection with the server, looping until there is a valid connection, or the receive thread is inactive (this means it will not get a socket connection) or the calling thread is told to stop.  Sleep for waitDeltaTime between connect checks.  The elapsedCount is a counter to report the number of times the sleep was called.  This can be useful in diagnostics to calculate the overall elapsed time, if the function had to wait for awhile the connection is valid.  elapsedCount*waitDeltaTime = elapsedTime

 

This routine will return an epicsFalse if the socket is not valid when it returns.

There is no error logged.

 

3.9.8      vmsstat_t tcpSockReadyForRead

vmsstat_t  tcpSockReadyForRead(const slcSocket_ts* sock_ps, unsigned short waitTime)

 

This routine uses the select statement to see if a non-blocking socket has a message and is ready to be read.  It will wait waitTime seconds at the select call.  This routine is used currently used only by the Database Service on the dbCtl non-blocking socket.

 

This routine returns the following status:

MICR_OKOK  - if the socket has a message to read

MICR_RCVTMOUT – if the call timed out without a message at the socket

MICR_RECVFAIL – if there was an error returned from the select call

 

 

 

SLC-Aware IOC Home Page | LCLS Controls | EPICS at SLAC | SLAC Computing | SLAC Networking | SLAC Home

 

Contact: Diane Fairley

Last Modified:

Apr 11,2005. by dfairley updated messageQRecv ad msgQmsgRecv

Apr 6, 2005. by saa updated slcCmlog utilities

Mar 22, 2005. by dfairley added tcpSockNonblockingConnect, tcpSockReadyForRead

Mar. 4, 2005. by dfairley changed a few msgQUtil definitions .

Feb. 1, 2005. by dfairley added new msgQUtils . Added me to contacts