Merge branch 'PSI-3.14' of git.psi.ch:epics_base/base-3-14-12 into PSI-3.14
This commit is contained in:
@@ -191,7 +191,7 @@ USE_POSIX_THREAD_PRIORITY_SCHEDULING = YES
|
||||
|
||||
# Site version number, if set will append '-' and this string to the
|
||||
# EPICS version number string that is reported by many tools
|
||||
EPICS_SITE_VERSION := $(shell date +%Y-%m)
|
||||
EPICS_SITE_VERSION=$(shell $(PERL) -MPOSIX -e 'print strftime "%Y-%m-%d_$(shell git describe --tags --dirty)", localtime')
|
||||
|
||||
# For GNU compiler, use pipes rather than temporary files for communication
|
||||
# between the various stages of compilation.
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-clang
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
ARCH_DEP_CFLAGS += -march=i686
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-clang
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 5.5.1
|
||||
VXWORKS_VERSION = 5.5
|
||||
WIND_BASE = /afs/psi.ch/project/vxworks/Tornado2.2.1
|
||||
|
||||
#there is a problem with our ccppc and optimization
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
ARCH_CLASS = ppc
|
||||
|
||||
SDK = eldk
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
ARCH_CLASS = ppc
|
||||
|
||||
SDK = eldk
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# DeltaTau PowerPMAC with ELDK 5.3
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
ARCH_CLASS = ppc
|
||||
|
||||
SDK = eldk
|
||||
SDK_DIR = /opt/eldk-5.3
|
||||
SDK_HOST_ARCH = $(GNU_HOST_ARCH)-$(SDK)-$(GNU_HOST_OS)
|
||||
GNU_ARCH = ppc440e-linux
|
||||
SDKTARGETSYSROOT=$(SDK_DIR)/powerpc-4xx/sysroots
|
||||
GNU_DIR = $(SDKTARGETSYSROOT)/$(SDK_HOST_ARCH)/usr
|
||||
GNU_BIN = $(GNU_DIR)/bin/$(GNU_ARCH)
|
||||
GNU_TARGET_INCLUDE_DIR =
|
||||
GNU_TARGET=powerpc-linux
|
||||
|
||||
ARCH_DEP_CPPFLAGS = -m32 -mcpu=440fp -mhard-float
|
||||
ARCH_DEP_CPPFLAGS += --sysroot=$(SDKTARGETSYSROOT)/$(GNU_ARCH)
|
||||
ARCH_DEP_LDFLAGS = --sysroot=$(SDKTARGETSYSROOT)/$(GNU_ARCH)
|
||||
AS=$(GNU_BIN)/$(GNU_TARGET)-as
|
||||
@@ -3,8 +3,6 @@
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
ARCH_CLASS = ppc
|
||||
|
||||
SDK = fslsdk
|
||||
|
||||
@@ -8,7 +8,7 @@ include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
# Using readline:
|
||||
# Due to missing/messed up libs in the toolchain, readline needs copies of
|
||||
# libtinfo.so.5.9 and libreadline.so.6.2 from a Raspbian 7 rootfs
|
||||
# libtinfo.so.5.9 and libreadline.so.6.2 from a Raspbian 7 rootfs
|
||||
# /lib/arm-linux-gnueabihf/ to the toolchain, e.g.
|
||||
# $(SDK_DIR)/gcc-linaro-arm-linux-gnueabihf-raspbian/arm-linux-gnueabihf/libc/lib/arm-linux-gnueabihf/
|
||||
# and manually created links libtinfo.so.5 and libreadline.so.
|
||||
@@ -18,8 +18,6 @@ include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
# Also copy /usr/include/readline/ directory from some readline 6 installation
|
||||
# to $(SDK_DIR)/gcc-linaro-arm-linux-gnueabihf-raspbian/arm-linux-gnueabihf/libc/usr/include/
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
ARCH_CLASS = arm
|
||||
|
||||
SDK_DIR = /opt/raspberrypi/arm-bcm2708
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
ARCH_CLASS = arm64
|
||||
|
||||
SDK = petalinux
|
||||
|
||||
@@ -85,16 +85,20 @@ CPP = cl -nologo -C -E
|
||||
|
||||
# Configure OS vendor C++ compiler
|
||||
#
|
||||
# __STDC__=0 gives us both:
|
||||
# 1) define STDC for code (pretend ANSI conformance)
|
||||
# 2) set it to 0 to use MS C "extensions" (open for _open etc.)
|
||||
# because MS uses: if __STDC__ ... disable many nice things
|
||||
#
|
||||
# -EHsc - generate code for exceptions
|
||||
# -GR - generate code for run time type identification
|
||||
#
|
||||
CCC = cl -EHsc -GR
|
||||
CODE_CPPFLAGS += -nologo -D__STDC__=0
|
||||
|
||||
# Other compiler flags, used for CPP, C and C++
|
||||
#
|
||||
# -FC - Show absolute path of source file in diagnostics
|
||||
# -D__STDC__=0 gives us both:
|
||||
# 1) define STDC for code (pretend ANSI conformance)
|
||||
# 2) set it to 0 to use MS C "extensions" (open for _open etc.)
|
||||
# because MS uses: if __STDC__ ... disable many nice things
|
||||
#
|
||||
CODE_CPPFLAGS += -nologo -FC -D__STDC__=0
|
||||
CODE_CPPFLAGS += -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
@@ -2,6 +2,6 @@
|
||||
CROSS_COMPILER_TARGET_ARCHS += SL6-x86
|
||||
|
||||
# Improved error checking with clang
|
||||
CROSS_COMPILER_TARGET_ARCHS += SL6-x86_64-clang
|
||||
#CROSS_COMPILER_TARGET_ARCHS += SL6-x86_64-clang
|
||||
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86_64.Common
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
GNU_HOST_ARCH=i686
|
||||
GNU_HOST_OS=linux
|
||||
LD_LIBRARY_PATH=
|
||||
|
||||
# vxWorks 5 for MVxxxx boards
|
||||
CROSS_COMPILER_TARGET_ARCHS += T2-ppc604
|
||||
@@ -34,6 +35,7 @@ CROSS_COMPILER_TARGET_ARCHS += eldk52-e500v2
|
||||
|
||||
# DeltaTau PowerPMAC
|
||||
CROSS_COMPILER_TARGET_ARCHS += eldk42-ppc4xxFP
|
||||
CROSS_COMPILER_TARGET_ARCHS += eldk53-ppc4xxFP
|
||||
|
||||
# Test other vxWorks versions
|
||||
CROSS_COMPILER_TARGET_ARCHS += V66-ppc603
|
||||
|
||||
@@ -35,7 +35,6 @@ INC += db_access_routines.h
|
||||
INC += db_convert.h
|
||||
INC += dbCaPvt.h
|
||||
|
||||
|
||||
DBDINC += menuAlarmSevr
|
||||
DBDINC += menuAlarmStat
|
||||
DBDINC += menuCompress
|
||||
|
||||
@@ -47,6 +47,9 @@ epicsExportAddress(int,dbRecordsOnceOnly);
|
||||
epicsShareDef int dbBptNotMonotonic=0;
|
||||
epicsExportAddress(int,dbBptNotMonotonic);
|
||||
|
||||
epicsShareDef int dbQuietMacroWarnings=0;
|
||||
epicsExportAddress(int,dbQuietMacroWarnings);
|
||||
|
||||
/*private routines */
|
||||
static void yyerrorAbort(char *str);
|
||||
static void allocTemp(void *pvoid);
|
||||
@@ -227,6 +230,7 @@ static long dbReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp,
|
||||
free((void *)macPairs);
|
||||
mac_input_buffer = dbCalloc(MY_BUFFER_SIZE,sizeof(char));
|
||||
}
|
||||
macSuppressWarning(macHandle,dbQuietMacroWarnings);
|
||||
}
|
||||
pinputFile = dbCalloc(1,sizeof(inputFile));
|
||||
if (filename) {
|
||||
@@ -960,23 +964,29 @@ static void dbRecordHead(char *recordType, char *name, int visible)
|
||||
|
||||
static void dbRecordField(char *name,char *value)
|
||||
{
|
||||
DBENTRY *pdbentry;
|
||||
tempListNode *ptempListNode;
|
||||
long status;
|
||||
DBENTRY *pdbentry;
|
||||
tempListNode *ptempListNode;
|
||||
long status;
|
||||
|
||||
if(duplicate) return;
|
||||
if (duplicate) return;
|
||||
ptempListNode = (tempListNode *)ellFirst(&tempList);
|
||||
pdbentry = ptempListNode->item;
|
||||
status = dbFindField(pdbentry,name);
|
||||
if(status) {
|
||||
epicsPrintf("Record \"%s\" does not have a field \"%s\"\n",
|
||||
dbGetRecordName(pdbentry), name);
|
||||
yyerror(NULL);
|
||||
return;
|
||||
if (status) {
|
||||
epicsPrintf("Record \"%s\" does not have a field \"%s\"\n",
|
||||
dbGetRecordName(pdbentry), name);
|
||||
yyerror(NULL);
|
||||
return;
|
||||
}
|
||||
if (pdbentry->indfield == 0) {
|
||||
epicsPrintf("Can't set \"NAME\" field of record \"%s\"\n",
|
||||
dbGetRecordName(pdbentry));
|
||||
yyerror(NULL);
|
||||
return;
|
||||
}
|
||||
dbTranslateEscape(value, value); /* yuck: in-place, but safe */
|
||||
status = dbPutString(pdbentry,value);
|
||||
if(status) {
|
||||
if (status) {
|
||||
epicsPrintf("Can't set \"%s.%s\" to \"%s\"\n",
|
||||
dbGetRecordName(pdbentry), name, value);
|
||||
yyerror(NULL);
|
||||
@@ -986,33 +996,33 @@ static void dbRecordField(char *name,char *value)
|
||||
|
||||
static void dbRecordInfo(char *name, char *value)
|
||||
{
|
||||
DBENTRY *pdbentry;
|
||||
tempListNode *ptempListNode;
|
||||
long status;
|
||||
DBENTRY *pdbentry;
|
||||
tempListNode *ptempListNode;
|
||||
long status;
|
||||
|
||||
if(duplicate) return;
|
||||
if (duplicate) return;
|
||||
ptempListNode = (tempListNode *)ellFirst(&tempList);
|
||||
pdbentry = ptempListNode->item;
|
||||
status = dbPutInfo(pdbentry,name,value);
|
||||
if(status) {
|
||||
epicsPrintf("Can't set \"%s\" info \"%s\" to \"%s\"\n",
|
||||
if (status) {
|
||||
epicsPrintf("Can't set \"%s\" info \"%s\" to \"%s\"\n",
|
||||
dbGetRecordName(pdbentry), name, value);
|
||||
yyerror(NULL);
|
||||
return;
|
||||
yyerror(NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void dbRecordAlias(char *name)
|
||||
{
|
||||
DBENTRY *pdbentry;
|
||||
tempListNode *ptempListNode;
|
||||
long status;
|
||||
DBENTRY *pdbentry;
|
||||
tempListNode *ptempListNode;
|
||||
long status;
|
||||
|
||||
if(duplicate) return;
|
||||
if (duplicate) return;
|
||||
ptempListNode = (tempListNode *)ellFirst(&tempList);
|
||||
pdbentry = ptempListNode->item;
|
||||
status = dbCreateAlias(pdbentry, name);
|
||||
if(status) {
|
||||
if (status) {
|
||||
epicsPrintf("Can't create alias \"%s\" for \"%s\"\n",
|
||||
name, dbGetRecordName(pdbentry));
|
||||
yyerror(NULL);
|
||||
@@ -1022,15 +1032,16 @@ static void dbRecordAlias(char *name)
|
||||
|
||||
static void dbAlias(char *name, char *alias)
|
||||
{
|
||||
DBENTRY dbEntry;
|
||||
DBENTRY *pdbEntry = &dbEntry;
|
||||
DBENTRY dbEntry;
|
||||
DBENTRY *pdbEntry = &dbEntry;
|
||||
|
||||
dbInitEntry(pdbbase, pdbEntry);
|
||||
if (dbFindRecord(pdbEntry, name)) {
|
||||
epicsPrintf("Alias \"%s\" refers to unknown record \"%s\"\n",
|
||||
alias, name);
|
||||
yyerror(NULL);
|
||||
} else if (dbCreateAlias(pdbEntry, alias)) {
|
||||
}
|
||||
else if (dbCreateAlias(pdbEntry, alias)) {
|
||||
epicsPrintf("Can't create alias \"%s\" referring to \"%s\"\n",
|
||||
alias, name);
|
||||
yyerror(NULL);
|
||||
@@ -1040,14 +1051,14 @@ static void dbAlias(char *name, char *alias)
|
||||
|
||||
static void dbRecordBody(void)
|
||||
{
|
||||
DBENTRY *pdbentry;
|
||||
DBENTRY *pdbentry;
|
||||
|
||||
if(duplicate) {
|
||||
duplicate = FALSE;
|
||||
return;
|
||||
if (duplicate) {
|
||||
duplicate = FALSE;
|
||||
return;
|
||||
}
|
||||
pdbentry = (DBENTRY *)popFirstTemp();
|
||||
if(ellCount(&tempList))
|
||||
yyerrorAbort("dbRecordBody: tempList not empty");
|
||||
if (ellCount(&tempList))
|
||||
yyerrorAbort("dbRecordBody: tempList not empty");
|
||||
dbFreeEntry(pdbentry);
|
||||
}
|
||||
|
||||
@@ -51,9 +51,8 @@ typedef struct errnumnode {
|
||||
#define NHASH 256
|
||||
|
||||
|
||||
static ELLLIST errnumlist = ELLLIST_INIT;
|
||||
static ERRNUMNODE **hashtable;
|
||||
static int initialized = FALSE;
|
||||
static ERRNUMNODE **hashtable = NULL;
|
||||
#define initialized (hashtable!=NULL)
|
||||
extern ERRSYMTAB_ID errSymTbl;
|
||||
|
||||
/****************************************************************
|
||||
@@ -67,12 +66,8 @@ extern ERRSYMTAB_ID errSymTbl;
|
||||
int epicsShareAPI errSymBld(void)
|
||||
{
|
||||
ERRSYMBOL *errArray = errSymTbl->symbols;
|
||||
ERRNUMNODE *perrNumNode = NULL;
|
||||
ERRNUMNODE *pNextNode = NULL;
|
||||
ERRNUMNODE **phashnode = NULL;
|
||||
int i;
|
||||
int modnum;
|
||||
unsigned short hashInd;
|
||||
|
||||
if(initialized) return(0);
|
||||
hashtable = (ERRNUMNODE**)callocMustSucceed
|
||||
@@ -89,21 +84,6 @@ int epicsShareAPI errSymBld(void)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
perrNumNode = (ERRNUMNODE *) ellFirst(&errnumlist);
|
||||
while (perrNumNode) {
|
||||
/* hash each perrNumNode->errNum */
|
||||
hashInd = errhash(perrNumNode->errNum);
|
||||
phashnode = (ERRNUMNODE**)&hashtable[hashInd];
|
||||
pNextNode = (ERRNUMNODE*) *phashnode;
|
||||
/* search for last node (NULL) of hashnode linked list */
|
||||
while (pNextNode) {
|
||||
phashnode = &pNextNode->hashnode;
|
||||
pNextNode = *phashnode;
|
||||
}
|
||||
*phashnode = perrNumNode;
|
||||
perrNumNode = (ERRNUMNODE *) ellNext((ELLNODE *) perrNumNode);
|
||||
}
|
||||
initialized = TRUE;
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -125,16 +105,33 @@ unsigned short errnum;
|
||||
|
||||
/****************************************************************
|
||||
* ERRSYMBOLADD
|
||||
* adds symbols to the master errnumlist as compiled from errSymTbl.c
|
||||
* adds symbols to the master hashtable as compiled from errSymTbl.c
|
||||
***************************************************************/
|
||||
int epicsShareAPI errSymbolAdd (long errNum,char *name)
|
||||
{
|
||||
ERRNUMNODE *pNew;
|
||||
ERRNUMNODE *perrNumNode;
|
||||
ERRNUMNODE *pNextNode = NULL;
|
||||
ERRNUMNODE **phashnode = NULL;
|
||||
unsigned short hashInd;
|
||||
|
||||
if(!initialized) errSymBld();
|
||||
|
||||
perrNumNode = (ERRNUMNODE*)callocMustSucceed(1,sizeof(ERRNUMNODE),"errSymbolAdd");
|
||||
perrNumNode->errNum = errNum;
|
||||
perrNumNode->message = name;
|
||||
|
||||
/* hash each perrNumNode->errNum */
|
||||
hashInd = errhash(perrNumNode->errNum);
|
||||
phashnode = (ERRNUMNODE**)&hashtable[hashInd];
|
||||
pNextNode = (ERRNUMNODE*) *phashnode;
|
||||
/* search for last node (NULL) of hashnode linked list */
|
||||
while (pNextNode) {
|
||||
phashnode = &pNextNode->hashnode;
|
||||
pNextNode = *phashnode;
|
||||
}
|
||||
*phashnode = perrNumNode;
|
||||
perrNumNode = (ERRNUMNODE *) ellNext((ELLNODE *) perrNumNode);
|
||||
|
||||
pNew = (ERRNUMNODE*)callocMustSucceed(1,sizeof(ERRNUMNODE),"errSymbolAdd");
|
||||
pNew->errNum = errNum;
|
||||
pNew->message = name;
|
||||
ellAdd(&errnumlist,(ELLNODE*)pNew);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "errlog.h"
|
||||
#include "logClient.h"
|
||||
#include "iocLog.h"
|
||||
#include "epicsExit.h"
|
||||
|
||||
int iocLogDisable = 0;
|
||||
|
||||
@@ -75,6 +76,14 @@ void epicsShareAPI epicsShareAPI iocLogFlush (void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* logClientDestroy()
|
||||
*/
|
||||
static void iocLogClientDestroy (logClientId id)
|
||||
{
|
||||
errlogRemoveListener (logClientSendMessage);
|
||||
}
|
||||
|
||||
/*
|
||||
* iocLogClientInit()
|
||||
*/
|
||||
@@ -91,7 +100,8 @@ static logClientId iocLogClientInit (void)
|
||||
}
|
||||
id = logClientCreate (addr, port);
|
||||
if (id != NULL) {
|
||||
errlogAddListener ( logClientSendMessage, id );
|
||||
errlogAddListener (logClientSendMessage, id);
|
||||
epicsAtExit (iocLogClientDestroy, id);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
@@ -139,13 +149,3 @@ logClientId epicsShareAPI logClientInit (void)
|
||||
{
|
||||
return iocLogClientInit ();
|
||||
}
|
||||
|
||||
/*
|
||||
* logClientSendMessage (); deprecated
|
||||
*/
|
||||
void logClientSendMessage ( logClientId id, const char * message )
|
||||
{
|
||||
if ( !iocLogDisable ) {
|
||||
logClientSend (id, message);
|
||||
}
|
||||
}
|
||||
|
||||
+147
-124
@@ -24,6 +24,7 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include "dbDefs.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "iocLog.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsThread.h"
|
||||
#include "epicsTime.h"
|
||||
@@ -42,6 +43,7 @@ typedef struct {
|
||||
SOCKET sock;
|
||||
epicsThreadId restartThreadId;
|
||||
epicsEventId stateChangeNotify;
|
||||
epicsEventId shutdownNotify;
|
||||
unsigned connectCount;
|
||||
unsigned nextMsgIndex;
|
||||
unsigned connected;
|
||||
@@ -51,9 +53,13 @@ typedef struct {
|
||||
} logClient;
|
||||
|
||||
static const double LOG_RESTART_DELAY = 5.0; /* sec */
|
||||
static const double LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT = 5.0; /* sec */
|
||||
static const double LOG_SERVER_SHUTDOWN_TIMEOUT = 30.0; /* sec */
|
||||
|
||||
/*
|
||||
* If set using iocLogPrefix() this string is prepended to all log messages:
|
||||
*/
|
||||
static char* logClientPrefix = NULL;
|
||||
|
||||
/*
|
||||
* logClientClose ()
|
||||
*/
|
||||
@@ -77,8 +83,6 @@ static void logClientClose ( logClient *pClient )
|
||||
pClient->sock = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
pClient->nextMsgIndex = 0u;
|
||||
memset ( pClient->msgBuf, '\0', sizeof ( pClient->msgBuf ) );
|
||||
pClient->connected = 0u;
|
||||
|
||||
/*
|
||||
@@ -106,6 +110,7 @@ static void logClientDestroy (logClientId id)
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
pClient->shutdown = 1u;
|
||||
epicsMutexUnlock ( pClient->mutex );
|
||||
epicsEventSignal ( pClient->shutdownNotify );
|
||||
|
||||
/* unblock log client thread blocking in send() or connect() */
|
||||
interruptInfo =
|
||||
@@ -150,112 +155,109 @@ static void logClientDestroy (logClientId id)
|
||||
logClientClose ( pClient );
|
||||
|
||||
epicsMutexDestroy ( pClient->mutex );
|
||||
|
||||
epicsEventDestroy ( pClient->stateChangeNotify );
|
||||
epicsEventDestroy ( pClient->shutdownNotify );
|
||||
|
||||
free ( pClient );
|
||||
}
|
||||
|
||||
/*
|
||||
* logClientCheckConnection
|
||||
*/
|
||||
static void logClientCheckConnection( logClient * pClient )
|
||||
{
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
while ( pClient->connected ) {
|
||||
struct timeval timeout = { 0, 0 };
|
||||
fd_set set;
|
||||
char buffer[256];
|
||||
|
||||
FD_ZERO ( &set );
|
||||
FD_SET ( pClient->sock, &set );
|
||||
if ( select ( pClient->sock + 1, &set, NULL, NULL, &timeout ) == 0)
|
||||
break;
|
||||
if ( recv ( pClient->sock, buffer, sizeof ( buffer ), 0 ) == 0 ) {
|
||||
fprintf ( stderr, "log client: connection closed by server \"%s\"\n",
|
||||
pClient->name );
|
||||
logClientClose ( pClient );
|
||||
break;
|
||||
}
|
||||
}
|
||||
epicsMutexUnlock ( pClient->mutex );
|
||||
}
|
||||
|
||||
/*
|
||||
* This method requires the pClient->mutex be owned already.
|
||||
*/
|
||||
static void sendMessageChunk(logClient * pClient, const char * message) {
|
||||
unsigned strSize;
|
||||
|
||||
strSize = strlen ( message );
|
||||
while ( strSize ) {
|
||||
unsigned msgBufBytesLeft =
|
||||
sizeof ( pClient->msgBuf ) - pClient->nextMsgIndex;
|
||||
|
||||
if ( msgBufBytesLeft < strSize && pClient->nextMsgIndex != 0u && pClient->connected)
|
||||
{
|
||||
/* buffer is full, thus flush it */
|
||||
logClientCheckConnection( pClient );
|
||||
logClientFlush ( pClient );
|
||||
msgBufBytesLeft = sizeof ( pClient->msgBuf ) - pClient->nextMsgIndex;
|
||||
}
|
||||
if ( msgBufBytesLeft == 0u ) {
|
||||
fprintf ( stderr, "log client: messages to \"%s\" are lost\n",
|
||||
pClient->name );
|
||||
break;
|
||||
}
|
||||
if ( msgBufBytesLeft > strSize) msgBufBytesLeft = strSize;
|
||||
memcpy ( & pClient->msgBuf[pClient->nextMsgIndex],
|
||||
message, msgBufBytesLeft );
|
||||
pClient->nextMsgIndex += msgBufBytesLeft;
|
||||
strSize -= msgBufBytesLeft;
|
||||
message += msgBufBytesLeft;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* logClientSend ()
|
||||
*/
|
||||
void epicsShareAPI logClientSend ( logClientId id, const char * message )
|
||||
{
|
||||
logClient * pClient = ( logClient * ) id;
|
||||
unsigned strSize;
|
||||
|
||||
if ( ! pClient || ! message ) {
|
||||
return;
|
||||
}
|
||||
|
||||
strSize = strlen ( message );
|
||||
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
|
||||
while ( strSize ) {
|
||||
unsigned msgBufBytesLeft =
|
||||
sizeof ( pClient->msgBuf ) - pClient->nextMsgIndex;
|
||||
|
||||
if ( strSize > msgBufBytesLeft ) {
|
||||
int status;
|
||||
|
||||
if ( ! pClient->connected ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( msgBufBytesLeft > 0u ) {
|
||||
memcpy ( & pClient->msgBuf[pClient->nextMsgIndex],
|
||||
message, msgBufBytesLeft );
|
||||
pClient->nextMsgIndex += msgBufBytesLeft;
|
||||
strSize -= msgBufBytesLeft;
|
||||
message += msgBufBytesLeft;
|
||||
}
|
||||
|
||||
status = send ( pClient->sock, pClient->msgBuf,
|
||||
pClient->nextMsgIndex, 0 );
|
||||
if ( status > 0 ) {
|
||||
unsigned nSent = (unsigned) status;
|
||||
if ( nSent < pClient->nextMsgIndex ) {
|
||||
unsigned newNextMsgIndex = pClient->nextMsgIndex - nSent;
|
||||
memmove ( pClient->msgBuf, & pClient->msgBuf[nSent],
|
||||
newNextMsgIndex );
|
||||
pClient->nextMsgIndex = newNextMsgIndex;
|
||||
}
|
||||
else {
|
||||
pClient->nextMsgIndex = 0u;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( ! pClient->shutdown ) {
|
||||
char sockErrBuf[64];
|
||||
if ( status ) {
|
||||
epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) );
|
||||
}
|
||||
else {
|
||||
strcpy ( sockErrBuf, "server initiated disconnect" );
|
||||
}
|
||||
fprintf ( stderr, "log client: lost contact with log server at \"%s\" because \"%s\"\n",
|
||||
pClient->name, sockErrBuf );
|
||||
}
|
||||
logClientClose ( pClient );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
memcpy ( & pClient->msgBuf[pClient->nextMsgIndex],
|
||||
message, strSize );
|
||||
pClient->nextMsgIndex += strSize;
|
||||
break;
|
||||
}
|
||||
if (logClientPrefix) {
|
||||
sendMessageChunk(pClient, logClientPrefix);
|
||||
}
|
||||
|
||||
sendMessageChunk(pClient, message);
|
||||
|
||||
epicsMutexUnlock (pClient->mutex);
|
||||
}
|
||||
|
||||
|
||||
void epicsShareAPI logClientFlush ( logClientId id )
|
||||
{
|
||||
unsigned nSent = 0u;
|
||||
|
||||
logClient * pClient = ( logClient * ) id;
|
||||
|
||||
if ( ! pClient ) {
|
||||
if ( ! pClient || ! pClient->connected ) {
|
||||
return;
|
||||
}
|
||||
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
|
||||
while ( pClient->nextMsgIndex && pClient->connected ) {
|
||||
int status = send ( pClient->sock, pClient->msgBuf,
|
||||
pClient->nextMsgIndex, 0 );
|
||||
while ( nSent < pClient->nextMsgIndex && pClient->connected ) {
|
||||
int status = send ( pClient->sock, pClient->msgBuf + nSent,
|
||||
pClient->nextMsgIndex - nSent, 0 );
|
||||
if ( status > 0 ) {
|
||||
unsigned nSent = (unsigned) status;
|
||||
if ( nSent < pClient->nextMsgIndex ) {
|
||||
unsigned newNextMsgIndex = pClient->nextMsgIndex - nSent;
|
||||
memmove ( pClient->msgBuf, & pClient->msgBuf[nSent],
|
||||
newNextMsgIndex );
|
||||
pClient->nextMsgIndex = newNextMsgIndex;
|
||||
}
|
||||
else {
|
||||
pClient->nextMsgIndex = 0u;
|
||||
}
|
||||
nSent += (unsigned) status;
|
||||
}
|
||||
else {
|
||||
if ( ! pClient->shutdown ) {
|
||||
@@ -273,6 +275,11 @@ void epicsShareAPI logClientFlush ( logClientId id )
|
||||
break;
|
||||
}
|
||||
}
|
||||
pClient->nextMsgIndex -= nSent;
|
||||
if ( nSent > 0 && pClient->nextMsgIndex > 0 ) {
|
||||
memmove ( pClient->msgBuf, & pClient->msgBuf[nSent],
|
||||
pClient->nextMsgIndex );
|
||||
}
|
||||
epicsMutexUnlock ( pClient->mutex );
|
||||
}
|
||||
|
||||
@@ -377,20 +384,6 @@ static void logClientConnect (logClient *pClient)
|
||||
fprintf (stderr, "log client: unable to enable keepalive option because \"%s\"\n", sockErrBuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* we don't need full-duplex (clients only write), so we shutdown
|
||||
* the read end of our socket
|
||||
*/
|
||||
status = shutdown (pClient->sock, SHUT_RD);
|
||||
if (status < 0) {
|
||||
char sockErrBuf[64];
|
||||
epicsSocketConvertErrnoToString (
|
||||
sockErrBuf, sizeof ( sockErrBuf ) );
|
||||
fprintf (stderr, "%s:%d shutdown(%d,SHUT_RD) error was \"%s\"\n",
|
||||
__FILE__, __LINE__, pClient->sock, sockErrBuf);
|
||||
/* not fatal (although it shouldn't happen) */
|
||||
}
|
||||
|
||||
/*
|
||||
* set how long we will wait for the TCP state machine
|
||||
* to clean up when we issue a close(). This
|
||||
@@ -430,20 +423,21 @@ static void logClientRestart ( logClientId id )
|
||||
/* SMP safe state inspection */
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
while ( ! pClient->shutdown ) {
|
||||
unsigned isConn;
|
||||
unsigned isConn, dataToSend;
|
||||
|
||||
logClientCheckConnection( pClient );
|
||||
|
||||
isConn = pClient->connected;
|
||||
dataToSend = pClient->nextMsgIndex;
|
||||
|
||||
epicsMutexUnlock ( pClient->mutex );
|
||||
|
||||
if ( isConn ) {
|
||||
if ( dataToSend ) {
|
||||
if ( ! isConn ) logClientConnect ( pClient );
|
||||
logClientFlush ( pClient );
|
||||
}
|
||||
else {
|
||||
logClientConnect ( pClient );
|
||||
}
|
||||
|
||||
epicsThreadSleep ( LOG_RESTART_DELAY );
|
||||
|
||||
epicsEventWaitWithTimeout ( pClient->shutdownNotify, LOG_RESTART_DELAY);
|
||||
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
}
|
||||
@@ -459,9 +453,7 @@ static void logClientRestart ( logClientId id )
|
||||
logClientId epicsShareAPI logClientCreate (
|
||||
struct in_addr server_addr, unsigned short server_port)
|
||||
{
|
||||
epicsTimeStamp begin, current;
|
||||
logClient *pClient;
|
||||
double diff;
|
||||
|
||||
pClient = calloc (1, sizeof (*pClient));
|
||||
if (pClient==NULL) {
|
||||
@@ -486,14 +478,22 @@ logClientId epicsShareAPI logClientCreate (
|
||||
pClient->shutdownConfirm = 0;
|
||||
|
||||
epicsAtExit (logClientDestroy, (void*) pClient);
|
||||
|
||||
|
||||
pClient->stateChangeNotify = epicsEventCreate (epicsEventEmpty);
|
||||
if ( ! pClient->stateChangeNotify ) {
|
||||
epicsMutexDestroy ( pClient->mutex );
|
||||
free ( pClient );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
pClient->shutdownNotify = epicsEventCreate (epicsEventEmpty);
|
||||
if ( ! pClient->shutdownNotify ) {
|
||||
epicsMutexDestroy ( pClient->mutex );
|
||||
epicsEventDestroy ( pClient->stateChangeNotify );
|
||||
free ( pClient );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pClient->restartThreadId = epicsThreadCreate (
|
||||
"logRestart", epicsThreadPriorityLow,
|
||||
epicsThreadGetStackSize(epicsThreadStackSmall),
|
||||
@@ -501,33 +501,12 @@ logClientId epicsShareAPI logClientCreate (
|
||||
if ( pClient->restartThreadId == NULL ) {
|
||||
epicsMutexDestroy ( pClient->mutex );
|
||||
epicsEventDestroy ( pClient->stateChangeNotify );
|
||||
epicsEventDestroy ( pClient->shutdownNotify );
|
||||
free (pClient);
|
||||
fprintf(stderr, "log client: unable to start log client connection watch dog thread\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* attempt to synchronize with circuit connect
|
||||
*/
|
||||
epicsTimeGetCurrent ( & begin );
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
do {
|
||||
epicsMutexUnlock ( pClient->mutex );
|
||||
epicsEventWaitWithTimeout (
|
||||
pClient->stateChangeNotify,
|
||||
LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT / 10.0 );
|
||||
epicsTimeGetCurrent ( & current );
|
||||
diff = epicsTimeDiffInSeconds ( & current, & begin );
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
}
|
||||
while ( ! pClient->connected && diff < LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT );
|
||||
epicsMutexUnlock ( pClient->mutex );
|
||||
|
||||
if ( ! pClient->connected ) {
|
||||
fprintf (stderr, "log client create: timed out synchronizing with circuit connect to \"%s\" after %.1f seconds\n",
|
||||
pClient->name, LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT );
|
||||
}
|
||||
|
||||
return (void *) pClient;
|
||||
}
|
||||
|
||||
@@ -537,6 +516,9 @@ logClientId epicsShareAPI logClientCreate (
|
||||
void epicsShareAPI logClientShow (logClientId id, unsigned level)
|
||||
{
|
||||
logClient *pClient = (logClient *) id;
|
||||
if ( ! pClient ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pClient->connected ) {
|
||||
printf ("log client: connected to log server at \"%s\"\n", pClient->name);
|
||||
@@ -550,5 +532,46 @@ void epicsShareAPI logClientShow (logClientId id, unsigned level)
|
||||
pClient->sock==INVALID_SOCKET?"INVALID":"OK",
|
||||
pClient->connectCount);
|
||||
}
|
||||
|
||||
if (logClientPrefix) {
|
||||
printf ("log client: prefix is \"%s\"\n", logClientPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* logClientSendMessage (); deprecated
|
||||
*/
|
||||
void logClientSendMessage ( logClientId id, const char * message )
|
||||
{
|
||||
if ( !iocLogDisable ) {
|
||||
logClientSend (id, message);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* iocLogPrefix()
|
||||
*/
|
||||
void epicsShareAPI iocLogPrefix(const char * prefix)
|
||||
{
|
||||
|
||||
/* If we have already established a log prefix, don't let the user change
|
||||
* it. The iocLogPrefix command is expected to be run from the IOC startup
|
||||
* script during initialization; the prefix can't be changed once it has
|
||||
* been set.
|
||||
*/
|
||||
|
||||
if (logClientPrefix) {
|
||||
printf ("iocLogPrefix: The prefix was already set to \"%s\" "
|
||||
"and can't be changed.\n", logClientPrefix);
|
||||
return;
|
||||
}
|
||||
|
||||
if (prefix) {
|
||||
unsigned prefixLen = strlen(prefix);
|
||||
if (prefixLen > 0) {
|
||||
char * localCopy = malloc(prefixLen+1);
|
||||
strcpy(localCopy, prefix);
|
||||
logClientPrefix = localCopy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ epicsShareFunc logClientId epicsShareAPI logClientCreate (
|
||||
epicsShareFunc void epicsShareAPI logClientSend (logClientId id, const char *message);
|
||||
epicsShareFunc void epicsShareAPI logClientShow (logClientId id, unsigned level);
|
||||
epicsShareFunc void epicsShareAPI logClientFlush (logClientId id);
|
||||
epicsShareFunc void epicsShareAPI iocLogPrefix(const char* prefix);
|
||||
|
||||
/* deprecated interface; retained for backward compatibility */
|
||||
/* note: implementations are in iocLog.c, not logClient.c */
|
||||
|
||||
@@ -49,6 +49,7 @@ variable(CASDEBUG,int)
|
||||
# dbStaticLib settings
|
||||
variable(dbRecordsOnceOnly,int)
|
||||
variable(dbBptNotMonotonic,int)
|
||||
variable(dbQuietMacroWarnings,int)
|
||||
|
||||
# dbLoadTemplate settings
|
||||
variable(dbTemplateMaxVars,int)
|
||||
|
||||
+14
-6
@@ -174,6 +174,7 @@ static long process(seqRecord *prec)
|
||||
linkDesc *plink;
|
||||
unsigned short lmask;
|
||||
int tmp;
|
||||
int index;
|
||||
|
||||
if(seqRecDebug > 10)
|
||||
printf("seqRecord: process(%s) pact = %d\n", prec->name, prec->pact);
|
||||
@@ -230,6 +231,7 @@ static long process(seqRecord *prec)
|
||||
}
|
||||
/* Figure out which links are going to be processed */
|
||||
pcb->index = 0;
|
||||
index = 0;
|
||||
plink = (linkDesc *)(&(prec->dly1));
|
||||
tmp = 1;
|
||||
while (lmask)
|
||||
@@ -241,23 +243,21 @@ static long process(seqRecord *prec)
|
||||
if ((lmask & 1) && ((plink->lnk.type != CONSTANT)||(plink->dol.type != CONSTANT)))
|
||||
{
|
||||
if (seqRecDebug > 4)
|
||||
printf(" seqRec-process Adding link %d at index %d\n", tmp, pcb->index);
|
||||
printf(" seqRec-process Adding link %d at index %d\n", tmp, index);
|
||||
|
||||
pcb->plinks[pcb->index] = plink;
|
||||
pcb->index++;
|
||||
pcb->plinks[index++] = plink;
|
||||
}
|
||||
lmask >>= 1;
|
||||
plink++;
|
||||
tmp++;
|
||||
}
|
||||
pcb->plinks[pcb->index] = NULL; /* mark the bottom of the list */
|
||||
pcb->plinks[index] = NULL; /* mark the bottom of the list */
|
||||
|
||||
if (!pcb->index)
|
||||
if (!index)
|
||||
{ /* There was nothing to do, finish record processing here */
|
||||
return(asyncFinish(prec));
|
||||
}
|
||||
|
||||
pcb->index = 0;
|
||||
/* Start doing the first forward link (We have at least one for sure) */
|
||||
processNextLink(prec);
|
||||
|
||||
@@ -367,6 +367,14 @@ static void processCallback(CALLBACK *arg)
|
||||
if (seqRecDebug > 5)
|
||||
printf("processCallback(%s) processing field index %d\n", prec->name, pcb->index+1);
|
||||
|
||||
if (pcb->plinks[pcb->index] == NULL)
|
||||
{
|
||||
static int overrun = 0;
|
||||
errlogPrintf("seq record %s: index overrun number %d in callback.\n", prec->name, ++overrun);
|
||||
dbScanUnlock((struct dbCommon *)prec);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save the old value */
|
||||
myDouble = pcb->plinks[pcb->index]->dov;
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ include $(TOP)/configure/CONFIG
|
||||
PROD_IOC_DEFAULT = softIoc
|
||||
PROD_IOC_iOS = -nil-
|
||||
|
||||
PROD_LDFLAGS_vxWorks = --whole-archive
|
||||
|
||||
DBD += softIoc.dbd
|
||||
softIoc_DBD += base.dbd
|
||||
softIoc_DBD += dlload.dbd
|
||||
|
||||
Reference in New Issue
Block a user