Compare commits

..

85 Commits

Author SHA1 Message Date
Janet Anderson
3009091875 Creating R3.14.12.3 2013-12-16 15:51:45 -06:00
Janet Anderson
6a0d5e0e87 Changed EPICS to Release 3.14.12.4 2013-12-16 15:48:54 -06:00
Andrew Johnson
97636a45e0 libCom: Remove epicsShareAPI from epicsExit APIs
Passing epicsExitCallAtExits into atexit() was generating
a warning about passing in a __stdcall routine pointer.
2013-12-16 14:52:29 -06:00
Andrew Johnson
a50c66b6ff libCom/test: Added epicsEnvTest.c
VxWorks 6.x can make environment variables private to each
thread, which doesn't work too well.
A test failure on VxWorks explains how to change the image
configuration to fix this.
2013-12-16 12:48:25 -06:00
Andrew Johnson
88ae947c84 configure: Refined how/when we pull in <top>/cfg files
Only read CONFIG* and RULES* files,
and only do so in build dirs, i.e. when T_A is defined.
2013-12-13 16:04:01 -06:00
Andrew Johnson
22540ac743 docs: Release note update.
Credit Peter Heesterman with windows build updates.
2013-12-11 18:11:51 -06:00
Andrew Johnson
197e992241 Fixed iocsh stream redirection for several commands
Eric provided the fixes to iocsh (empty commands would not reset
redirected streams), I fixed various commands.
2013-12-11 17:50:29 -06:00
Andrew Johnson
b0cf5c256a startup: Add cygwin-x86_64 to EpicsHostArch.pl script 2013-12-10 16:28:08 -06:00
Andrew Johnson
76e967c960 dbStatic: Fixed crash loading record of unknown type
Fixed segfault when dbLoadRecords tried to load a record of a
type that was not defined in its DBD files.
2013-12-04 17:37:42 -06:00
Andrew Johnson
4ac35ab85c docs: iPhone Simulator builds broken by Xcode 5
From Mark Engbretson, no known solution yet.
2013-12-04 10:37:44 -06:00
Janet Anderson
4209abe2cf Set snapshot to 3.14.12.4-rc1-DEV 2013-12-02 14:12:45 -06:00
Janet Anderson
90d1d9568c Creating 3.14.12.4-rc1 2013-12-02 13:56:17 -06:00
Janet Anderson
082df89090 Creating 3.14.12.4-rc1 2013-12-02 13:54:20 -06:00
Andrew Johnson
78a4e462d5 libCom: Recognize hex literals in epicsStrtod()
Allows Windows and VxWorks to accept hex integers as a double.
2013-12-02 11:12:19 -06:00
Andrew Johnson
bd82554299 Set snapshot to 3.14.12.4-pre1-DEV 2013-11-20 18:03:16 -06:00
Andrew Johnson
1a3e7414b3 Creating 3.14.12.4-pre1 2013-11-20 18:02:28 -06:00
Andrew Johnson
9ab6f89604 Clean up epicsExport.h includes
Mostly in record and device support, this commit puts
the include in the right place and moves some other
includes around to get the order right.
2013-11-20 16:21:10 -06:00
Andrew Johnson
570993e32b configure: New targets cygwin-x86_64 and windows-x64-mingw 2013-11-19 18:50:49 -06:00
Andrew Johnson
93be1400c1 Fixed various 64-bit windows build issues. 2013-11-19 18:42:45 -06:00
Andrew Johnson
176ee926ad cygwin: Fixed SocketSystemCallInterruptMechanism
Cygwin changed it back again.
2013-11-19 18:41:03 -06:00
Andrew Johnson
2d52067484 libCom: Clean up build warnings from Visual Studio. 2013-11-19 15:26:22 -06:00
Andrew Johnson
66209118f6 libCom/macLib: Don't use unsigned chars in macParseDefns()
These pointers are really pointing to standard chars.
2013-11-13 12:39:23 -06:00
Andrew Johnson
d6dab34ae9 Merged changes from Jeff Hill's ca-ref-man-maint branch.
This contains only text changes to the CA reference manual.
2013-11-07 17:57:09 -06:00
Andrew Johnson
4b44881744 db: Fixed bogus dbScan overrun warnings
Penalizing the 0.1 second scan thread by 0.1 seconds
guarantees another overrun in most cases...
Warning message improved.

Also added a release note for Jeff's CAS commit.
2013-10-17 17:21:26 -05:00
Jeff Hill
42f4c3a0a5 fixed potential memory leak 2013-10-17 09:23:47 -06:00
Andrew Johnson
2ad468dd38 CAref: Fix returns from ca_attach_context()
ECA_NORMAL was missing, ECA_ISATTACHED given twice.
2013-09-27 09:59:34 -05:00
Andrew Johnson
2bf4b36639 configure: Support Apple Xcode 5.0 and iOS 7.0
Not tested on the 64-bit ARMv8 architecture, although it should be
compatible (confirmation would be welcome).
2013-09-24 15:30:26 -05:00
Andrew Johnson
6814b09fad docs: Release Notes update
... for several recent commits.
2013-09-13 17:30:38 -05:00
Andrew Johnson
2d3a828acd Fixed read-back of TSEL link
Reading back a .TSEL field that was originally pointed to
another record's .TIME field was exposing internal details
that didn't need to be made visible. This commit hides the
.TIME => .VAL change completely, and allows a .TSEL link
field to be saved and restored properly using autosave.
2013-09-13 11:57:18 -05:00
Andrew Johnson
4ae048572a Added dbTemplateMaxVars variable
Allows users to configure dbLoadTemplate command to accept more than
100 variables or a larger string buffer for variables.
2013-09-13 11:36:52 -05:00
Andrew Johnson
e49210a3ea configure: IOS version bump to 6.1 2013-08-30 12:50:34 -05:00
Andrew Johnson
d25eff3af7 configure: Darwin build settings
Modify comments and defaults for darwin builds.
Changing to use gcc wasn't working.
2013-08-30 11:51:51 -05:00
Andrew Johnson
01f0fdbf1e More file permission fixes. 2013-08-19 15:46:51 -05:00
Andrew Johnson
3219ea0608 Fixed file permissions. 2013-08-19 13:30:19 -05:00
Ralph Lange
fb983fe382 CAref: typos, replace ..._event() calls with ..._subscription() (by J. Lewis Muir) 2013-08-16 17:00:13 +02:00
Andrew Johnson
ffa96d36e1 db: dbpf can now put strings to UCHAR arrays
Also improved the dbpf error message on value conversion failures.
Source code reformatting inside dbTest.c as well.
2013-08-01 18:10:18 -05:00
Janet Anderson
515f882c7b Added OPT_CXXFLAGS_YES += -g 2013-07-25 10:49:26 -05:00
Janet Anderson
d3b6d01807 Added WIN32 system library for epicsSockResolveTest 2013-07-17 15:55:49 -05:00
Andrew Johnson
f2891d72e5 ca: Add missing template instances for VxWorks 5.5.x 2013-07-10 14:55:34 -05:00
Andrew Johnson
75a5f19d2e IOCS_APPL_TOP must be absolute path
Fix a recently introduced problem where cdCommands and envParams
had TOP as a relative path (which actually worked by chance).
Also fixed a problem with convertRelease hanging when the -t
argument matched the absolute path to TOP.
2013-07-10 14:13:31 -05:00
Andrew Johnson
98deef5004 configure: Added FULLPATHNAME tool variable
Changed os/CONFIG files where we use the fullPathName.pl script.
2013-07-10 14:07:51 -05:00
Andrew Johnson
c187d8c13a CAref: typo's, added missing ca_put_callback 2013-07-05 13:26:26 -05:00
Andrew Johnson
1289f99e30 rec: Additional dependencies for parallel builds. 2013-06-21 10:36:26 -05:00
Andrew Johnson
ef5d88d3e5 libCom: Back-ported aToIPAddr fix from 3.15 branch.
Cherry-picked 3.15 revno 12398 with some changes.
2013-06-07 17:03:55 -05:00
Andrew Johnson
93449dccb8 ca: Fix acctst.c for older C compilers
All declarations must still precede other statements within a block...
2013-06-07 16:08:57 -05:00
Andrew Johnson
863e8fdd3b libCom: Fix VxWorks localtime_r() and gmtime_r() wrappers
Wind River changed the return value between VxWorks 6.8 and 6.9.
2013-06-07 14:35:45 -05:00
Andrew Johnson
ee9c0ba409 ca: Minor reference manual tweaks. 2013-05-28 15:07:33 -05:00
Andrew Johnson
7f82c2f32e libCom: Added osi/os/WIN32/osdFindSymbol.c
Implemented by Dirk Zimoch.
2013-05-28 14:16:22 -05:00
Jeff Hill johill@lanl.gov
e0bc071de3 merged in fix for https://bugs.launchpad.net/epics-base/+bug/1179642
also merged in removal of c++ support for old HPUX compiler
2013-05-16 12:33:31 -06:00
Andrew Johnson
593e313fab dbStatic: More commands accept "" or "*" to mean 'all'
dbDumpRecordType, dbDumpMenu and dbDumpRecord commands improved.
2013-05-09 15:48:49 -05:00
Andrew Johnson
34744264e1 libCom: Fix win32 handle leak
Closing an epicsThread would leak one Win32 handle.
Reported by Giles Knap, Diamond.
2013-05-06 17:29:10 -05:00
Andrew Johnson
5ac686fafd tools: Munch support for module destructors
Added in VxWorks 6.9
2013-04-25 17:00:36 -05:00
Andrew Johnson
7e347b2de9 libCom: Fix sysAtReboot registration on vxWorks 6.8+
Removed C++ static constructor, do it from epicsThreadInit()
2013-04-24 12:52:05 -05:00
Andrew Johnson
5bc15b72a1 libCom: Add some missing #include guards.
There are still quite a few missing in libCom/osi/os/*
2013-04-11 12:56:56 -05:00
Andrew Johnson
880db9d4af configure: Set IOCS_APPL_TOP from INSTALL_LOCATION
Fixes lp:1165257
2013-04-09 12:39:26 -05:00
Andrew Johnson
58c031238b configure: Modify help rule to use $(DIVIDER)
... in case someone changes it.
2013-04-01 10:03:38 -05:00
Andrew Johnson
f824246baa Add configuration for vxWorks 6.9 builds. 2013-03-29 11:17:09 -05:00
Andrew Johnson
f9a0c82a63 libCom/osi: Resolve bcopyLongs() conflict on vxWorks 6.9 2013-03-28 17:17:41 -05:00
Andrew Johnson
a4edc46a5f dbStatic: Allow empty DB & DBD files
They used to cause a Syntax error with a bad context string.
2013-03-20 16:53:10 -05:00
Andrew Johnson
738b8ca55f libCom: Add a High-Resolution Time Provider on MacOS
Since Apple don't support clock_gettime(CLOCK_REALTIME) I added a
new time provider that uses the Mach kernel Clock service to get
nanosecond resolution time.
2013-03-13 14:48:34 -05:00
Andrew Johnson
c767958539 gdd: Build tweaks
Remove obselete HPUX warning flags
Disable strict-aliasing to suppress warnings (RTEMS, Linux)
2013-02-11 17:49:05 -06:00
Andrew Johnson
8400e74606 Fix epicsRingPointerGetSize()
Definition name didn't match declaration.

Fixes lp:1109785 reported by Martin Konrad.
2013-01-29 18:02:51 -06:00
Andrew Johnson
451c4cc854 Unify #! line for Perl scripts
/usr/bin/env exists on all current workstation OSs.
2013-01-23 07:29:07 -06:00
Andrew Johnson
038a1140f4 Fix drift in periodic scan times.
Method from Eric Norum, with warnings added by me.

Fixes lp:597054
2013-01-09 18:12:30 -06:00
Jeff Hill
89d000be08 fixed problems with ca clear channel protocol during reload of the access security file.
See https://bugs.launchpad.net/epics-base/+bug/1091401.
2012-12-18 14:32:12 -07:00
Janet Anderson
a0798939b3 R3.14.13.3-DEV 2012-12-17 14:24:23 -06:00
Janet Anderson
a5999242b0 Creating R3.14.12.3 2012-12-17 14:13:19 -06:00
Janet Anderson
9e484306d6 Creating R3.14.12.3 2012-12-17 14:11:47 -06:00
Andrew Johnson
835199a45d RTEMS: Bump the version number
Also show the other COMMANDLINE_LIBRARY choices.
2012-12-13 15:52:06 -06:00
Andrew Johnson
0df6f849d6 Document another Launchpad bug fix from Jeff 2012-12-13 15:50:44 -06:00
Jeff Hill
75e32c9086 fix for https://bugs.launchpad.net/epics-base/+bug/1090009 2012-12-13 09:35:18 -07:00
Ralph Lange
b7018dd16d ca: Fix bug in "Firewalls" section of Channel Access reference manual 2012-12-11 23:38:42 +01:00
Janet Anderson
3498a6d4e0 Update readline libraries and dont have readline the default 2012-12-05 15:02:26 -06:00
Janet Anderson
f90f021309 Added SHRLIB_PERMISSIONS 2012-12-05 14:34:18 -06:00
Andrew Johnson
c1203076f2 Release Notes update
Mark Rivers asked for documentation on the new
workstation OS stack sizes.
2012-12-04 11:15:41 -06:00
Andrew Johnson
753622315c Set snapshot to 3.14.12.3-rc1-DEV 2012-12-03 16:41:53 -06:00
Andrew Johnson
910ab38af6 Creating 3.14.12.3-rc1 2012-12-03 16:39:27 -06:00
Andrew Johnson
0e990bbe0c Update release notes. 2012-12-03 13:34:27 -06:00
Andrew Johnson
ef5688f8de libCom: Accept hex literals in CALC expressions
Code back-ported from the 3.15 branch.
2012-12-03 12:58:26 -06:00
Andrew Johnson
d622bbad05 Fix compiler warnings on linux-x86 2012-12-03 12:48:11 -06:00
Janet Anderson
416cf68fd1 Make target not first prerequisite depend on Makefile. 2012-12-03 09:33:08 -06:00
Andrew Johnson
cbde3ea9fd cas: Added propertyEventMask support
Allows server tools to send DBE_PROPERTY events to clients.
New functionality not tested, but fairly trivial and doesn't
break existing server tools.
2012-11-30 17:42:47 -06:00
Andrew Johnson
6f9c2db8a8 libCom: Revert 12374 which breaks MSVC++ builds
Both the Microsoft 2008 and 2010 compilers fail with this change.
2012-11-30 13:32:25 -06:00
Andrew Johnson
01276d952f ca: Build caRepeater etc. by default
Exceptions for vxWorks, RTEMS and iOS which don't support
executable programs like the workstation OSs.
2012-11-26 15:37:54 -06:00
Andrew Johnson
809633d698 Set snapshot to 3.14.12.3-pre1-DEV 2012-11-19 15:04:58 -06:00
225 changed files with 3679 additions and 2529 deletions

View File

@@ -1,17 +1,13 @@
#*************************************************************************
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
# National Laboratory.
# Copyright (c) 2002 The Regents of the University of California, as
# Operator of Los Alamos National Laboratory.
# EPICS BASE Versions 3.13.7
# and higher are distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
# EPICS BASE is distributed subject to a Software License Agreement found
# in the file LICENSE that is included with this distribution.
#*************************************************************************
#
# $Revision-Id$
#
# The developer may edit this file.
# assume T_A is the host arch if not specified
#
# Common build definitions
@@ -89,8 +85,6 @@ endif
-include $(CONFIG)/os/CONFIG_SITE.Common.$(T_A)
-include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
endif
# Include <top>/cfg/CONFIG* definitions from tops defined in RELEASE* files
#
ifneq ($(CONFIG),$(TOP)/configure)
@@ -103,12 +97,12 @@ endif
# Include $(INSTALL_CFG)/CONFIG* definitions
#
ifndef T_A
TOP_CFG_CONFIGS = $(wildcard $(INSTALL_CFG)/CONFIG*)
ifneq ($(TOP_CFG_CONFIGS),)
include $(TOP_CFG_CONFIGS)
endif
endif
endif # ifdef T_A
# User specific definitions
#
@@ -119,22 +113,3 @@ ifdef T_A
-include $(HOME)/configure/CONFIG_USER.$(EPICS_HOST_ARCH).$(T_A)
endif
# All options
# may be overridden here.
#
# EXAMPLES
# --------
# Build client objects statically ? must be either YES or NO
#STATIC_BUILD=NO
# Host build optimization, must be either YES or NO
#HOST_OPT=YES
# Cross build optimization, must be either YES or NO
#CROSS_OPT=YES
# Generate Verbose Compiler Warnings for host build, must be either YES or NO
#HOST_WARN=YES
# Generate Verbose Compiler Warnings for cross compile builds, must be either YES or NO
#CROSS_WARN=YES
#etc.
#CROSS_COMPILER_TARGET_ARCHS=vxWorks-68040

View File

@@ -63,7 +63,8 @@ DBEXPAND = $(call PATH_FILTER, $(TOOLS)/dbExpand$(HOSTEXE))
DBTORECORDTYPEH = $(call PATH_FILTER, $(TOOLS)/dbToRecordtypeH$(HOSTEXE))
DBTOMENUH = $(call PATH_FILTER, $(TOOLS)/dbToMenuH$(HOSTEXE))
REGISTERRECORDDEVICEDRIVER = $(PERL) $(TOOLS)/registerRecordDeviceDriver.pl
CONVERTRELEASE=$(PERL) $(TOOLS)/convertRelease.pl
CONVERTRELEASE = $(PERL) $(TOOLS)/convertRelease.pl
FULLPATHNAME = $(PERL) $(TOOLS)/fullPathName.pl
#-------------------------------------------------------
# tools for installing libraries and products

View File

@@ -30,11 +30,11 @@ EPICS_MODIFICATION = 12
# EPICS_PATCH_LEVEL must be a number (win32 resource file requirement)
# Not included if zero
EPICS_PATCH_LEVEL = 3
EPICS_PATCH_LEVEL = 4
# This will end in -DEV between official releases
#EPICS_DEV_SNAPSHOT=-DEV
EPICS_DEV_SNAPSHOT=-pre1
#EPICS_DEV_SNAPSHOT=-pre1
#EPICS_DEV_SNAPSHOT=-pre1-DEV
#EPICS_DEV_SNAPSHOT=-pre2
#EPICS_DEV_SNAPSHOT=-pre2-DEV
@@ -42,7 +42,7 @@ EPICS_DEV_SNAPSHOT=-pre1
#EPICS_DEV_SNAPSHOT=-rc1-DEV
#EPICS_DEV_SNAPSHOT=-rc2
#EPICS_DEV_SNAPSHOT=-rc2-DEV
#EPICS_DEV_SNAPSHOT=
EPICS_DEV_SNAPSHOT=
# No changes should be needed below here

View File

@@ -76,9 +76,12 @@ INSTALL_DB = $(INSTALL_LOCATION)/db
INSTALL_CONFIG = $(INSTALL_LOCATION)/configure
INSTALL_JAVA = $(INSTALL_LOCATION)/javalib
#Directory for OS independant build created files
# Directory for OS independant build created files
COMMON_DIR = ../O.Common
# IOC's absolute path to $(TOP), may be overridden inside the application
IOCS_APPL_TOP = $(shell $(FULLPATHNAME) $(INSTALL_LOCATION))
#-------------------------------------------------------
# Make echo output - suppress echoing if make's '-s' flag is set
NOP = :
@@ -371,6 +374,7 @@ INSTALL_LIB_INSTALLS = $(addprefix $(INSTALL_LIB)/,$(notdir $(LIB_INSTALLS)))
# Installed file permissions
BIN_PERMISSIONS = 555
LIB_PERMISSIONS = 444
SHRLIB_PERMISSIONS = 555
INSTALL_PERMISSIONS = 444
#---------------------------------------------------------------

View File

@@ -1,10 +1,10 @@
#*************************************************************************
# Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
# National Laboratory.
# Copyright (c) 2002 The Regents of the University of California, as
# Operator of Los Alamos National Laboratory.
# EPICS BASE is distributed subject to a Software License Agreement found
# in the file LICENSE that is included with this distribution.
# in the file LICENSE that is included with this distribution.
#*************************************************************************
# $Revision-Id$
#
@@ -12,7 +12,7 @@
#
# --------------------------------------------------------------
# Module developers can now define a new type of file, e.g. ABC,
# Module developers can now define a new type of file, e.g. ABC,
# so that files of type ABC will be installed into a directory
# defined by INSTALL_ABC. This is done by creating a new CONFIG<name>
# file, e.g. CONFIG_ABC, with the following lines:
@@ -24,8 +24,14 @@
# $(INSTALL_LOCATION). The file type ABC should be target
# architecture independent (alh files, medm files, edm files).
#
# Optional rules necessary for files of type ABC should be put in
# a RULES_ABC file.
# Files of type ABC are then installed into the INSTALL_ABC
# directory by adding a line like the following to a Makefile.
#
# ABC += <filename1> <filename2> <filename3>
#
# Rules necessary to create files of type ABC should be put in
# a RULES_ABC file. Variables used by those rules should appear
# in a CONFIG_ABC file.
#
# The module developer installs new CONFIG* or RULES* files
# into the directory $(INSTALL_LOCATION)/cfg by including the
@@ -33,16 +39,11 @@
#
# CFG += CONFIG_ABC RULES_ABC
#
# Files of type ABC are installed into INSTALL_ABC directory
# by adding a line like the following to a Makefile.
#
# ABC += <filename1> <filename2> <filename3>
#
# Files in $(INSTALL_LOCATION)/cfg directory are now included by
# the base config files so the definitions and rules are available
# for use by later src directory Makefiles in the same module or
# by other modules with a RELEASE line pointing to the TOP of
# the module with RULES_ABC.
# CONFIG and RULES files in the $(INSTALL_LOCATION)/cfg directory
# are included by the Base config files so their definitions and
# rules are available for use by later src directory Makefiles in
# the same module, or by other modules with a RELEASE line that
# points to the TOP of the module providing these files.
FILE_TYPE += ADL
INSTALL_ADL = $(INSTALL_LOCATION)/adl
@@ -59,6 +60,6 @@ INSTALL_EDL = $(INSTALL_LOCATION)/edl
FILE_TYPE += PERL_MODULES
INSTALL_PERL_MODULES = $(INSTALL_LOCATION_LIB)/perl
INSTALLS_CFG= $(CFG:%= $(INSTALL_CFG)/%)
INSTALLS_CFG = $(CFG:%= $(INSTALL_CFG)/%)
DIRECTORY_TARGETS += $(foreach type, $(FILE_TYPE),$(INSTALL_$(type)))

View File

@@ -19,6 +19,7 @@
# aix-ppc (IBM compiler used for host builds)
# aix-ppc-gnu (GNU compiler used for host builds)
# cygwin-x86 (cygwin compiler used for host builds)
# cygwin-x86_64 (cygwin compiler used for host builds)
# darwin-ppc (PowerPC based Apple running OSX)
# darwin-ppcx86 (Universal binaries for both CPUs)
# darwin-x86 (Intel based Apple running OSX)
@@ -41,6 +42,7 @@
# win32-x86-cygwin (WIN32 API with cygwin GNU compiler used for host builds)
# win32-x86-mingw (MinGW compiler used for host builds)
# windows-x64 (MS Visual C++ compiler used for host builds)
# windows-x64-mingw (MinGW compiler used for host builds)
# Debugging builds
# linux-x86-debug (GNU compiler with -g option for host builds)
@@ -72,6 +74,7 @@
# linux-cris (Axis GNU crosscompiler on linux-x86 host)
# linux-cris_v10 (Axis GNU crosscompiler on linux-x86 host)
# linux-cris_v32 (Axis GNU crosscompiler on linux-x86 host)
# linux-microblaze
# linux-xscale_be
# vxWorks-486
# vxWorks-68040
@@ -119,9 +122,9 @@ CROSS_COMPILER_HOST_ARCHS=
# NOTE: os/CONFIG.$(EPICS_HOST_ARCH).$(EPICS_HOST_ARCH) files and
# os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(EPICS_HOST_ARCH) files may override
#
# NOTE WIN32: YES results in a DLL. Valid settings are
# SHARED_LIBRARIES=YES and STATIC_BUILD=NO
# SHARED_LIBRARIES=NO and STATIC_BUILD=YES
# NOTE Windows: YES results in a DLL. Valid settings are
# SHARED_LIBRARIES=YES and STATIC_BUILD=NO
# SHARED_LIBRARIES=NO and STATIC_BUILD=YES
#
SHARED_LIBRARIES=YES

View File

@@ -228,7 +228,7 @@ $(COMMON_DIR)/%Record.h: $(COMMON_DIR)/%Record.dbd
$(COMMON_DIR)/%Record.h: %Record.dbd
@$(RM) $(notdir $@)$(DEP)
@$(DBDDEPENDS_CMD)
echo "$< : ../Makefile" >> $(notdir $@)$(DEP)
echo "$@ : ../Makefile" >> $(notdir $@)$(DEP)
@$(RM) $(notdir $@)
$(DBTORECORDTYPEH) $(DBDFLAGS) $< $(notdir $@)
@$(MV) $(notdir $@) $@
@@ -244,7 +244,7 @@ $(COMMON_DIR)/menu%.h: $(COMMON_DIR)/menu%.dbd
$(COMMON_DIR)/menu%.h: menu%.dbd
@$(RM) $(notdir $@)$(DEP)
@$(DBDDEPENDS_CMD)
echo "$< : ../Makefile" >> $(notdir $@)$(DEP)
echo "$@ : ../Makefile" >> $(notdir $@)$(DEP)
@$(RM) $(notdir $@)
$(DBTOMENUH) $(DBDFLAGS) $< $(notdir $@)
@$(MV) $(notdir $@) $@
@@ -269,7 +269,7 @@ $(COMMON_DIR)/%.dbd: $(COMMON_DIR)/%Include.dbd
$(COMMON_DIR)/%.dbd: %Include.dbd
@$(RM) $(notdir $@)$(DEP)
@$(DBDDEPENDS_CMD)
echo "$< : ../Makefile" >> $(notdir $@)$(DEP)
echo "$@ : ../Makefile" >> $(notdir $@)$(DEP)
$(ECHO) "Expanding dbd"
@$(RM) $(notdir $@)
$(DBEXPAND) $(DBDFLAGS) -o $(notdir $@) $<
@@ -368,17 +368,14 @@ $(foreach file, $(DB_INSTALLS), $(eval $(call DB_INSTALLS_template, $(file))))
##################################################### register record,device,driver support
IOC_INST_TOP := $(firstword $(IOCS_APPL_TOP) \
$(shell $(PERL) $(TOOLS)/fullPathName.pl $(INSTALL_LOCATION) ) )
%_registerRecordDeviceDriver.cpp: $(COMMON_DIR)/%.dbd
@$(RM) $@ $*.tmp
$(REGISTERRECORDDEVICEDRIVER) $< $(basename $@) $(IOC_INST_TOP) > $*.tmp
$(REGISTERRECORDDEVICEDRIVER) $< $(basename $@) $(IOCS_APPL_TOP) > $*.tmp
$(MV) $*.tmp $@
%_registerRecordDeviceDriver.cpp: %.dbd
@$(RM) $@ $*.tmp
$(REGISTERRECORDDEVICEDRIVER) $< $(basename $@) $(IOC_INST_TOP) > $*.tmp
$(REGISTERRECORDDEVICEDRIVER) $< $(basename $@) $(IOCS_APPL_TOP) > $*.tmp
$(MV) $*.tmp $@
.PRECIOUS: %_registerRecordDeviceDriver.cpp

View File

@@ -1,13 +1,13 @@
#*************************************************************************
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
# National Laboratory.
# Copyright (c) 2002 The Regents of the University of California, as
# Operator of Los Alamos National Laboratory.
# EPICS BASE Versions 3.13.7
# and higher are distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
# EPICS BASE is distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
#*************************************************************************
#RULES.ioc
include $(CONFIG)/RULES_DIRS
build$(DIVIDER)$(ARCH) build: buildInstall
@@ -15,23 +15,18 @@ install$(DIVIDER)$(ARCH) install: buildInstall
$(ARCH): buildInstall
ifeq ($(filter $(ARCH),$(BUILD_ARCHS)),$(ARCH))
buildInstall$(DIVIDER)$(ARCH) buildInstall: $(TARGETS)
buildInstall$(DIVIDER)$(ARCH) buildInstall: $(TARGETS)
clean$(DIVIDER)$(ARCH) clean:
clean$(DIVIDER)$(ARCH) clean:
$(RM) cdCommands envPaths dllPath.bat
else
buildInstall$(DIVIDER)$(ARCH) buildInstall:
clean$(DIVIDER)$(ARCH) clean:
else
buildInstall$(DIVIDER)$(ARCH) buildInstall:
clean$(DIVIDER)$(ARCH) clean:
endif
cdCommands envPaths dllPath.bat: $(wildcard $(TOP)/configure/RELEASE*) \
$(TOP)/configure/CONFIG $(INSTALL_BIN)
ifeq ($(IOCS_APPL_TOP),)
$(PERL) $(TOOLS)/convertRelease.pl -a $(ARCH) $@
else
$(PERL) $(TOOLS)/convertRelease.pl -a $(ARCH) -t $(IOCS_APPL_TOP) $@
endif
$(wildcard $(TOP)/configure/CONFIG_SITE*) $(INSTALL_BIN)
$(CONVERTRELEASE) -a $(ARCH) -t $(IOCS_APPL_TOP) $@
realclean:
$(RM) cdCommands envPaths dllPath.bat

View File

@@ -383,7 +383,7 @@ $(INSTALL_LIB)/%.lib: %.lib
$(INSTALL_SHRLIBS): $(INSTALL_SHRLIB)/%: %
$(ECHO) "Installing shared library $@"
@$(INSTALL_LIBRARY) -d -m $(LIB_PERMISSIONS) $< $(INSTALL_SHRLIB)
@$(INSTALL_LIBRARY) -d -m $(SHRLIB_PERMISSIONS) $< $(INSTALL_SHRLIB)
ifneq ($(SHRLIB_SUFFIX),$(SHRLIB_SUFFIX_BASE))
ifneq (,$(strip $(SHRLIB_VERSION)))
@$(RM) $(subst $(SHRLIB_SUFFIX),$(SHRLIB_SUFFIX_BASE),$@)

View File

@@ -1,10 +1,10 @@
#*************************************************************************
# Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne
# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
# National Laboratory.
# Copyright (c) 2002 The Regents of the University of California, as
# Operator of Los Alamos National Laboratory.
# EPICS BASE is distributed subject to a Software License Agreement found
# in the file LICENSE that is included with this distribution.
# in the file LICENSE that is included with this distribution.
#*************************************************************************
# $Revision-Id$
#
@@ -36,13 +36,11 @@ endif
endif
#---------------------------------------------
# Include existing and new $(INSTALL_CFG)/* definitions
# Include our own $(INSTALL_CFG)/RULES* definitions
#
TOP_CFG_FILES = $(sort $(wildcard $(INSTALL_CFG)/RULES*) \
$(wildcard $(INSTALL_CFG)/CONFIG*) \
$(addprefix $(INSTALL_CFG)/,$(CFG)))
ifneq ($(TOP_CFG_FILES),)
include $(TOP_CFG_FILES)
TOP_CFG_RULES = $(wildcard $(INSTALL_CFG)/RULES*)
ifneq ($(TOP_CFG_RULES),)
include $(TOP_CFG_RULES)
endif
#---------------------------------------------------------------

0
configure/RULES_TARGET Executable file → Normal file
View File

View File

@@ -64,11 +64,11 @@ help:
@echo " rebuild - Same as clean install"
@echo " archclean - Removes O.<arch> dirs but not O.Common dir"
@echo "\"Partial\" build targets supported by Makefiles:"
@echo " inc.<arch> - Installs <arch> only header files."
@echo " build.<arch> - Builds and installs <arch> only."
@echo " install.<arch> - Builds and installs <arch> only."
@echo " clean.<arch> - Cleans <arch> binaries in O.<arch> dirs only."
@echo " uninstall.<arch> - Remove bin & lib directories for <arch> only."
@echo " inc$(DIVIDER)<arch> - Installs <arch> only header files."
@echo " build$(DIVIDER)<arch> - Builds and installs <arch> only."
@echo " install$(DIVIDER)<arch> - Builds and installs <arch> only."
@echo " clean$(DIVIDER)<arch> - Cleans <arch> binaries in O.<arch> dirs only."
@echo " uninstall$(DIVIDER)<arch> - Remove bin & lib directories for <arch> only."
@echo "Targets supported by top level Makefile:"
@echo " archuninstall - Remove bin & lib directories created by this hostarch."
@echo " uninstall - Remove install directories created by this hostarch."

0
configure/Sample.Makefile Executable file → Normal file
View File

View File

@@ -50,7 +50,7 @@ SHRLIB_LDLIBS = $(addprefix -l, $($*_LDLIBS) $(LIB_LIBS) $(USR_LIBS))\
$(LDLIBS)
SHRLIB_DEPLIB_DIRS = $(foreach word,$(sort $(dir $($*_DEPLIBS) $(SHRLIB_DEPLIBS))), \
$(shell $(PERL) $(TOOLS)/fullPathName.pl $(word)))
$(shell $(FULLPATHNAME) $(word)))
SHRLIBDIR_LDFLAGS += $(SHRLIB_DEPLIB_DIRS:%=-L%)
@@ -73,7 +73,7 @@ PROD_LDLIBS += $($(firstword $(LDLIBS_STATIC_$(STATIC_BUILD)) \
$(LDLIBS_SHARED_$(SHARED_LIBRARIES))))
PROD_DEPLIB_DIRS = $(foreach word,$(sort $(dir $($*_DEPLIBS) $(PROD_DEPLIBS))), \
$(shell $(PERL) $(TOOLS)/fullPathName.pl $(word)))
$(shell $(FULLPATHNAME) $(word)))
PRODDIR_LDFLAGS += $(PROD_DEPLIB_DIRS:%=-L%)

View File

@@ -14,7 +14,7 @@ OS_CLASS = cygwin32
ARCH_CLASS = x86
# Definitions used when COMMANDLINE_LIBRARY is READLINE
LDLIBS_READLINE = -lreadline -lcurses
LDLIBS_READLINE = -lreadline
POSIX_CPPFLAGS = -D_POSIX_THREADS -D_POSIX_TIMERS
#POSIX_CPPFLAGS += -D_POSIX_SOURCE

View File

@@ -0,0 +1,14 @@
# CONFIG.Common.cygwin-x86_64
#
# $Revision-Id$
# This file is maintained by the build community.
#
# Definitions for cygwin-x86_64 target builds
# Sites may override these definitions in CONFIG_SITE.Common.cygwin-x86_64
#-------------------------------------------------------
include $(CONFIG)/os/CONFIG.Common.cygwin-x86
ARCH_DEP_CFLAGS = -m64
ARCH_DEP_LDFLAGS = -m64

View File

@@ -73,7 +73,7 @@ OP_SYS_LDFLAGS += -dynamic -Z -L$(SDK_DIR)/usr/lib -L$(SDK_DIR)/usr/lib/system
# Shared libraries
SHRLIB_VERSION = $(EPICS_VERSION).$(EPICS_REVISION).$(EPICS_MODIFICATION)
SHRLIB_LDFLAGS = -dynamiclib -flat_namespace -undefined suppress \
-install_name $(shell $(PERL) $(TOOLS)/fullPathName.pl $(INSTALL_LIB))/$@ \
-install_name $(shell $(FULLPATHNAME) $(INSTALL_LIB))/$@ \
-compatibility_version $(EPICS_VERSION).$(EPICS_REVISION) \
-current_version $(SHRLIB_VERSION)
SHRLIB_SUFFIX_BASE = .dylib

View File

@@ -93,6 +93,7 @@ VX_GNU_VERSION_6.5 = 3.4.4
VX_GNU_VERSION_6.6 = 4.1.2
VX_GNU_VERSION_6.7 = 4.1.2
VX_GNU_VERSION_6.8 = 4.1.2
VX_GNU_VERSION_6.9 = 4.3.3
VX_GNU_VERSION = $(VX_GNU_VERSION_$(VXWORKS_VERSION))
VX_GNU_MAJOR_VERSION = $(basename $(basename $(VX_GNU_VERSION)))
@@ -134,6 +135,7 @@ NM_DIR_6.5 = $(WORKBENCH_BIN)
NM_DIR_6.6 = $(WORKBENCH_BIN)
NM_DIR_6.7 = $(GNU_BIN)
NM_DIR_6.8 = $(UTILITIES_BIN)
NM_DIR_6.9 = $(UTILITIES_BIN)
NM_DIR = $(firstword $(NM_DIR_$(VXWORKS_VERSION)) $(GNU_BIN))
NM = $(NM_DIR)/$(CMPLR_PREFIX)nm$(CMPLR_SUFFIX)$(HOSTEXE)

View File

@@ -0,0 +1,15 @@
# CONFIG.Common.windows-x64-mingw
#
# $Revision-Id$
# This file is maintained by the build community.
#
# Definitions for windows-x64-mingw target builds
# Sites may override these definitions in CONFIG_SITE.Common.windows-x64-mingw
#-------------------------------------------------------
include $(CONFIG)/os/CONFIG.Common.win32-x86-mingw
ARCH_CLASS = x64
ARCH_DEP_CFLAGS = -m64
ARCH_DEP_LDFLAGS = -m64

View File

@@ -0,0 +1,10 @@
# CONFIG.cygwin-x86_64.Common
#
# $Revision-Id$
# This file is maintained by the build community.
#
# Definitions for cygwin-x86_64 host archs
# Sites may override these definitions in CONFIG_SITE.cygwin-x86_64.Common
#-------------------------------------------------------
include $(CONFIG)/os/CONFIG.cygwin-x86.Common

View File

@@ -0,0 +1,11 @@
# CONFIG.cygwin-x86_64.cygwin-x86_64
#
# $Revision-Id$
#
# Definitions for cygwin-x86_64 host - cygwin-x86_64 target builds
# Sites may override these definitions in CONFIG_SITE.cygwin-x86_64.cygwin-x86_64
#-------------------------------------------------------
# Include common gnu compiler definitions
include $(CONFIG)/os/CONFIG.cygwin-x86.cygwin-x86

View File

@@ -59,15 +59,17 @@ COMMANDLINE_LIBRARY=READLINE
GNU_DIR = /usr
CC = $(GNU_BIN)/cc
CCC = $(GNU_BIN)/c++
# Apple soft-links these compilers to clang/clang++
CC = cc
CCC = c++
GNU = NO
#
# Darwin shared libraries
#
SHRLIB_VERSION = $(EPICS_VERSION).$(EPICS_REVISION).$(EPICS_MODIFICATION)
SHRLIB_LDFLAGS = -dynamiclib -flat_namespace -undefined suppress \
-install_name $(shell $(PERL) $(TOOLS)/fullPathName.pl $(INSTALL_LIB))/$@ \
-install_name $(shell $(FULLPATHNAME) $(INSTALL_LIB))/$@ \
-compatibility_version $(EPICS_VERSION).$(EPICS_REVISION) \
-current_version $(SHRLIB_VERSION)
SHRLIB_SUFFIX_BASE = .dylib

View File

@@ -9,14 +9,15 @@
# Include common gnu compiler definitions
include $(CONFIG)/CONFIG.gnuCommon
# gcc, g++, ar, ld, and ranlib must be in user's path
CC = gcc
CCC = g++
AR = ar -rc
LD = ld -r
RANLIB = ranlib
RES=.coff
RCCMD = windres $(INCLUDES) $< $@
CMPLR_PREFIX =
CC = $(CMPLR_PREFIX)gcc
CCC = $(CMPLR_PREFIX)g++
AR = $(CMPLR_PREFIX)ar -rc
LD = $(CMPLR_PREFIX)ld -r
RANLIB = $(CMPLR_PREFIX)ranlib
RES = .coff
RCCMD = $(CMPLR_PREFIX)windres $(INCLUDES) $< $@
# No -fPIC avoids "-fPIC ignored for target (all code is position independent)"
SHRLIB_CFLAGS =
@@ -26,4 +27,4 @@ LOADABLE_SHRLIB_LDFLAGS = -shared -Wl,--out-implib,$(LIB_PREFIX)$*$(LIB_SUFFIX)
# Override linking with gcc library from CONFIG.gnuCommon
GNU_LDLIBS_YES =
OP_SYS_LDLIBS = -lws2_32
OP_SYS_LDLIBS = -lws2_32

View File

@@ -0,0 +1,11 @@
# CONFIG.windows-x64-mingw.Common
#
# $Revision-Id$
# This file is maintained by the build community.
#
# Definitions for windows-x64-mingw host archs
# Sites may override these definitions in CONFIG_SITE.windows-x64-mingw.Common
#-------------------------------------------------------
include $(CONFIG)/os/CONFIG.win32-x86-mingw.Common

View File

@@ -0,0 +1,11 @@
# CONFIG.windows-x64-mingw.windows-x64-mingw
#
# $Revision-Id$
# This file is maintained by the build community.
#
# Definitions for windows-x64-mingw target archs
# Sites may override these definitions in CONFIG_SITE.windows-x64-mingw.windows-x64-mingw
#-------------------------------------------------------
# Include common gnu compiler definitions
include $(CONFIG)/os/CONFIG.win32-x86-mingw.win32-x86-mingw

View File

@@ -5,21 +5,22 @@
# Where to find RTEMS
#
RTEMS_VERSION=4.9.2
RTEMS_BASE=/usr/local/rtems/rtems-$(RTEMS_VERSION)
RTEMS_VERSION = 4.10.2
RTEMS_BASE = /usr/local/rtems/rtems-$(RTEMS_VERSION)
# Cross-compile toolchain in $(RTEMS_TOOLS)/bin
#
RTEMS_TOOLS=$(RTEMS_BASE)
RTEMS_TOOLS = $(RTEMS_BASE)
# If you're using neither BOOTP/DHCP nor FLASH to pick up your IOC
# network configuration you must uncomment and specify your Internet
# network configuration you must uncomment and specify your Internet
# Domain Name here
#
#OP_SYS_CFLAGS += -DRTEMS_NETWORK_CONFIG_DNS_DOMAINNAME=<domainname>
#
# Specify your desired command-line-input library
# Select the command-line-input library to use
#
COMMANDLINE_LIBRARY = EPICS
#COMMANDLINE_LIBRARY = LIBTECLA
#COMMANDLINE_LIBRARY = READLINE

View File

@@ -7,4 +7,7 @@
# If readline is installed uncomment the following line
# to add command-line editing and history support
COMMANDLINE_LIBRARY = READLINE
#COMMANDLINE_LIBRARY = READLINE
# Uncomment the following line if readline has problems
#LDLIBS_READLINE= -lreadline -lcurses

View File

@@ -0,0 +1,14 @@
# CONFIG_SITE.Common.cygwin-x86_64
#
# $Revision-Id$
#
# Site Specific definitions for cygwin-x86_64 target
# Only the local epics system manager should modify this file
# If readline is installed uncomment the following line
# to add command-line editing and history support
#COMMANDLINE_LIBRARY = READLINE
# Uncomment the following line if readline has problems
#LDLIBS_READLINE = -lreadline -lcurses

View File

@@ -14,19 +14,19 @@ ARCH_CLASS = x86_64
#ARCH_CLASS = i386 x86_64
#
# Comment out the following 3 lines to build with Apple's GCC instead of CLANG.
# Uncomment the following 3 lines to build with Apple's GCC instead of CLANG.
#
CC = clang
CCC = clang++
GNU = NO
#CC = gcc
#CCC = g++
#GNU = YES
# To use MacPorts GCC, comment out ALL the settings above this line,
# then uncomment (and modify if necessary) the following instead:
# To use MacPorts GCC uncomment (and modify if necessary) the following:
#GNU_DIR = /opt/local
#CC = $(GNU_BIN)/gcc -m64
#CCC = $(GNU_BIN)/g++ -m64
#GNU = YES
# If you see this or similar errors while building in the src/cap5 directory
# gcc: error: unrecognized option '-no-cpp-precomp'

View File

@@ -16,11 +16,16 @@
#
# Xcode 4.5 dropped support for the ARMv6.
#
# ARMv7s devices: iPhone 5
# ARMv8 (arm64) devices: iPhone 5S
# ARMv7s devices: iPhone 5 and 5C, iPad Gen 4
# ARMv7 devices: iPhone 3GS, 4 and 4S, iPod Touch Gen 3 to 5
# iPad Gen 1 to 3, iPad Mini, Apple TV Gen 2 and 3
# ARMv6 devices: iPhone 1 and 3G, iPod Touch Gen 1 and 2
# All other devices are ARMv7
ARCH_CLASS = armv7 armv7s
#ARCH_CLASS = arm64
#ARCH_CLASS = armv7s arm64
ARCH_CLASS = armv7 armv7s arm64
#ARCH_CLASS = armv7 armv7s
#ARCH_CLASS = armv7
#ARCH_CLASS = armv6 armv7
#ARCH_CLASS = armv6

View File

@@ -13,11 +13,13 @@
#IOS_VERSION = 4.3
#IOS_VERSION = 5.0
#IOS_VERSION = 5.1
IOS_VERSION = 6.0
#IOS_VERSION = 6.0
#IOS_VERSION = 6.1
IOS_VERSION = 7.0
# Which compiler to use:
# CLANG is preferred for recent versions of Xcode
# CLANG is required for Xcode 5.0 and later
# LLVM_GNU uses the llvm-gcc and llvm-g++ compilers
# GNU is needed for older versions of Xcode

View File

@@ -38,3 +38,4 @@ COMMANDLINE_LIBRARY = READLINE
# This does cost disk space, but not memory as debug symbols are not
# loaded into RAM when the binary is loaded.
OPT_CFLAGS_YES += -g
OPT_CXXFLAGS_YES += -g

View File

@@ -38,3 +38,4 @@ COMMANDLINE_LIBRARY = READLINE
# This does cost disk space, but not memory as debug symbols are not
# loaded into RAM when the binary is loaded.
OPT_CFLAGS_YES += -g
OPT_CXXFLAGS_YES += -g

View File

@@ -20,6 +20,7 @@ VXWORKS_VERSION = 5.5
#VXWORKS_VERSION = 6.6
#VXWORKS_VERSION = 6.7
#VXWORKS_VERSION = 6.8
#VXWORKS_VERSION = 6.9
# Sites may override the following path for a particular host
@@ -40,6 +41,7 @@ WIND_BASE = /usr/local/vw/tornado22-$(ARCH_CLASS)
#WORKBENCH_VERSION = 2.6
#WORKBENCH_VERSION = 3.0
#WORKBENCH_VERSION = 3.2
#WORKBENCH_VERSION = 3.3
# Utilities Version number, required from vxWorks 6.8 and later

View File

@@ -0,0 +1,9 @@
# CONFIG_SITE.windows-x64-mingw.windows-x64-mingw
#
# $Revision-Id$
#
# Site Specific definitions for windows-x64-mingw target
# Only the local epics system manager should modify this file
# Prefix for mingw compiler from cygwin
#CMPLR_PREFIX = x86_64-w64-mingw32-

View File

@@ -3,15 +3,224 @@
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<title>EPICS Base R3.14.12.3-pre1 Release Notes</title>
<title>EPICS Base R3.14.12.4 Release Notes</title>
</head>
<body lang="en">
<h1 align="center">EPICS Base Release 3.14.12.3-pre1</h1>
<h1 align="center">EPICS Base Release 3.14.12.4</h1>
<h2 align="center">Changes between 3.14.12.3 and 3.14.12.4</h2>
<!-- Insert new items immediately below here ... -->
<h3>New test for environment variables</h3>
<p>A new test program epicsEnvTest has been added to the libCom tests which
checks environment variable APIs. It was written to confirm that threads see
environment variable values that have been set in their parent thread. VxWorks
6.x boot images must be configured with ENV_VAR_USE_HOOKS set to FALSE for the
correct behaviour to occur (a test failure on VxWorks explains this).</p>
<h3>Inclusion of &lt;top&gt;/cfg/* files refined</h3>
<p>The way the build system includes files installed in the &lt;top&gt;/cfg/*
directory has been cleaned up. Files whose names begin with CONFIG will now get
included by the CONFIG step, and files whose names begin with RULES will get
included in the RULES step. These files are only ever included when GNUMake is
working in an application build (O.) directory and T_A is defined, so they
cannot be used to create generic build targets at other levels.</p>
<p>Files whose names don't start with either CONFIG or RULES are no longer
included automatically, but such files can still be installed into
&lt;top&gt;/cfg by naming them in the CFG variable.</p>
<h3>Fixed iocsh stream redirection for several commands</h3>
<p>A number of iocsh commands did not respond correctly to redirection of their
output using the iocsh '>file' or '2>error-file' syntax, and redirecting an
empty command could create files with garbage names. There may still be a few
commands that do not properly redirect their output, please notify the core
developers if you discover any. Thanks to Eric Norum for the iocsh changes.</p>
<p>For externally developed commands, the simplest way to support redirection in
your C/C++ code is to <tt>#include "epicsStdioRedirect.h"</tt> instead of
<tt>stdio.h</tt>.</p>
<h3>Fixed crash on loading record instance of unknown type</h3>
<p>Fixed segfault when dbLoadRecords tried to load a record of a type that was
not defined in its DBD files.</p>
<h3>Hex literal support in epicStrtod()</h3>
<p>Some OS implementations of the standard C library routine strtod() do not
recognize hexadecimal integers, in particular the libraries provided on Windows
and VxWorks. The internal implementation of epicsStrtod() that these targets use
now recognizes the 0x prefix and will convert hex numbers correctly. Thanks to
Dirk Zimoch for suggesting this change.</p>
<h3>Added support for 64-bit Cygwin and MinGW targets</h3>
<p>Both windows-x64-mingw and cygwin-x86_64 build targets are now provided.</p>
<h3>Windows build issues</h3>
<p>Thanks to Peter Heesterman for suggesting a number of small changes that
clean up build issues on Windows, mostly related to symbol import and export
to/from DLLs.</p>
<h3>CAS: GDD Reference Count Underflow</h3>
<p>Thanks to Bruce Hill a source of an underflow in a GDD reference count in the
CAS code has been fixed.</p>
<h3>Support for Apple Xcode 5.0</h3>
<p>This adds the ability to build for iOS 7.0 and the ARMv8 64-bit CPU on the
newest iPhone 5S device. Unfortunately the Xcode upgrade breaks the build of the
ios-x86 simulator target, although the ios-arm target successfully builds code
which runs fine on the real hardware.</p>
<h3>Reading TSEL field</h3>
<p>The TSEL link field has two complementary uses; it is read to fetch a
time-stamp event number for the TSE field, or if pointed to the .TIME field of
another record the record's timestamp is copied directly from the target record.
However with the latter usage if the TSEL link is itself read back instead of
pointing to the .TIME field the link appears to have changed to point to the VAL
field. This is due to an internal detail, and makes it impossible to save the
TSEL field's value using autosave. This has been fixed, and now the TSEL field
should always read back the same PV that it was pointed to.</p>
<h3>dbLoadTemplate variable limits adjustable</h3>
<p>The <tt>dbLoadTemplate</tt> command used to allocate a fixed amount of memory
for the template macro values that it used to 5000 bytes, and also limited the
number of variables that could defined to 100. These limits can now be changed
at runtime using the variable <tt>dbTemplateMaxVars</tt> which sets the maximum
number of macro variables that can be used; the amount of memory allocated for
value storage is 50 times this number. This variable is registered as an iocsh
variable in the base.dbd file, and can be adjusted as necessary before each
individual call to <tt>dbLoadTemplate</tt>.</p>
<p>The code now checks for and prevents any attempt to define more than the set
number of variables, but it does not check for overruns of the storage buffer.
This means that template files which define many long macro value strings could
still cause a buffer overflow and crash the IOC at startup, but increasing the
variable is all that is needed to allow that template file to be loaded.</p>
<h3>Improvements to dbpf</h3>
<p>It is now possible to use the <tt>dbpf</tt> command to put a long string
value into a UCHAR array field, previously only CHAR arrays were supported by
this command even though through Channel Access could put a long string to
either type. The error message printed by <tt>dbpf</tt> when a value conversion
fails has also been significantly improved.</p>
<h3>Support for VxWorks 6.9</h3>
<p>Various changes have been made that were needed to allow Base to build and
run properly on VxWorks 6.9.</p>
<h3>Improvements to aToIPAddr()</h3>
<p>The libCom routine aToIPAddr() and the vxWorks implementation of the
associated hostToIPAddr() function have been modified to be able to look up
hostnames that begin with one or more digits. The epicsSockResolveTest program
was added to check this functionality.</p>
<h4>Added osdFindSymbol for Windows</h4>
<p>Dirk Zimoch implemented the epicsLoadLibrary(), epicsLoadError() and
epicsFindSymbol() routines for Windows OS targets.</p>
<h4>More dbStatic commands accept "" or "*" to mean 'all'</h4>
<p>The IOC commands dbDumpRecordType, dbDumpMenu and dbDumpRecord will now
accept either an empty string or any string beginning with an asterisk '*' to
mean all record types or menus. Previously the 'all' option for these commands
required passing in a NULL value, which could be done from the vxWorks shell but
was not possible from iocsh.</p>
<h4>VxWorks sysAtReboot Registration</h4>
<p>The increasing intelligence of the GNU compiler and linker broke the method
that was being used by the VxWorks code to register a reboot hook that can close
down TCP connections nicely before the network stack gets disabled. This has
been fixed and no longer uses a C++ static contructor to execute that code.</p>
<h4>IOCS_APPL_TOP and INSTALL_LOCATION</h4>
<p>An IOC application that sets INSTALL_LOCATION in its configure/CONFIG_SITE
file no longer has to set IOCS_APPL_TOP there as well, unless the IOC uses a
different path than the build host to reach the application's top directory in
its filesystem. The IOCS_APPL_TOP variable now defaults to the value of
INSTALL_LOCATION, so setting the latter automatically sets the former. This
change fixes <a href="https://bugs.launchpad.net/bugs/1165257">Launchpad bug
1165257</a>.</p>
<h4>devLibVME.h</h4>
<p>Moved the declaration of bcopyLongs() from this header into RTEMS/osdVME.h.
Its original location broke the build for vxWorks 6.9 (the int nlongs argument
becomes size_t in 6.9, thus conflicting with this declaration). The only local
implementation of this routine is found in RTEMS/devLibVMEOSD.c, but it is not
used anywhere in Base.</p>
<h4>Allow empty database files</h4>
<p>The IOC used to report an error if dbLoadRecords or dbLoadDatabase was asked
to load an empty file or one containing just whitespace and/or comments. Such
files are now permitted, simplifying the task of automated database generation
programs which might discover they have nothing to output.</p>
<h4>High-Resolution Time Provider on MacOS</h4>
<p>MacOS does not provide the clock_gettime() API with CLOCK_REALTIME that other
Posix systems implement, so we previously used gettimeofday() to fetch the
current date & time from the OS. That older routine only provides the time with
a resolution of 1 microsecond though, whereas clock_gettime() gives results with
a nanosecond resolution. This release uses a new MachTime time provider on
MacOS which uses the Mach Kernel's CALENDAR_CLOCK service to fetch the time, and
provides nanosecond resolution.</p>
<h4>Time drift in periodic scans</h4>
<p>The implementation of the periodic scan code has been modified to remove
long-term drift associated with OS thread sheduling. The new code keeps scan
times much more closely tied to the system clock tick, only allowing the scan
period to drift if the record processing time takes longer to execute than the
interval between scans. If this happens the scan thread is made to wait for an
additional half-period but at most 1 second before the records are scanned
again, to allow lower priority threads some time to process on a preemptive
priority scheduled OS. After 10 repeated over-runs a warning will be logged,
with an increasing delay between messages up to hourly.</p>
<p>This fixes <a href="https://bugs.launchpad.net/bugs/597054">launchpad bug
597054</a>.</p>
<h2 align="center">Changes between 3.14.12.2 and 3.14.12.3</h2>
<!-- Insert new items immediately below here ... -->
<h4>Hex literals in CALC expressions</h4>
<p>In previous releases, CALC expressions could contain hexadecimal literal
integers on a target if the OS implementation of strtod() allows them (the
vxWorks implementation does not). Now hex literal integers can be used in CALC
expressions on all architectures. Hexadecimal floating point literals may have
worked on some architectures in the past, but will no longer be accepted.</p>
<h4>CAS: Added propertyEventMask support</h4>
<p>Server tools should now be able to detect subscriptions to and send updates
for DBE_PROPERTY events, using a casEventMask value returned by the new
caServer::propertyEventMask() method.</p>
<h4>caRepeater now built by default</h4>
<p>Previously caRepeater was only built for host architectures, so builds for
cross-compiled but workstation-type targets like linux-arm did not build it.
Explicit exceptions prevent it being built on architectures like vxWorks, RTEMS
and iOS which do not support normal executable programs.</p>
<h4>Array Subroutine (aSub) record type fixes</h4>
@@ -69,6 +278,9 @@ has trailing whitespace characters.</p>
fixed in this release:</p>
<ul>
<li>1090009
<a href="https://bugs.launchpad.net/bugs/1090009">
osdSufficentSpaceInPoolQuery fails on vxWorks 2 GB system</a></li>
<li>999167
<a href="https://launchpad.net/bugs/999167">
Missing epicsShareFunc for casStatsFetch</a></li>
@@ -82,7 +294,19 @@ fixed in this release:</p>
error</a></li>
<li>903448
<a href="https://launchpad.net/bugs/903448">
RHEL5 nss ldap update cause stack size related failure</a></li>
RHEL5 nss ldap update cause stack size related failure</a>
<p>
This bug fix changed the stack sizes for both Posix and Windows targets as
follows:</p>
<table>
<tr><th>epicsThreadStackSizeClass</th><th>New Stack Size</th></tr>
<tr><td>epicsThreadStackSmall</td>
<td>0x10000 &times; sizeof (void *)</td></tr>
<tr><td>epicsThreadStackMedium</td>
<td>0x20000 &times; sizeof (void *)</td></tr>
<tr><td>epicsThreadStackBig</td>
<td>0x40000 &times; sizeof (void *)</td></tr>
</table></li>
</ul>

0
src/as/asHost.rc Executable file → Normal file
View File

0
src/as/asIoc.rc Executable file → Normal file
View File

View File

@@ -25,8 +25,6 @@
#include "cac.h"
#include "sgAutoPtr.h"
casgRecycle::~casgRecycle () {}
CASG::CASG ( epicsGuard < epicsMutex > & guard, ca_client_context & cacIn ) :
client ( cacIn ), magic ( CASG_MAGIC )
{
@@ -38,12 +36,13 @@ CASG::~CASG ()
}
void CASG::destructor (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
if ( this->verify ( guard ) ) {
this->reset ( guard );
this->reset ( cbGuard, guard );
this->client.uninstallCASG ( guard, *this );
this->magic = 0;
}
@@ -127,36 +126,37 @@ int CASG::block (
delay = cur_time - beg_time;
}
this->reset ( guard );
return status;
}
void CASG::reset (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
this->destroyCompletedIO ( guard );
this->destroyPendingIO ( guard );
this->destroyCompletedIO ( cbGuard, guard );
this->destroyPendingIO ( cbGuard, guard );
}
// lock must be applied
void CASG::destroyCompletedIO (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
syncGroupNotify * pNotify;
while ( ( pNotify = this->ioCompletedList.get () ) ) {
pNotify->destroy ( guard, * this );
pNotify->destroy ( cbGuard, guard );
}
}
void CASG::destroyPendingIO (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
while ( syncGroupNotify * pNotify = this->ioPendingList.first () ) {
pNotify->cancel ( guard );
pNotify->cancel ( cbGuard, guard );
// cancel must release the guard while
// canceling put callbacks so we
// must double check list membership
@@ -166,7 +166,7 @@ void CASG::destroyPendingIO (
else {
this->ioCompletedList.remove ( *pNotify );
}
pNotify->destroy ( guard, *this );
pNotify->destroy ( cbGuard, guard );
}
}
@@ -201,10 +201,11 @@ void CASG::show (
}
bool CASG::ioComplete (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
this->destroyCompletedIO ( guard );
this->destroyCompletedIO ( cbGuard, guard );
return this->ioPendingList.count () == 0u;
}
@@ -212,9 +213,9 @@ void CASG::put ( epicsGuard < epicsMutex > & guard, chid pChan,
unsigned type, arrayElementCount count, const void * pValue )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
sgAutoPtr < syncGroupWriteNotify > pNotify ( guard, *this, this->ioPendingList );
sgAutoPtr < syncGroupWriteNotify > pNotify ( guard, *this );
pNotify = syncGroupWriteNotify::factory (
this->freeListWriteOP, *this, pChan );
this->freeListWriteOP, *this, & CASG :: recycleWriteNotifyIO, pChan );
pNotify->begin ( guard, type, count, pValue );
pNotify.release ();
}
@@ -223,9 +224,9 @@ void CASG::get ( epicsGuard < epicsMutex > & guard, chid pChan,
unsigned type, arrayElementCount count, void *pValue )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
sgAutoPtr < syncGroupReadNotify > pNotify ( guard, *this, this->ioPendingList );
sgAutoPtr < syncGroupReadNotify > pNotify ( guard, *this );
pNotify = syncGroupReadNotify::factory (
this->freeListReadOP, *this, pChan, pValue );
this->freeListReadOP, *this, & CASG :: recycleReadNotifyIO, pChan, pValue );
pNotify->begin ( guard, type, count );
pNotify.release ();
}
@@ -241,20 +242,20 @@ void CASG::completionNotify (
}
}
void CASG::recycleSyncGroupWriteNotify (
epicsGuard < epicsMutex > & guard, syncGroupWriteNotify & io )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
this->freeListWriteOP.release ( & io );
}
void CASG::recycleSyncGroupReadNotify (
epicsGuard < epicsMutex > & guard, syncGroupReadNotify & io )
void CASG :: recycleReadNotifyIO ( epicsGuard < epicsMutex > & guard,
syncGroupReadNotify & io )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
this->freeListReadOP.release ( & io );
}
void CASG :: recycleWriteNotifyIO ( epicsGuard < epicsMutex > & guard,
syncGroupWriteNotify & io )
{
guard.assertIdenticalMutex ( this->client.mutexRef() );
this->freeListWriteOP.release ( & io );
}
int CASG :: printFormated ( const char *pformat, ... )
{
va_list theArgs;
@@ -295,13 +296,6 @@ void CASG::exception (
}
}
void * CASG::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void CASG::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if

View File

@@ -165,7 +165,8 @@ $Date$</span></small></p>
<li><a href="#ca_pend_io">block for certain requests to complete</a></li>
<li><a href="#ca_test_io">test to see if certain requests have
completed</a></li>
<li><a href="#ca_pend_event">process CA client library background activities</a></li>
<li><a href="#ca_pend_event">process CA client library background
activities</a></li>
<li><a href="#ca_flush_io">flush outstanding requests to the server</a></li>
<li><a href="#ca_add_exception_event">replace the default exception
handler</a></li>
@@ -454,26 +455,20 @@ Environment</a> below.</p>
<h3><a name="firewall">Firewalls</a></h3>
<p>If you want channel access clients on a machine to be able to see
beacons and replies to broadcast PV search requests you need to permit
inbound UDP packets with source port EPICS_CA_SERVER_PORT (default is 5064)
or destination port EPICS_CA_REPEATER_PORT (default is 5065). On systems
using iptables this can be accomplished by rules like</p>
<pre>
-A INPUT -s 192.168.0.0/22 -p udp --sport 5064 -j ACCEPT
-A INPUT -s 192.168.0.0/22 -p udp --dport 5065 -j ACCEPT
</pre>
<p>If you want channel access clients on a machine to be able to see beacons
and replies to broadcast PV search requests, you need to permit inbound UDP
packets with source port EPICS_CA_SERVER_PORT (default is 5064) or destination
port EPICS_CA_REPEATER_PORT (default is 5065). On systems using iptables this
can be accomplished by rules like</p>
<pre> -A INPUT -s 192.168.0.0/22 -p udp --sport 5064 -j ACCEPT
-A INPUT -s 192.168.0.0/22 -p udp --dport 5065 -j ACCEPT</pre>
<p>If you want channel access servers (e.g. "soft IOCs") on a machine to be
able to see clients you need to permit inbound TCP or UDP packets with source
port EPICS_CA_SERVER_PORT (default is 5064). On systems using iptables this
can be accomplished by rules like</p>
<pre>
-A INPUT -s 192.168.0.0/22 -p udp --dport 5064 -j ACCEPT
-A INPUT -s 192.168.0.0/22 -p tcp --dport 5064 -j ACCEPT
</pre>
able to be seen by clients, you need to permit inbound TCP or UDP packets with
destination port EPICS_CA_SERVER_PORT (default is 5064). On systems using
iptables this can be accomplished by rules like</p>
<pre> -A INPUT -s 192.168.0.0/22 -p udp --dport 5064 -j ACCEPT
-A INPUT -s 192.168.0.0/22 -p tcp --dport 5064 -j ACCEPT</pre>
<p>In all cases the "-s 192.168.0.0/22" specifies the range of addresses from
which you wish to accept packets.</p>
@@ -498,9 +493,8 @@ broadcast address of that subnet is added to the list. For each point to point
interface found, the destination address of that link is added to the list.
This automatic server address list initialization can be disabled if the EPICS
environment variable EPICS_CA_AUTO_ADDR_LIST exists and its value is either
of "no" or "NO". The typical default is to enable network interface
introspection driven initialization with EPICS_CA_AUTO_ADDR_LIST set to "YES"
or "yes".</p>
"no" or "NO". The typical default is to enable network interface introspection
driven initialization with EPICS_CA_AUTO_ADDR_LIST set to "YES" or "yes".</p>
<p>Following network interface introspection, any IP addresses specified in the
EPICS environment variable EPICS_CA_ADDR_LIST are added to the list of
@@ -511,8 +505,8 @@ CA servers unless a CA proxy (gateway) is installed. The addresses in
EPICS_CA_ADDR_LIST may be dotted IP addresses or host names if the local OS has
support for host name to IP address translation. When multiple names are added
to EPICS_CA_ADDR_LIST they must be separated by white space. There is no
requirement that the addresses specified in the EPICS_CA_ADDR_LIST be
broadcast addresses, but this will often be the most convenient choice.</p>
requirement that the addresses specified in the EPICS_CA_ADDR_LIST be broadcast
addresses, but this will often be the most convenient choice.</p>
<p>For any IP addresses specified in the EPICS environment variable
EPICS_CA_NAME_SERVERS, TCP connections are opened and used for CA client name
@@ -560,7 +554,7 @@ default to EPICS_CA_SERVER_PORT.</p>
<p>Frequently vxWorks systems boot by default with routes limiting access only
to the local subnet. If a EPICS system is operating in a WAN environment it may
be necessary to configure routes into the vxWorks system which enable a vxWorks
based CA server to respond to requests originating outside it's subnet. These
based CA server to respond to requests originating outside its subnet. These
routing restrictions can also apply to vxWorks base CA clients communicating
with off subnet servers. An EPICS system manager can implement an rudimentary,
but robust, form of access control for a particular host by not providing
@@ -865,8 +859,8 @@ the contents of EPICS_CA_ADDR_LIST is used to augment the list. Otherwise, the
list is not augmented.</p>
<p>The EPICS_CAS_BEACON_PORT parameter specifies the destination port for
server beacons. The only exception to this occurs when ports are specified
in EPICS_CAS_BEACON_ADDR_LIST or possibly in EPICS_CA_ADDR_LIST. If
server beacons. The only exception to this occurs when ports are specified in
EPICS_CAS_BEACON_ADDR_LIST or possibly in EPICS_CA_ADDR_LIST. If
EPICS_CAS_BEACON_PORT is not specified then beacons are sent to the port
specified in EPICS_CA_REPEATER_PORT.</p>
@@ -874,7 +868,7 @@ specified in EPICS_CA_REPEATER_PORT.</p>
<p>The parameter EPICS_CAS_INTF_ADDR_LIST allows a ca server to bind itself to,
and therefore accept messages only over, a limited set of the local host's
network interfaces (each specified by it's IP address). On UNIX systems type
network interfaces (each specified by its IP address). On UNIX systems type
"netstat -i" (type "ipconfig" on windows) to see a list of the local host's
network interfaces. Specifically, UDP search messages addressed to both the IP
addresses in EPICS_CAS_INTF_ADDR_LIST and also to the broadcast addresses of
@@ -1885,7 +1879,7 @@ order to connect to this new beacon-out-of-range server. The typical situation
where a client would not see the server's beacon might be when the client isnt
on the same IP subnet as the server, and the client's EPICS_CA_ADDR_LIST was
modified to include a destination address for the server, but the server's
beacon address list was not modified so that it's beacons are received by the
beacon address list was not modified so that its beacons are received by the
client.</p>
<h4><a name="Server1">A Server's IP Address Was Changed</a></h4>
@@ -1938,8 +1932,8 @@ Termination Appear to be Ignored</a></h3>
<p>Short lived CA client applications that issue a CA put request and then
immediately exit the process (return from <code>main</code> or call
<code>exit</code>) may find that there request isn't executed. To guarantee
that the request is sent call <code>ca_flush</code> followed by
<code>ca_context_destroy</code> prior to terminating the process.</p>
that the request is sent call <code>ca_flush_io()</code> followed by
<code>ca_context_destroy()</code> prior to terminating the process.</p>
<h3><a name="Problems">ENOBUFS Messages</a></h3>
@@ -2017,8 +2011,8 @@ OS and even between different versions of the same OS.</p>
<p>If the subscription update producer in the server produces subscription
updates faster than the subscription update consumer in the client consumes
them, then events have to be discarded if the buffering in the server
isn't allowed to grow to an infinite size. This is a law of nature
- based on queuing theory of course.</p>
isn't allowed to grow to an infinite size. This is a law of nature &ndash;
based on queuing theory of course.</p>
<p>What is done depends on the version of the CA server. All server versions
place quotas on the maximum number of subscription updates allowed on the
@@ -2040,10 +2034,10 @@ server to resume with subscription updates. This prevents slow clients from
getting time warped, but also guarantees that intervening events are discarded
until the slow client catches up.</p>
<p>There is currently no message on the IOC's console when a
particular client is slow on the uptake. A message of this type used to exist
many years ago, but it was a source of confusion (and what we will call
message noise) so it was removed. </p>
<p>There is currently no message on the IOC's console when a particular client
is slow on the uptake. A message of this type used to exist many years ago, but
it was a source of confusion (and what we will call message noise) so it was
removed.</p>
<p>There is unfortunately no field in the protocol allowing the server to
indicate that an intervening subscription update was discarded. We should
@@ -2320,7 +2314,7 @@ int main ( int argc, char ** argv )
<p>Certain CA client initiated requests asynchronously execute an application
supplied call back in the client process when a response arrives. The functions
ca_put_callback, ca_get_callback, and ca_add_event all request notification of
ca_put_callback, ca_get_callback, and ca_create_subscription all request notification of
asynchronous completion via this mechanism. The <code>event_handler_args
</code>structure is passed <em>by value</em> to the application supplied
callback. In this structure the <code>dbr</code> field is a void pointer to any
@@ -2355,8 +2349,8 @@ void myCallback ( struct event_handler_args args )
<h3><a name="Channel1">Channel Access Exceptions</a></h3>
<p>When the server detects a failure, and there is no client call back function
attached to the request, an exception handler is executed in the client.
The default exception handler prints a message on the console and exits if the
attached to the request, an exception handler is executed in the client. The
default exception handler prints a message on the console and exits if the
exception condition is severe. Certain internal exceptions within the CA client
library, and failures detected by the SEVCHK macro may also cause the exception
handler to be invoked. To modify this behavior see <a
@@ -2423,12 +2417,12 @@ same process).</p>
all OS (in past releases the library was thread safe only on vxWorks). When the
client library is initialized the programmer may specify if preemptive callback
is to be enabled. Preemptive callback is disabled by default. If preemptive
callback is enabled, then the user's callback functions might be called by
CA's auxiliary threads when the main initiating channel access thread is not
inside of a function in the channel access client library. Otherwise, the
user's callback functions will be called only when the main initiating channel
access thread is executing inside of the CA client library. When the CA client
library invokes a user's callback function, it will always wait for the current
callback is enabled, then the user's callback functions might be called by CA's
auxiliary threads when the main initiating channel access thread is not inside
of a function in the channel access client library. Otherwise, the user's
callback functions will be called only when the main initiating channel access
thread is executing inside of the CA client library. When the CA client library
invokes a user's callback function, it will always wait for the current
callback to complete prior to executing another callback function. Programmers
enabling preemptive callback should be familiar with using mutex locks to
create a reliable multi-threaded program.</p>
@@ -2457,10 +2451,10 @@ address space (process) to be independent of each other. For example, the
database CA links and the sequencer are designed to not use the same CA client
library threads, network circuits, and data structures. Each thread that calls
<a href="#ca_context_create">ca_context_create()</a> for the first time either
directly or implicitly when calling any CA library function for the first
time, creates a CA client library context. A CA client library context contains
all of the threads, network circuits, and data structures required to connect
and communicate with the channels that a CA client application has created. The
directly or implicitly when calling any CA library function for the first time,
creates a CA client library context. A CA client library context contains all
of the threads, network circuits, and data structures required to connect and
communicate with the channels that a CA client application has created. The
priority of auxiliary threads spawned by the CA client library are at fixed
offsets from the priority of the thread that called <a
href="#ca_context_create">ca_context_create()</a>. An application specific
@@ -2530,9 +2524,9 @@ questionable practice for the following reasons.</p>
<ul>
<li>The vxWorks shell thread runs at the very highest priority in the system
and therefore socket calls are made at a priority that is above the
priority of tNetTask - a practice that has caused the WRS IP kernel
to get sick in the past. That symptom was observed some time ago, but we
don't know if WRS has fixed the problem.</li>
priority of tNetTask. This has caused problems with the WRS IP kernel in
the past. That symptom was observed some time ago, but we don't know if
WRS has fixed the problem.</li>
</ul>
<ul>
<li>The vxWorks shell thread runs at the very highest priority in the system
@@ -2648,7 +2642,7 @@ get called in the correct order.</p>
resources used by the client library such as sockets and allocated memory are
automatically released by the system when the process exits and
ca_context_destroy() hasn't been called, but on light weight systems such as
vxWorks or RTEMS no cleanup occurs unless the application call
vxWorks or RTEMS no cleanup occurs unless the application calls
ca_context_destroy().</p>
<h4>Returns</h4>
@@ -2661,16 +2655,10 @@ ca_context_destroy().</p>
<h3><code><a name="ca_create_channel">ca_create_channel()</a></code></h3>
<pre>#include &lt;cadef.h&gt;
typedef void ( *pCallBack ) (
struct connection_handler_args );
int ca_create_channel
(
const char *PROCESS_VARIABLE_NAME,
caCh *USERFUNC,
void *PUSER,
capri priority,
chid *PCHID
);</pre>
typedef void ( caCh ) (struct connection_handler_args);
int ca_create_channel (const char *PVNAME,
caCh *USERFUNC, void *PUSER,
capri PRIORITY, chid *PCHID );</pre>
<h4>Description</h4>
@@ -2685,7 +2673,7 @@ on a channel.</p>
<p>The circuit may be initially connected or disconnected depending on the
state of the network and the location of the channel. A channel will only enter
a connected state after server's address is determined, and only if channel
a connected state after the server's address is determined, and only if channel
access successfully establishes a virtual circuit through the network to the
server. Channel access routines that send a request to a server will return
ECA_DISCONNCHID if the channel is currently disconnected.</p>
@@ -2695,7 +2683,7 @@ a connected state.</p>
<ul>
<li>The first and simplest method requires that you call ca_pend_io(), and
wait for successful completion, prior to using a channel that was created
specifying a nil connection call back function pointer.</li>
specifying a nill connection call back function pointer.</li>
<li>The second method requires that you register a connection handler by
supplying a valid connection callback function pointer. This connection
handler is called whenever the connection state of the channel changes. If
@@ -2719,7 +2707,7 @@ time.</p>
<h4>Arguments</h4>
<dl>
<dt><code>PROCESS_VARIABLE_NAME</code></dt>
<dt><code>PVNAME</code></dt>
<dd>A nil terminated process variable name string. EPICS process control
function block database variable names are of the form "&lt;record
name&gt;.&lt;field name&gt;". If the field name and the period separator
@@ -2731,10 +2719,10 @@ time.</p>
<dt><code>USERFUNC</code></dt>
<dd>Optional address of the user's call back function to be run when the
connection state changes. Casual users of channel access may decide to
set this field to nil or 0 if they do not need to have a call back
set this field to nill or 0 if they do not need to have a call back
function run in response to each connection state change event.
<p>The following structure is passed <em>by value </em>to the user's
connection connection callback function. The <code>op</code> field will
connection callback function. The <code>op</code> field will
be set by the CA client library to <code>CA_OP_CONN_UP</code> when the
channel connects, and to <code>CA_OP_CONN_DOWN</code> when the channel
disconnects. See <code><a href="#ca_puser">ca_puser</a></code> if the
@@ -2751,7 +2739,7 @@ time.</p>
<dd>The value of this void pointer argument is retained in
storage associated with the specified channel. See the MACROS manual page
for reading and writing this field. Casual users of channel access may
wish to set this field to nil or 0.</dd>
wish to set this field to nill or 0.</dd>
</dl>
<dl>
<dt><code>PRIORITY</code></dt>
@@ -2818,29 +2806,27 @@ subscriptions (monitors) registered with the channel.</p>
<pre>#include &lt;cadef.h&gt;
int ca_put ( chtype TYPE,
chid CHID, void *PVALUE );
int ca_array_put ( chtype TYPE,
unsigned long COUNT,
int ca_array_put ( chtype TYPE, unsigned long COUNT,
chid CHID, const void *PVALUE);
typedef void ( *pCallBack ) (struct event_handler_args );
typedef void ( caEventCallBackFunc ) (struct event_handler_args);
int ca_put_callback ( chtype TYPE,
chid CHID, const void *PVALUE,
pCallBack PFUNC, void *USERARG );
int ca_array_put_callback ( chtype TYPE,
unsigned long COUNT,
caEventCallBackFunc PFUNC, void *USERARG );
int ca_array_put_callback ( chtype TYPE, unsigned long COUNT,
chid CHID, const void *PVALUE,
pCallBack PFUNC, void *USERARG );</pre>
caEventCallBackFunc PFUNC, void *USERARG );</pre>
<h4>Description</h4>
<p>Write a scalar or array value to a process variable.</p>
<p>When ca_array_put or ca_put are invoked the client will receive no response
<p>When ca_put or ca_array_put are invoked the client will receive no response
unless the request can not be fulfilled in the server. If unsuccessful an
exception handler is run on the client side.</p>
<p>When ca_array_put_callback are invoked the user supplied asynchronous call
back is called only after the initiated write operation, and all actions
resulting from the initiating write operation, complete.</p>
<p>When ca_put_callback or ca_array_put_callback are invoked the user supplied
asynchronous call back is called only after the initiated write operation, and
all actions resulting from the initiating write operation, complete.</p>
<p>If unsuccessful the call back function is invoked indicating failure status.
</p>
@@ -2861,7 +2847,7 @@ This allows several requests to be efficiently combined into one message.</p>
<h4>Description (IOC Database Specific)</h4>
<p>A CA put request causes the record to process if the record's SCAN field is
set to passive, and the field being written has it's process passive attribute
set to passive, and the field being written has its process passive attribute
set to true. If such a record is already processing when a put request is
initiated the specified field is written immediately, and the record is
scheduled to process again as soon as it finishes processing. Earlier instances
@@ -2869,20 +2855,19 @@ of multiple put requests initiated while the record is being processing may be
discarded, but the last put request initiated is always written and
processed.</p>
<p>A CA put <span style="font-style: italic;">callback</span> request causes
the record to process if the record's SCAN field is set to passive, and the
field being written has it's process passive attribute set to true. For such a
record, the user's put callback function is not called until after the record,
and any records that the record links to, finish processing. If such a record
is already processing when a put <span
style="font-style: italic;">callback</span> request is initiated the put <span
style="font-style: italic;">callback</span> request is postponed until the
record, and any records it links to, finish processing.</p>
<p>A CA put <em>callback</em> request causes the record to process if the
record's SCAN field is set to passive, and the field being written has its
process passive attribute set to true. For such a record, the user's put
callback function is not called until after the record, and any records that
the record links to, finish processing. If such a record is already processing
when a put <em>callback</em> request is initiated the put <em>callback</em>
request is postponed until the record, and any records it links to, finish
processing.</p>
<p>If the record's SCAN field is not set to passive, or the field being written
has it's process passive attribute set to false then the CA put or CA put
callback request cause the specified field to be immediately written, but they
do not cause the record to be processed.</p>
has its process passive attribute set to false then the CA put or CA put
<em>callback</em> request cause the specified field to be immediately written,
but they do not cause the record to be processed.</p>
<h4>Arguments</h4>
<dl>
@@ -2948,18 +2933,19 @@ int ca_get ( chtype TYPE,
chid CHID, void *PVALUE );
int ca_array_get ( chtype TYPE, unsigned long COUNT,
chid CHID, void *PVALUE );
typedef void ( *pCallBack ) (struct event_handler_args );
typedef void ( caEventCallBackFunc ) (struct event_handler_args);
int ca_get_callback ( chtype TYPE,
chid CHID, pCallBack USERFUNC, void *USERARG);
chid CHID,
caEventCallBackFunc USERFUNC, void *USERARG);
int ca_array_get_callback ( chtype TYPE, unsigned long COUNT,
chid CHID,
pCallBack USERFUNC, void *USERARG );</pre>
caEventCallBackFunc USERFUNC, void *USERARG);</pre>
<h4>Description</h4>
<p>Read a scalar or array value from a process variable.</p>
<p>When ca_get or ca_array_get are invoked the returned channel value cant be
<p>When ca_get or ca_array_get are invoked the returned channel value can't be
assumed to be stable in the application supplied buffer until after ECA_NORMAL
is returned from ca_pend_io. If a connection is lost outstanding ca get
requests are not automatically reissued following reconnect.</p>
@@ -3051,11 +3037,10 @@ when a CA get request is initiated.</p>
<h3><code><a name="ca_add_event">ca_create_subscription()</a></code></h3>
<pre>#include &lt;cadef.h&gt;
typedef void ( *pCallBack ) (
struct event_handler_args );
int ca_create_subscription ( chtype TYPE,
unsigned long COUNT, chid CHID,
unsigned long MASK, pCallBack USERFUNC, void *USERARG,
typedef void ( caEventCallBackFunc ) (struct event_handler_args);
int ca_create_subscription ( chtype TYPE, unsigned long COUNT,
chid CHID, unsigned long MASK,
caEventCallBackFunc USERFUNC, void *USERARG,
evid *PEVID );</pre>
<h4>Description</h4>
@@ -3064,10 +3049,10 @@ int ca_create_subscription ( chtype TYPE,
invoked whenever the process variable undergoes significant state changes. A
significant change can be a change in the process variable's value, alarm
status, or alarm severity. In the process control function block database the
deadband field determines the magnitude of a significant change for for the
deadband field determines the magnitude of a significant change for the
process variable's value. Each call to this function consumes resources in the
client library and potentially a CA server until one of ca_clear_channel or
ca_clear_event is called.</p>
ca_clear_subscription is called.</p>
<p>Subscriptions may be installed or canceled against both connected and
disconnected channels. The specified USERFUNC is called once immediately after
@@ -3075,7 +3060,7 @@ the subscription is installed with the process variable's current state if the
process variable is connected. Otherwise, the specified USERFUNC is called
immediately after establishing a connection (or reconnection) with the process
variable. The specified USERFUNC is called immediately with the process
variable's current state from within ca_add_event() if the client and the
variable's current state from within ca_create_subscription() if the client and the
process variable share the same address space.</p>
<p>If a subscription is installed on a channel in a disconnected state then the
@@ -3132,8 +3117,8 @@ indicating the current state of the channel.</p>
<dl>
<dt><code>PEVID</code></dt>
<dd>This is a pointer to user supplied event id which is overwritten if
successful. This event id can later be used to clear a specific
event. This option may may be omitted by passing a nil pointer.</dd>
successful. This event id can later be used to clear a specific event.
This option may be omitted by passing a nill pointer.</dd>
</dl>
<dl>
<dt><code>MASK</code></dt>
@@ -3181,7 +3166,7 @@ int ca_clear_subscription ( evid EVID );</pre>
<p>Cancel a subscription.</p>
<p>All ca_clear_event() requests such as the above are accumulated (buffered)
<p>All cancel-subscription requests such as the above are accumulated (buffered)
and not forwarded to the server until one of ca_flush_io, ca_pend_io,
ca_pend_event, or ca_sg_pend are called. This allows several requests to be
efficiently sent together in one message.</p>
@@ -3189,7 +3174,7 @@ efficiently sent together in one message.</p>
<h4>Arguments</h4>
<dl>
<dt>EVID</dt>
<dd>event id returned by ca_add_event()</dd>
<dd>event id returned by ca_create_subscription()</dd>
</dl>
<h4>Returns</h4>
@@ -3240,9 +3225,9 @@ activities</em>.</p>
network delays such as Ethernet collision exponential back off until
retransmission delays which can be quite long on overloaded networks.</p>
<p>Unlike <code><a href="#ca_pend_event">ca_pend_event</a></code>, this routine will
not process CA's background activities if none of the selected IO requests are
pending.</p>
<p>Unlike <code><a href="#ca_pend_event">ca_pend_event</a></code>, this routine
will not process CA's background activities if none of the selected IO requests
are pending.</p>
<h4>Arguments</h4>
<dl>
@@ -3305,7 +3290,7 @@ activity is processed for TIMEOUT seconds.</p>
background activity is processed.</p>
<p>The ca_pend_event function will <em>not</em> return before the specified
time-out expires and all unfinished channel access labor has been processed,
timeout expires and all unfinished channel access labor has been processed,
and unlike <code><a href="#ca_pend_io">ca_pend_io</a></code> returning from the
function does <em>not </em>indicate anything about the status of pending IO
requests.</p>
@@ -3417,7 +3402,7 @@ field should not be used.</p>
<dl>
<dt><code>USERFUNC</code></dt>
<dd>Address of user callback function to be executed when an exceptions
occur. Passing a nil value causes the default exception handler to be
occur. Passing a nill value causes the default exception handler to be
reinstalled. The following structure is passed by value to the user's
callback function. Currently, the <code>op</code> field can be one of
<code>CA_OP_GET, CA_OP_PUT, CA_OP_CREATE_CHANNEL, CA_OP_ADD_EVENT,
@@ -3540,7 +3525,7 @@ get the lowest latency response to the arrival of CA messages.</p>
<h3><code><a name="ca_replace_printf_handler">ca_replace_printf_handler
()</a></code></h3>
<pre>#include &lt;cadef.h&gt;
typedef int caPrintfFunc ( const char *pFromat, va_list args );
typedef int caPrintfFunc ( const char *pFormat, va_list args );
int ca_replace_printf_handler ( caPrintfFunc *PFUNC );</pre>
<h4>Description</h4>
@@ -3552,7 +3537,7 @@ default handler uses fprintf to send messages to 'stderr'.</p>
<dl>
<dt><code>PFUNC</code></dt>
<dd>The address of a user supplied call back handler to be invoked when CA
prints diagnostic messages. Installing a nil pointer will cause the
prints diagnostic messages. Installing a nill pointer will cause the
default call back handler to be reinstalled.</dd>
</dl>
@@ -3571,8 +3556,9 @@ SEVCHK ( status, "failed to install my printf handler" );</pre>
<h3><code><a name="ca_replace">ca_replace_access_rights_event()</a></code></h3>
<pre>#include &lt;cadef.h&gt;
typedef void ( *pCallBack )( struct access_rights_handler_args );
int ca_replace_access_rights_event ( chid CHAN, pCallBack PFUNC );</pre>
typedef void ( caEventCallBackFunc )(struct access_rights_handler_args);
int ca_replace_access_rights_event ( chid CHAN,
caEventCallBackFunc PFUNC );</pre>
<h4>Description</h4>
@@ -3598,7 +3584,7 @@ specified channel.</p>
</dl>
<dl>
<dt><code>PFUNC</code></dt>
<dd>Address of user supplied call back function. A nil pointer uninstalls
<dd>Address of user supplied call back function. A nill pointer uninstalls
the current handler. The following arguments are passed <em>by value</em>
to the supplied callback handler.
<pre>typedef struct ca_access_rights {
@@ -3941,12 +3927,12 @@ prints diagnostics to standard out.</p>
<h4>Examples</h4>
<pre>void ca_test_event ();
status = ca_add_event ( type, chid, ca_test_event, NULL, NULL );
status = ca_create_subscription ( type, chid, ca_test_event, NULL, NULL );
SEVCHK ( status, .... );</pre>
<h4>See Also</h4>
<p><a href="#ca_add_event">ca_add_event</a>()</p>
<p><a href="#ca_add_event">ca_create_subscription</a>()</p>
<h3><code><a name="ca_sg_create">ca_sg_create()</a></code></h3>
<pre>#include &lt;cadef.h&gt;
@@ -4029,7 +4015,7 @@ SEVCHK ( status, Sync group delete failed );</pre>
<h3><code><a name="ca_sg_block">ca_sg_block()</a></code></h3>
<pre>#include &lt;cadef.h&gt;
int ca_sg_block ( CA_SYNC_GID GID, double timeout );</pre>
int ca_sg_block ( CA_SYNC_GID GID, double TIMEOUT );</pre>
<h4>Description</h4>
@@ -4050,13 +4036,16 @@ access background activity while it is waiting.</p>
<h4>Arguments</h4>
<dl>
<dt>GID</dt>
<dt><code>GID</code></dt>
<dd>Identifier of the synchronous group.</dd>
<dt><code>TIMEOUT</code></dt>
<dd>The duration to block in this routine in seconds. A timeout of zero
seconds blocks forever.</dd>
</dl>
<h4>Examples</h4>
<pre>CA_SYNC_GID gid;
status = ca_sg_block(gid);
status = ca_sg_block(gid, 0.0);
SEVCHK(status, Sync group block failed);</pre>
<h4>Returns</h4>
@@ -4267,8 +4256,8 @@ reissued.</p>
<h3><code><a name="ca_client_status">ca_client_status()</a></code></h3>
<pre>int ca_client_status ( unsigned level );
int ca_context_status ( struct ca_client_context *,
unsigned level );</pre>
int ca_context_status ( struct ca_client_context *CONTEXT,
unsigned LEVEL );</pre>
<h4>Description</h4>
@@ -4279,7 +4268,7 @@ ca_client_status() prints information about the calling threads CA context.</p>
<h4>Arguments</h4>
<dl>
<dt><code>CONTEXT</code></dt>
<dd>A pointer to the CA context to join with.</dd>
<dd>A pointer to the CA context to examine.</dd>
<dt><code>LEVEL</code></dt>
<dd>The interest level. Increasing level produces increasing detail.</dd>
</dl>
@@ -4289,7 +4278,7 @@ ca_client_status() prints information about the calling threads CA context.</p>
<h4>Description</h4>
<p>Returns a pointer to the current thread's CA context. If none then nil is
<p>Returns a pointer to the current thread's CA context. If none then nill is
returned.</p>
<h4>See Also</h4>
@@ -4322,12 +4311,11 @@ preemptively from more than one thread.</p>
<h4>Returns</h4>
<p>ECA_ISATTACHED - already attached to a CA context</p>
<p>ECA_NORMAL - Normal successful completion</p>
<p>ECA_NOTTHREADED - the specified context is non-preemptive and therefore does
not allow other threads to join</p>
<p>ECA_NOTTHREADED - Context is not preemptive so cannot be joined</p>
<p>ECA_ISATTACHED - the current thread is already attached to a CA context</p>
<p>ECA_ISATTACHED - Thread already attached to a CA context</p>
<h4>See Also</h4>

View File

@@ -91,14 +91,19 @@ PROD_LIBS = ca Com
# needed when its an object library build
PROD_SYS_LIBS_WIN32 = ws2_32 advapi32 user32
PROD_HOST += caRepeater catime acctst caConnTest casw caEventRate
OBJS_IOC += catime acctst caConnTest casw caEventRate acctstRegister
PROD_DEFAULT += caRepeater catime acctst caConnTest casw caEventRate
PROD_vxWorks = -nil-
PROD_RTEMS = -nil-
PROD_iOS = -nil-
OBJS_vxWorks = catime acctst caConnTest casw caEventRate acctstRegister
caRepeater_SRCS = caRepeater.cpp
catime_SRCS = catimeMain.c catime.c
acctst_SRCS = acctstMain.c acctst.c
catime_SRCS = catimeMain.c catime.c
acctst_SRCS = acctstMain.c acctst.c
caEventRate_SRCS = caEventRateMain.cpp caEventRate.cpp
casw_SRCS = casw.cpp
caConnTest_SRCS = caConnTestMain.cpp caConnTest.cpp
caConnTest_SRCS = caConnTestMain.cpp caConnTest.cpp
casw_SYS_LIBS_solaris = socket

0
src/ca/SearchDest.h Executable file → Normal file
View File

View File

@@ -376,15 +376,35 @@ int epicsShareAPI ca_create_channel (
int epicsShareAPI ca_clear_channel ( chid pChan )
{
ca_client_context & cac = pChan->getClientCtx ();
epicsGuard < epicsMutex > guard ( cac.mutex );
try {
pChan->eliminateExcessiveSendBacklog ( guard );
{
epicsGuard < epicsMutex > guard ( cac.mutex );
try {
pChan->eliminateExcessiveSendBacklog ( guard );
}
catch ( cacChannel::notConnected & ) {
// intentionally ignored
}
}
catch ( cacChannel::notConnected & ) {
// intentionally ignored
}
pChan->destructor ( guard );
if ( cac.pCallbackGuard.get() &&
cac.createdByThread == epicsThreadGetIdSelf () ) {
epicsGuard < epicsMutex > guard ( cac.mutex );
pChan->destructor ( *cac.pCallbackGuard.get(), guard );
cac.oldChannelNotifyFreeList.release ( pChan );
}
else {
//
// we will definately stall out here if all of the
// following are true
//
// o user creates non-preemtive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
//
CallbackGuard cbGuard ( cac.cbMutex );
epicsGuard < epicsMutex > guard ( cac.mutex );
pChan->destructor ( *cac.pCallbackGuard.get(), guard );
cac.oldChannelNotifyFreeList.release ( pChan );
}
return ECA_NORMAL;
}
@@ -433,7 +453,7 @@ chid epicsShareAPI ca_evid_to_chid ( evid pMon )
}
// extern "C"
int epicsShareAPI ca_pend ( ca_real timeout, int early ) // X aCC 361
int epicsShareAPI ca_pend ( ca_real timeout, int early )
{
if ( early ) {
return ca_pend_io ( timeout );
@@ -516,7 +536,7 @@ int epicsShareAPI ca_flush_io ()
/*
* CA_TEST_IO ()
*/
int epicsShareAPI ca_test_io () // X aCC 361
int epicsShareAPI ca_test_io ()
{
ca_client_context *pcac;
int caStatus = fetchClientContext ( &pcac );
@@ -551,7 +571,7 @@ void epicsShareAPI ca_signal ( long ca_status, const char *message )
* (if they call this routine again).
*/
// extern "C"
const char * epicsShareAPI ca_message ( long ca_status ) // X aCC 361
const char * epicsShareAPI ca_message ( long ca_status )
{
unsigned msgNo = CA_EXTRACT_MSG_NO ( ca_status );

View File

@@ -13,6 +13,7 @@
* Authors:
* Jeff Hill
* Murali Shankar - initial versions of verifyMultithreadSubscr
* Michael Abbott - initial versions of multiSubscrDestroyNoLateCallbackTest
*
*/
@@ -1328,6 +1329,159 @@ void test_sync_groups ( chid chan, unsigned interestLevel )
showProgressEnd ( interestLevel );
}
#define multiSubscrDestroyNoLateCallbackEventCount 500
struct MultiSubscrDestroyNoLateCallbackEventData {
evid m_id;
size_t m_nCallback;
int m_callbackIsOk;
struct MultiSubscrDestroyNoLateCallbackTestData * m_pTestData;
};
struct MultiSubscrDestroyNoLateCallbackTestData {
const char * m_pChanName;
chid m_chan;
epicsMutexId m_mutex;
epicsEventId m_testDoneEvent;
unsigned m_interestLevel;
struct MultiSubscrDestroyNoLateCallbackEventData
m_eventData [multiSubscrDestroyNoLateCallbackEventCount];
};
static void noLateCallbackDetect ( struct event_handler_args args )
{
int callbackIsOk;
struct MultiSubscrDestroyNoLateCallbackEventData * const pEventData = args.usr;
epicsMutexLockStatus lockStatus = epicsMutexLock ( pEventData->m_pTestData->m_mutex );
callbackIsOk = pEventData->m_callbackIsOk;
pEventData->m_nCallback++;
epicsMutexUnlock ( pEventData->m_pTestData->m_mutex );
verify ( lockStatus == epicsMutexLockOK );
verify ( callbackIsOk );
}
static void multiSubscrDestroyNoLateCallbackThread ( void * pParm )
{
struct MultiSubscrDestroyNoLateCallbackTestData * const pTestData =
( struct MultiSubscrDestroyNoLateCallbackTestData * ) pParm;
unsigned i, j;
int status;
status = ca_context_create ( ca_enable_preemptive_callback );
verify ( status == ECA_NORMAL );
status = ca_create_channel ( pTestData->m_pChanName, 0, 0,
CA_PRIORITY_DEFAULT, &pTestData->m_chan );
status = ca_pend_io ( timeoutToPendIO );
SEVCHK ( status, "multiSubscrDestroyLateNoCallbackTest: channel connect failed" );
verify ( status == ECA_NORMAL );
/*
* create a set of subscriptions
*/
for ( i=0; i < 10000; i++ ) {
unsigned int priorityOfTestThread;
for ( j=0; j < multiSubscrDestroyNoLateCallbackEventCount; j++ ) {
epicsMutexLockStatus lockStatus = epicsMutexLock ( pTestData->m_mutex );
verify ( lockStatus == epicsMutexLockOK );
pTestData->m_eventData[j].m_nCallback = 0;
pTestData->m_eventData[j].m_callbackIsOk = TRUE;
pTestData->m_eventData[j].m_pTestData = pTestData;
epicsMutexUnlock ( pTestData->m_mutex );
SEVCHK ( ca_add_event ( DBR_GR_FLOAT, pTestData->m_chan, noLateCallbackDetect,
&pTestData->m_eventData[j], &pTestData->m_eventData[j].m_id ) , NULL );
}
SEVCHK ( ca_flush_io(), NULL );
/*
* raise the priority of the current thread hoping to improve our
* likelyhood of detecting a bug
*/
priorityOfTestThread = epicsThreadGetPrioritySelf ();
epicsThreadSetPriority ( epicsThreadGetIdSelf(), epicsThreadPriorityHigh );
/*
* wait for the first subscription update to arrive
*/
{
epicsMutexLockStatus lockStatus = epicsMutexLock ( pTestData->m_mutex );
verify ( lockStatus == epicsMutexLockOK );
while ( pTestData->m_eventData[0].m_nCallback == 0 ) {
epicsMutexUnlock ( pTestData->m_mutex );
epicsThreadSleep ( 50e-6 );
lockStatus = epicsMutexLock ( pTestData->m_mutex );
verify ( lockStatus == epicsMutexLockOK );
}
epicsMutexUnlock ( pTestData->m_mutex );
}
/*
* try to destroy all of the subscriptions at precisely the same time that
* their first callbacks are running
*/
for ( j=0; j < multiSubscrDestroyNoLateCallbackEventCount; j++ ) {
epicsMutexLockStatus lockStatus;
SEVCHK ( ca_clear_event ( pTestData->m_eventData[j].m_id ) , NULL );
lockStatus = epicsMutexLock ( pTestData->m_mutex );
verify ( lockStatus == epicsMutexLockOK );
pTestData->m_eventData[j].m_callbackIsOk = FALSE;
epicsMutexUnlock ( pTestData->m_mutex );
}
/*
* return to the original priority
*/
epicsThreadSetPriority ( epicsThreadGetIdSelf(), priorityOfTestThread );
if ( i % 1000 == 0 ) {
showProgress ( pTestData->m_interestLevel );
}
}
SEVCHK ( ca_clear_channel ( pTestData->m_chan ), NULL );
ca_context_destroy ();
epicsEventSignal ( pTestData->m_testDoneEvent );
}
/*
* verify that, in a preemtive callback mode client, a subscription callback never
* comes after the subscription is destroyed
*/
static void multiSubscrDestroyNoLateCallbackTest ( const char *pName, unsigned interestLevel )
{
struct MultiSubscrDestroyNoLateCallbackTestData * pTestData;
showProgressBegin ( "multiSubscrDestroyNoLateCallbackTest", interestLevel );
pTestData = calloc ( 1u, sizeof ( struct MultiSubscrDestroyNoLateCallbackTestData ) );
verify ( pTestData );
pTestData->m_mutex = epicsMutexMustCreate ();
pTestData->m_testDoneEvent = epicsEventMustCreate ( epicsEventEmpty );
pTestData->m_pChanName = pName;
pTestData->m_interestLevel = interestLevel;
epicsThreadMustCreate (
"multiSubscrDestroyNoLateCallbackTest",
epicsThreadPriorityLow,
epicsThreadGetStackSize ( epicsThreadStackMedium ),
multiSubscrDestroyNoLateCallbackThread,
pTestData );
/*
* wait for test to complete
*/
epicsEventMustWait ( pTestData->m_testDoneEvent );
/*
* cleanup
*/
epicsMutexDestroy ( pTestData->m_mutex );
epicsEventDestroy ( pTestData->m_testDoneEvent );
free ( pTestData );
showProgressEnd ( interestLevel );
}
/*
* multiSubscriptionDeleteTest
*
@@ -3263,6 +3417,11 @@ int acctst ( const char * pName, unsigned interestLevel, unsigned channelCount,
epicsEnvSet ( "EPICS_CA_MAX_ARRAY_BYTES", tmpString );
}
/*
* this test creates, and then destroys, a private CA context
*/
multiSubscrDestroyNoLateCallbackTest ( pName, interestLevel );
status = ca_context_create ( select );
SEVCHK ( status, NULL );

View File

@@ -332,13 +332,6 @@ void bhe::unregisterIIU (
}
}
void * bhe::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void bhe::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if

View File

@@ -87,7 +87,6 @@ private:
const epicsTime & currentTime );
bhe ( const bhe & );
bhe & operator = ( const bhe & );
void * operator new ( size_t size );
epicsShareFunc void operator delete ( void * );
};

0
src/ca/ca.rc Executable file → Normal file
View File

View File

@@ -106,7 +106,7 @@ ca_client_context::ca_client_context ( bool enablePreemptiveCallback ) :
{
osiSockIoctl_t yes = true;
int status = socket_ioctl ( this->sock, // X aCC 392
int status = socket_ioctl ( this->sock,
FIONBIO, & yes);
if ( status < 0 ) {
char sockErrBuf[64];
@@ -126,7 +126,7 @@ ca_client_context::ca_client_context ( bool enablePreemptiveCallback ) :
memset ( (char *)&addr, 0 , sizeof ( addr ) );
addr.ia.sin_family = AF_INET;
addr.ia.sin_addr.s_addr = htonl ( INADDR_ANY );
addr.ia.sin_port = htons ( PORT_ANY ); // X aCC 818
addr.ia.sin_port = htons ( PORT_ANY );
int status = bind (this->sock, &addr.sa, sizeof (addr) );
if ( status < 0 ) {
char sockErrBuf[64];
@@ -159,9 +159,9 @@ ca_client_context::ca_client_context ( bool enablePreemptiveCallback ) :
this->localPort = htons ( tmpAddr.ia.sin_port );
}
epics_auto_ptr < epicsGuard < epicsMutex > > pCBGuard;
epics_auto_ptr < CallbackGuard > pCBGuard;
if ( ! enablePreemptiveCallback ) {
pCBGuard.reset ( new epicsGuard < epicsMutex > ( this->cbMutex ) );
pCBGuard.reset ( new CallbackGuard ( this->cbMutex ) );
}
// multiple steps ensure exception safety
@@ -277,7 +277,7 @@ int ca_client_context :: printFormated (
}
int ca_client_context :: varArgsPrintFormated (
const char *pformat, va_list args ) const // X aCC 361
const char *pformat, va_list args ) const
{
caPrintfFunc * pFunc;
{
@@ -751,6 +751,8 @@ epicsShareFunc int epicsShareAPI ca_clear_subscription ( evid pMon )
{
oldChannelNotify & chan = pMon->channel ();
ca_client_context & cac = chan.getClientCtx ();
// !!!! the order in which we take the mutex here prevents deadlocks
{
epicsGuard < epicsMutex > guard ( cac.mutex );
try {
// if this stalls out on a live circuit then an exception
@@ -761,7 +763,25 @@ epicsShareFunc int epicsShareAPI ca_clear_subscription ( evid pMon )
catch ( cacChannel::notConnected & ) {
// intentionally ignored
}
pMon->cancel ( guard );
}
if ( cac.pCallbackGuard.get() &&
cac.createdByThread == epicsThreadGetIdSelf () ) {
epicsGuard < epicsMutex > guard ( cac.mutex );
pMon->cancel ( *cac.pCallbackGuard.get(), guard );
}
else {
//
// we will definately stall out here if all of the
// following are true
//
// o user creates non-preemtive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
//
CallbackGuard cbGuard ( cac.cbMutex );
epicsGuard < epicsMutex > guard ( cac.mutex );
pMon->cancel ( cbGuard, guard );
}
return ECA_NORMAL;
}

View File

@@ -568,7 +568,7 @@ bool cac::findOrCreateVirtCircuit (
}
void cac::transferChanToVirtCircuit (
unsigned cid, unsigned sid, // X aCC 431
unsigned cid, unsigned sid,
ca_uint16_t typeCode, arrayElementCount count,
unsigned minorVersionNumber, const osiSockAddr & addr,
const epicsTime & currentTime )
@@ -711,6 +711,7 @@ netReadNotifyIO & cac::readNotifyRequest (
}
bool cac::destroyIO (
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & guard,
const cacChannel::ioid & idIn, nciu & chan )
{
@@ -787,7 +788,7 @@ void cac::recycleSubscription (
netSubscription & cac::subscriptionRequest (
epicsGuard < epicsMutex > & guard,
nciu & chan, privateInterfaceForIO & privChan,
unsigned type, // X aCC 361
unsigned type,
arrayElementCount nElem, unsigned mask,
cacStateNotify & notifyIn,
bool chanIsInstalled )
@@ -1021,7 +1022,7 @@ bool cac::readExcep ( callbackManager &, tcpiiu &,
}
bool cac::writeExcep (
callbackManager & mgr, // X aCC 431
callbackManager & mgr,
tcpiiu &, const caHdrLargeArray & hdr,
const char * pCtx, unsigned status )
{
@@ -1093,7 +1094,7 @@ bool cac::exceptionRespAction ( callbackManager & cbMutexIn, tcpiiu & iiu,
}
bool cac::accessRightsRespAction (
callbackManager & mgr, tcpiiu &, // X aCC 431
callbackManager & mgr, tcpiiu &,
const epicsTime &, const caHdrLargeArray & hdr, void * /* pMsgBody */ )
{
epicsGuard < epicsMutex > guard ( this->mutex );
@@ -1110,7 +1111,7 @@ bool cac::accessRightsRespAction (
}
bool cac::createChannelRespAction (
callbackManager & mgr, tcpiiu & iiu, // X aCC 431
callbackManager & mgr, tcpiiu & iiu,
const epicsTime &, const caHdrLargeArray & hdr, void * /* pMsgBody */ )
{
epicsGuard < epicsMutex > guard ( this->mutex );
@@ -1157,7 +1158,7 @@ bool cac::verifyAndDisconnectChan (
}
void cac::disconnectChannel (
epicsGuard < epicsMutex > & cbGuard, // X aCC 431
epicsGuard < epicsMutex > & cbGuard,
epicsGuard < epicsMutex > & guard, nciu & chan )
{
guard.assertIdenticalMutex ( this->mutex );

View File

@@ -55,7 +55,7 @@ class netSubscription;
// used to control access to cac's recycle routines which
// should only be indirectly invoked by CAC when its lock
// is applied
class cacRecycle { // X aCC 655
class cacRecycle {
public:
virtual void recycleReadNotifyIO (
epicsGuard < epicsMutex > &, netReadNotifyIO &io ) = 0;
@@ -155,7 +155,8 @@ public:
unsigned type, arrayElementCount nElem, unsigned mask,
cacStateNotify &, bool channelIsInstalled );
bool destroyIO (
epicsGuard < epicsMutex > & guard,
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard,
const cacChannel::ioid & idIn,
nciu & chan );
void disconnectAllIO (
@@ -167,11 +168,6 @@ public:
epicsGuard < epicsMutex > & guard,
const cacChannel::ioid &id, unsigned level ) const;
// sync group routines
CASG * lookupCASG ( epicsGuard < epicsMutex > &, unsigned id );
void installCASG ( epicsGuard < epicsMutex > &, CASG & );
void uninstallCASG ( epicsGuard < epicsMutex > &, CASG & );
// exception generation
void exception (
epicsGuard < epicsMutex > & cbGuard,

View File

@@ -69,7 +69,7 @@ typedef unsigned long arrayElementCount;
// 1) this should not be passing caerr.h status to the exception callback
// 2) needless-to-say the data should be passed here using the new data access API
class epicsShareClass cacWriteNotify { // X aCC 655
class epicsShareClass cacWriteNotify {
public:
virtual ~cacWriteNotify () = 0;
virtual void completion ( epicsGuard < epicsMutex > & ) = 0;
@@ -82,7 +82,7 @@ public:
// 1) this should not be passing caerr.h status to the exception callback
// 2) needless-to-say the data should be passed here using the new data access API
class epicsShareClass cacReadNotify { // X aCC 655
class epicsShareClass cacReadNotify {
public:
virtual ~cacReadNotify () = 0;
virtual void completion (
@@ -97,7 +97,7 @@ public:
// 1) this should not be passing caerr.h status to the exception callback
// 2) needless-to-say the data should be passed here using the new data access API
class epicsShareClass cacStateNotify { // X aCC 655
class epicsShareClass cacStateNotify {
public:
virtual ~cacStateNotify () = 0;
virtual void current (
@@ -131,7 +131,7 @@ private:
bool f_operatorConfirmationRequest:1;
};
class epicsShareClass cacChannelNotify { // X aCC 655
class epicsShareClass cacChannelNotify {
public:
virtual ~cacChannelNotify () = 0;
virtual void connectNotify ( epicsGuard < epicsMutex > & ) = 0;
@@ -152,6 +152,16 @@ public:
unsigned type, arrayElementCount count ) = 0;
};
class CallbackGuard :
public epicsGuard < epicsMutex > {
public:
CallbackGuard ( epicsMutex & mutex ) :
epicsGuard < epicsMutex > ( mutex ) {}
private:
CallbackGuard ( const CallbackGuard & );
CallbackGuard & operator = ( const CallbackGuard & );
};
//
// Notes
// 1) This interface assumes that when a channel is deleted then all
@@ -174,6 +184,7 @@ public:
cacChannel ( cacChannelNotify & );
virtual void destroy (
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0;
cacChannelNotify & notify () const; // required ?????
virtual unsigned getName (
@@ -207,7 +218,15 @@ public:
epicsGuard < epicsMutex > &, unsigned type,
arrayElementCount count, unsigned mask, cacStateNotify &,
ioid * = 0 ) = 0;
// The primary mutex must be released when calling the user's
// callback, and therefore a finite interval exists when we are
// moving forward with the intent to call the users callback
// but the users IO could be deleted during this interval.
// To prevent the user's callback from being called after
// destroying his IO we must past a guard for the callback
// mutex here.
virtual void ioCancel (
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard,
const ioid & ) = 0;
virtual void ioShow (
@@ -258,7 +277,7 @@ private:
cacChannel & operator = ( const cacChannel & );
};
class epicsShareClass cacContext { // X aCC 655
class epicsShareClass cacContext {
public:
virtual ~cacContext ();
virtual cacChannel & createChannel (
@@ -277,7 +296,7 @@ public:
epicsGuard < epicsMutex > &, unsigned level ) const = 0;
};
class epicsShareClass cacContextNotify { // X aCC 655
class epicsShareClass cacContextNotify {
public:
virtual ~cacContextNotify () = 0;
virtual cacContext & createNetworkContext (
@@ -297,7 +316,7 @@ public:
// **** Lock Hierarchy ****
// callbackControl must be taken before mutualExclusion if both are held at
// the same time
class epicsShareClass cacService { // X aCC 655
class epicsShareClass cacService {
public:
virtual ~cacService () = 0;
virtual cacContext & contextCreate (

View File

@@ -131,7 +131,7 @@ int main ( int argc, char ** argv )
}
osiSockIoctl_t yes = true;
status = socket_ioctl ( sock, FIONBIO, &yes ); // X aCC 392
status = socket_ioctl ( sock, FIONBIO, &yes );
if ( status < 0 ) {
char sockErrBuf[64];
epicsSocketConvertErrnoToString (
@@ -166,7 +166,7 @@ int main ( int argc, char ** argv )
}
osiSockIoctl_t no = false;
status = socket_ioctl ( sock, FIONBIO, &no ); // X aCC 392
status = socket_ioctl ( sock, FIONBIO, &no );
if ( status < 0 ) {
char sockErrBuf[64];
epicsSocketConvertErrnoToString (

View File

@@ -44,7 +44,7 @@ public:
virtual void release ( void * ) = 0;
};
class wireSendAdapter { // X aCC 655
class wireSendAdapter {
public:
virtual unsigned sendBytes ( const void * pBuf,
unsigned nBytesInBuf,
@@ -65,7 +65,7 @@ struct statusWireIO {
swioCircuitState circuitState;
};
class wireRecvAdapter { // X aCC 655
class wireRecvAdapter {
public:
virtual void recvBytes ( void * pBuf,
unsigned nBytesInBuf, statusWireIO & ) = 0;
@@ -114,7 +114,6 @@ private:
unsigned nextWriteIndex;
unsigned nextReadIndex;
epicsUInt8 buf [ comBufSize ];
void * operator new ( size_t size );
void operator delete ( void * );
template < class T >
bool push ( const T * ); // disabled

View File

@@ -155,7 +155,7 @@ epicsUInt32 comQueRecv::multiBufferPopUInt32 ()
unsigned byte3 = this->popUInt8();
unsigned byte4 = this->popUInt8();
tmp = static_cast <epicsUInt32>
( ( byte1 << 24u ) | ( byte2 << 16u ) | //X aCC 392
( ( byte1 << 24u ) | ( byte2 << 16u ) |
( byte3 << 8u ) | byte4 );
}
else {

View File

@@ -368,7 +368,7 @@ void comQueSend::insertRequestWithPayLoad (
// the above checks verify that the total size
// is lest that 0xffffffff
size = static_cast < ca_uint32_t >
( dbr_size_n ( dataType, nElem ) ); // X aCC 392
( dbr_size_n ( dataType, nElem ) );
payloadSize = CA_MESSAGE_ALIGN ( size );
this->insertRequestHeader ( request, payloadSize,
static_cast <ca_uint16_t> ( dataType ),

View File

@@ -65,7 +65,7 @@ void disconnectGovernorTimer::shutdown (
}
epicsTimerNotify::expireStatus disconnectGovernorTimer::expire (
const epicsTime & /* currentTime */ ) // X aCC 361
const epicsTime & /* currentTime */ )
{
epicsGuard < epicsMutex > guard ( this->mutex );
while ( nciu * pChan = chanList.get () ) {

View File

@@ -43,7 +43,7 @@
#include "caProto.h"
#include "netiiu.h"
class disconnectGovernorNotify { // X aCC 655
class disconnectGovernorNotify {
public:
virtual ~disconnectGovernorNotify () = 0;
virtual void govExpireNotify (

View File

@@ -90,13 +90,6 @@ void getCallback::exception (
}
}
void * getCallback::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void getCallback::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if

View File

@@ -105,13 +105,6 @@ void getCopy::show ( unsigned level ) const
}
}
void * getCopy::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void getCopy::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if

View File

@@ -22,12 +22,12 @@
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include "envDefs.h"
#include "epicsAssert.h"
#include "epicsStdioRedirect.h"
#include "errlog.h"
#include "osiWireFormat.h"
@@ -133,7 +133,7 @@ extern "C" void epicsShareAPI removeDuplicateAddresses
if ( pNode->addr.sa.sa_family == AF_INET ) {
pTmpNode = (osiSockAddrNode *) ellFirst (pDestList); // X aCC 749
pTmpNode = (osiSockAddrNode *) ellFirst (pDestList);
while ( pTmpNode ) {
if (pTmpNode->addr.sa.sa_family == AF_INET) {
if ( pNode->addr.ia.sin_addr.s_addr == pTmpNode->addr.ia.sin_addr.s_addr &&
@@ -149,7 +149,7 @@ extern "C" void epicsShareAPI removeDuplicateAddresses
break;
}
}
pTmpNode = (osiSockAddrNode *) ellNext (&pTmpNode->node); // X aCC 749
pTmpNode = (osiSockAddrNode *) ellNext (&pTmpNode->node);
}
if (pNode) {
ellAdd (pDestList, &pNode->node);
@@ -168,12 +168,12 @@ static void forcePort ( ELLLIST *pList, unsigned short port )
{
osiSockAddrNode *pNode;
pNode = ( osiSockAddrNode * ) ellFirst ( pList ); // X aCC 749
pNode = ( osiSockAddrNode * ) ellFirst ( pList );
while ( pNode ) {
if ( pNode->addr.sa.sa_family == AF_INET ) {
pNode->addr.ia.sin_port = htons ( port );
}
pNode = ( osiSockAddrNode * ) ellNext ( &pNode->node ); // X aCC 749
pNode = ( osiSockAddrNode * ) ellNext ( &pNode->node );
}
}
@@ -192,9 +192,9 @@ extern "C" void epicsShareAPI configureChannelAccessAddressList
/*
* dont load the list twice
*/
assert ( ellCount (pList) == 0 ); // X aCC 392
assert ( ellCount (pList) == 0 );
ellInit ( &tmpList ); // X aCC 392
ellInit ( &tmpList );
/*
* Check to see if the user has disabled
@@ -217,12 +217,12 @@ extern "C" void epicsShareAPI configureChannelAccessAddressList
if (yes) {
ELLLIST bcastList;
osiSockAddr addr;
ellInit ( &bcastList ); // X aCC 392
ellInit ( &bcastList );
addr.ia.sin_family = AF_UNSPEC;
osiSockDiscoverBroadcastAddresses ( &bcastList, sock, &addr );
forcePort ( &bcastList, port );
removeDuplicateAddresses ( &tmpList, &bcastList, 1 );
if ( ellCount ( &tmpList ) == 0 ) { // X aCC 392
if ( ellCount ( &tmpList ) == 0 ) {
osiSockAddrNode *pNewNode;
pNewNode = (osiSockAddrNode *) calloc ( 1, sizeof (*pNewNode) );
if ( pNewNode ) {
@@ -254,11 +254,11 @@ extern "C" void epicsShareAPI printChannelAccessAddressList ( const ELLLIST *pLi
osiSockAddrNode *pNode;
::printf ( "Channel Access Address List\n" );
pNode = (osiSockAddrNode *) ellFirst ( pList ); // X aCC 749
pNode = (osiSockAddrNode *) ellFirst ( pList );
while (pNode) {
char buf[64];
ipAddrToA ( &pNode->addr.ia, buf, sizeof ( buf ) );
::printf ( "%s\n", buf );
pNode = (osiSockAddrNode *) ellNext ( &pNode->node ); // X aCC 749
pNode = (osiSockAddrNode *) ellNext ( &pNode->node );
}
}

View File

@@ -73,13 +73,6 @@ void msgForMultiplyDefinedPV::operator delete ( void *pCadaver,
}
#endif
void * msgForMultiplyDefinedPV::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void msgForMultiplyDefinedPV::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if

View File

@@ -39,7 +39,7 @@
# define epicsExportSharedSymbols
#endif
class callbackForMultiplyDefinedPV { // X aCC 655
class callbackForMultiplyDefinedPV {
public:
virtual ~callbackForMultiplyDefinedPV () = 0;
virtual void pvMultiplyDefinedNotify (
@@ -64,7 +64,6 @@ private:
void transactionComplete ( const char * pHostName );
msgForMultiplyDefinedPV ( const msgForMultiplyDefinedPV & );
msgForMultiplyDefinedPV & operator = ( const msgForMultiplyDefinedPV & );
void * operator new ( size_t size );
void operator delete ( void * );
};

View File

@@ -76,29 +76,24 @@ nciu::~nciu ()
// channels are created by the user, and only destroyed by the user
// using this routine
void nciu::destroy (
epicsGuard < epicsMutex > & guard )
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExcusionGuard )
{
while ( baseNMIU * pNetIO = this->eventq.first () ) {
bool success = this->cacCtx.destroyIO ( guard, pNetIO->getId (), *this );
bool success = this->cacCtx.destroyIO ( callbackGuard, mutualExcusionGuard,
pNetIO->getId (), *this );
assert ( success );
}
// if the claim reply has not returned yet then we will issue
// the clear channel request to the server when the claim reply
// arrives and there is no matching nciu in the client
if ( this->channelNode::isInstalledInServer ( guard ) ) {
this->getPIIU(guard)->clearChannelRequest (
guard, this->sid, this->id );
if ( this->channelNode::isInstalledInServer ( mutualExcusionGuard ) ) {
this->getPIIU(mutualExcusionGuard)->clearChannelRequest (
mutualExcusionGuard, this->sid, this->id );
}
this->piiu->uninstallChan ( guard, *this );
this->cacCtx.destroyChannel ( guard, *this );
}
void * nciu::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
this->piiu->uninstallChan ( mutualExcusionGuard, *this );
this->cacCtx.destroyChannel ( mutualExcusionGuard, *this );
}
void nciu::operator delete ( void * )
@@ -387,9 +382,12 @@ void nciu::subscribe (
}
void nciu::ioCancel (
epicsGuard < epicsMutex > & guard, const ioid & idIn )
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard,
const ioid & idIn )
{
this->cacCtx.destroyIO ( guard, idIn, *this );
this->cacCtx.destroyIO ( callbackGuard,
mutualExclusionGuard, idIn, *this );
}
void nciu::ioShow (

View File

@@ -121,7 +121,7 @@ private:
friend class disconnectGovernorTimer;
};
class privateInterfaceForIO { // X aCC 655
class privateInterfaceForIO {
public:
virtual void ioCompletionNotify (
epicsGuard < epicsMutex > &, class baseNMIU & ) = 0;
@@ -220,6 +220,7 @@ private:
ca_uint16_t typeCode;
ca_uint8_t priority;
virtual void destroy (
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard );
void initiateConnect (
epicsGuard < epicsMutex > & );
@@ -243,7 +244,15 @@ private:
epicsGuard < epicsMutex > & guard,
unsigned type, arrayElementCount nElem,
unsigned mask, cacStateNotify &notify, ioid * );
// The primary mutex must be released when calling the user's
// callback, and therefore a finite interval exists when we are
// moving forward with the intent to call the users callback
// but the users IO could be deleted during this interval.
// To prevent the user's callback from being called after
// destroying his IO we must past a guard for the callback
// mutex here.
virtual void ioCancel (
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard,
const ioid & );
void ioShow (
@@ -270,7 +279,6 @@ private:
epicsGuard < epicsMutex > & guard ) const throw ();
nciu ( const nciu & );
nciu & operator = ( const nciu & );
void * operator new ( size_t );
void operator delete ( void * );
};

View File

@@ -42,7 +42,7 @@
class privateInterfaceForIO;
class baseNMIU : public tsDLNode < baseNMIU >, // X aCC 655
class baseNMIU : public tsDLNode < baseNMIU >,
public chronIntIdRes < baseNMIU > {
public:
virtual void destroy (
@@ -106,7 +106,6 @@ private:
const unsigned mask;
bool subscribed;
class netSubscription * isSubscription ();
void * operator new ( size_t );
void operator delete ( void * );
void * operator new ( size_t,
tsFreeList < class netSubscription, 1024, epicsMutexNOOP > & );
@@ -147,7 +146,6 @@ protected:
private:
cacReadNotify & notify;
class privateInterfaceForIO & privateChanForIO;
void * operator new ( size_t );
void operator delete ( void * );
void * operator new ( size_t,
tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > & );
@@ -190,7 +188,6 @@ protected:
private:
cacWriteNotify & notify;
privateInterfaceForIO & privateChanForIO;
void * operator new ( size_t );
void operator delete ( void * );
void * operator new ( size_t,
tsFreeList < class netWriteNotifyIO, 1024, epicsMutexNOOP > & );
@@ -237,12 +234,12 @@ inline netSubscription * netSubscription::factory (
class privateInterfaceForIO & chan, unsigned type, arrayElementCount count,
unsigned mask, cacStateNotify &notify )
{
return new ( freeList ) netSubscription ( chan, type, // X aCC 930
return new ( freeList ) netSubscription ( chan, type,
count, mask, notify );
}
inline arrayElementCount netSubscription::getCount (
epicsGuard < epicsMutex > & guard, bool allow_zero ) const // X aCC 361
epicsGuard < epicsMutex > & guard, bool allow_zero ) const
{
//guard.assertIdenticalMutex ( this->mutex );
arrayElementCount nativeCount = this->privateChanForIO.nativeElementCount ( guard );
@@ -268,7 +265,7 @@ inline netReadNotifyIO * netReadNotifyIO::factory (
tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > & freeList,
privateInterfaceForIO & ioComplNotifIntf, cacReadNotify & notify )
{
return new ( freeList ) netReadNotifyIO ( ioComplNotifIntf, notify ); // X aCC 930
return new ( freeList ) netReadNotifyIO ( ioComplNotifIntf, notify );
}
inline void * netReadNotifyIO::operator new ( size_t size,
@@ -289,7 +286,7 @@ inline netWriteNotifyIO * netWriteNotifyIO::factory (
tsFreeList < class netWriteNotifyIO, 1024, epicsMutexNOOP > & freeList,
privateInterfaceForIO & ioComplNotifyIntf, cacWriteNotify & notify )
{
return new ( freeList ) netWriteNotifyIO ( ioComplNotifyIntf, notify ); // X aCC 930
return new ( freeList ) netWriteNotifyIO ( ioComplNotifyIntf, notify );
}
inline void * netWriteNotifyIO::operator new ( size_t size,

View File

@@ -119,13 +119,6 @@ void netReadNotifyIO::forceSubscriptionUpdate (
{
}
void * netReadNotifyIO::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void netReadNotifyIO::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if

View File

@@ -170,13 +170,6 @@ void netSubscription::forceSubscriptionUpdate (
guard, chan, *this );
}
void * netSubscription::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void netSubscription::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if

View File

@@ -117,14 +117,6 @@ void netWriteNotifyIO::forceSubscriptionUpdate (
{
}
void * netWriteNotifyIO::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error (
"why is the compiler calling private operator new" );
}
void netWriteNotifyIO::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if

View File

@@ -35,7 +35,7 @@ union osiSockAddr;
class cac;
class nciu;
class netiiu { // X aCC 655
class netiiu {
public:
virtual ~netiiu () = 0;
virtual unsigned getHostName (

View File

@@ -53,7 +53,8 @@ public:
const char * pName, caCh * pConnCallBackIn,
void * pPrivateIn, capri priority );
void destructor (
epicsGuard < epicsMutex > & guard );
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & mutexGuard );
// legacy C API
friend unsigned epicsShareAPI ca_get_host_name (
@@ -122,6 +123,7 @@ public:
unsigned type, arrayElementCount count, const void *pValue,
cacWriteNotify &, cacChannel::ioid *pId = 0 );
void ioCancel (
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard,
const cacChannel::ioid & );
void ioShow (
@@ -162,7 +164,6 @@ private:
unsigned type, arrayElementCount count );
oldChannelNotify ( const oldChannelNotify & );
oldChannelNotify & operator = ( const oldChannelNotify & );
void * operator new ( size_t size );
void operator delete ( void * );
};
@@ -195,7 +196,6 @@ private:
const char *pContext, unsigned type, arrayElementCount count );
getCopy ( const getCopy & );
getCopy & operator = ( const getCopy & );
void * operator new ( size_t size );
void operator delete ( void * );
};
@@ -221,7 +221,6 @@ private:
const char * pContext, unsigned type, arrayElementCount count );
getCallback ( const getCallback & );
getCallback & operator = ( const getCallback & );
void * operator new ( size_t size );
void operator delete ( void * );
};
@@ -245,7 +244,6 @@ private:
unsigned type, arrayElementCount count );
putCallback ( const putCallback & );
putCallback & operator = ( const putCallback & );
void * operator new ( size_t size );
void operator delete ( void * );
};
@@ -259,8 +257,16 @@ public:
evid * );
~oldSubscription ();
oldChannelNotify & channel () const;
// The primary mutex must be released when calling the user's
// callback, and therefore a finite interval exists when we are
// moving forward with the intent to call the users callback
// but the users IO could be deleted during this interval.
// To prevent the user's callback from being called after
// destroying his IO we must past a guard for the callback
// mutex here.
void cancel (
epicsGuard < epicsMutex > & guard );
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard );
void * operator new ( size_t size,
tsFreeList < struct oldSubscription, 1024, epicsMutexNOOP > & );
epicsPlacementDeleteOperator (( void *,
@@ -278,7 +284,6 @@ private:
const char *pContext, unsigned type, arrayElementCount count );
oldSubscription ( const oldSubscription & );
oldSubscription & operator = ( const oldSubscription & );
void * operator new ( size_t size );
void operator delete ( void * );
};
@@ -341,6 +346,8 @@ public:
void destroySubscription ( epicsGuard < epicsMutex > &, oldSubscription & );
epicsMutex & mutexRef () const;
template < class T >
void whenThereIsAnExceptionDestroySyncGroupIO ( epicsGuard < epicsMutex > &, T & );
// legacy C API
friend int epicsShareAPI ca_create_channel (
@@ -368,6 +375,17 @@ public:
friend int epicsShareAPI ca_sg_block ( const CA_SYNC_GID gid, ca_real timeout );
friend int epicsShareAPI ca_sg_reset ( const CA_SYNC_GID gid );
friend int epicsShareAPI ca_sg_test ( const CA_SYNC_GID gid );
friend int epicsShareAPI ca_sg_array_get ( const CA_SYNC_GID gid,
chtype type, arrayElementCount count,
chid pChan, void *pValue );
friend int epicsShareAPI ca_sg_array_put ( const CA_SYNC_GID gid,
chtype type, arrayElementCount count,
chid pChan, const void *pValue );
friend int ca_sync_group_destroy ( CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard,
ca_client_context & cac, const CA_SYNC_GID gid );
friend void sync_group_reset ( ca_client_context & client,
CASG & sg );
// exceptions
class noSocket {};
@@ -384,7 +402,7 @@ private:
epicsEvent ioDone;
epicsEvent callbackThreadActivityComplete;
epicsThreadId createdByThread;
epics_auto_ptr < epicsGuard < epicsMutex > > pCallbackGuard;
epics_auto_ptr < CallbackGuard > pCallbackGuard;
epics_auto_ptr < cacContext > pServiceContext;
caExceptionHandler * ca_exception_func;
void * ca_exception_arg;
@@ -444,10 +462,11 @@ inline void oldChannelNotify::initiateConnect (
}
inline void oldChannelNotify::ioCancel (
epicsGuard < epicsMutex > & guard,
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard,
const cacChannel::ioid & id )
{
this->io.ioCancel ( guard, id );
this->io.ioCancel ( callbackGuard, mutualExclusionGuard, id );
}
inline void oldChannelNotify::ioShow (
@@ -492,9 +511,10 @@ inline void oldSubscription::operator delete ( void *pCadaver,
#endif
inline void oldSubscription::cancel (
epicsGuard < epicsMutex > & guard )
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard )
{
this->chan.ioCancel ( guard, this->id );
this->chan.ioCancel ( callbackGuard, mutualExclusionGuard, this->id );
}
inline oldChannelNotify & oldSubscription::channel () const
@@ -560,5 +580,32 @@ inline unsigned ca_client_context::sequenceNumberOfOutstandingIO (
// perhaps on SMP systems THERE should be lock/unlock around this
return this->ioSeqNo;
}
template < class T >
void ca_client_context :: whenThereIsAnExceptionDestroySyncGroupIO (
epicsGuard < epicsMutex > & guard, T & io )
{
if ( this->pCallbackGuard.get() &&
this->createdByThread == epicsThreadGetIdSelf () ) {
io.destroy ( *this->pCallbackGuard.get(), guard );
}
else {
// dont reverse the lock hierarchy
epicsGuardRelease < epicsMutex > guardRelease ();
{
//
// we will definately stall out here if all of the
// following are true
//
// o user creates non-preemtive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
//
CallbackGuard cbGuard ( this->cbMutex );
epicsGuard < epicsMutex > guard ( this->mutex );
io.destroy ( cbGuard, guard );
}
}
}
#endif // ifndef oldAccessh

View File

@@ -65,14 +65,15 @@ oldChannelNotify::~oldChannelNotify ()
}
void oldChannelNotify::destructor (
epicsGuard < epicsMutex > & guard )
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & mutexGuard )
{
guard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
this->io.destroy ( guard );
mutexGuard.assertIdenticalMutex ( this->cacCtx.mutexRef () );
this->io.destroy ( cbGuard, mutexGuard );
// no need to worry about a connect preempting here because
// the io (the nciu) has been destroyed above
if ( this->pConnCallBack == 0 && ! this->currentlyConnected ) {
this->cacCtx.decrementOutstandingIO ( guard, this->ioSeqNo );
this->cacCtx.decrementOutstandingIO ( mutexGuard, this->ioSeqNo );
}
this->~oldChannelNotify ();
}
@@ -159,13 +160,6 @@ void oldChannelNotify::writeException (
__FILE__, __LINE__, *this, type, count, CA_OP_PUT );
}
void * oldChannelNotify::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void oldChannelNotify::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if
@@ -638,7 +632,7 @@ arrayElementCount epicsShareAPI ca_element_count ( chid pChan )
/*
* ca_state ()
*/
enum channel_state epicsShareAPI ca_state ( chid pChan ) // X aCC 361
enum channel_state epicsShareAPI ca_state ( chid pChan )
{
epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
if ( pChan->io.connected ( guard ) ) {

View File

@@ -90,13 +90,6 @@ void putCallback::exception (
}
}
void * putCallback::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void putCallback::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if

View File

@@ -178,7 +178,7 @@ bool repeaterClient::connect ()
return true;
}
bool repeaterClient::sendConfirm () // X aCC 361
bool repeaterClient::sendConfirm ()
{
int status;
@@ -204,7 +204,7 @@ bool repeaterClient::sendConfirm () // X aCC 361
}
}
bool repeaterClient::sendMessage ( const void *pBuf, unsigned bufSize ) // X aCC 361
bool repeaterClient::sendMessage ( const void *pBuf, unsigned bufSize )
{
int status;
@@ -245,13 +245,6 @@ repeaterClient::~repeaterClient ()
#endif
}
void * repeaterClient::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void repeaterClient::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if
@@ -304,7 +297,7 @@ inline bool repeaterClient::identicalPort ( const osiSockAddr &fromIn )
return false;
}
bool repeaterClient::verify () // X aCC 361
bool repeaterClient::verify ()
{
SOCKET tmpSock;
bool success = makeSocket ( this->port (), false, & tmpSock );

View File

@@ -64,7 +64,6 @@ private:
osiSockAddr from;
SOCKET sock;
unsigned short port () const;
void * operator new ( size_t size );
void operator delete ( void * );
};

View File

@@ -64,7 +64,7 @@ void repeaterSubscribeTimer::shutdown (
}
epicsTimerNotify::expireStatus repeaterSubscribeTimer::
expire ( const epicsTime & /* currentTime */ ) // X aCC 361
expire ( const epicsTime & /* currentTime */ )
{
static const unsigned nTriesToMsg = 50;
if ( this->attempts > nTriesToMsg && ! this->once ) {

View File

@@ -43,7 +43,7 @@
class epicsMutex;
class cacContextNotify;
class repeaterTimerNotify { // X aCC 655
class repeaterTimerNotify {
public:
virtual ~repeaterTimerNotify () = 0;
virtual void repeaterRegistrationMessage (

View File

@@ -124,7 +124,7 @@ void searchTimer::moveChannels (
// searchTimer::expire ()
//
epicsTimerNotify::expireStatus searchTimer::expire (
const epicsTime & currentTime ) // X aCC 361
const epicsTime & currentTime )
{
epicsGuard < epicsMutex > guard ( this->mutex );

View File

@@ -43,7 +43,7 @@
#include "caProto.h"
#include "netiiu.h"
class searchTimerNotify { // X aCC 655
class searchTimerNotify {
public:
virtual ~searchTimerNotify () = 0;
virtual void boostChannel (

View File

@@ -29,8 +29,7 @@
template < class T >
class sgAutoPtr {
public:
sgAutoPtr ( epicsGuard < epicsMutex > &,
struct CASG &, tsDLList < syncGroupNotify > & );
sgAutoPtr ( epicsGuard < epicsMutex > &, struct CASG & );
~sgAutoPtr ();
sgAutoPtr < T > & operator = ( T * );
T * operator -> ();
@@ -38,7 +37,6 @@ public:
T * get ();
T * release ();
private:
tsDLList < syncGroupNotify > & list;
T * pNotify;
struct CASG & sg;
epicsGuard < epicsMutex > & guard;
@@ -47,9 +45,8 @@ private:
template < class T >
inline sgAutoPtr < T > :: sgAutoPtr (
epicsGuard < epicsMutex > & guardIn,
struct CASG & sgIn, tsDLList < syncGroupNotify > & listIn ) :
list ( listIn ), pNotify ( 0 ), sg ( sgIn ), guard ( guardIn )
epicsGuard < epicsMutex > & guardIn, struct CASG & sgIn ) :
pNotify ( 0 ), sg ( sgIn ), guard ( guardIn )
{
}
@@ -57,8 +54,9 @@ template < class T >
inline sgAutoPtr < T > :: ~sgAutoPtr ()
{
if ( this->pNotify ) {
list.remove ( *this->pNotify );
pNotify->destroy ( this->guard, this->sg );
this->sg.ioPendingList.remove ( *this->pNotify );
this->sg.client.
whenThereIsAnExceptionDestroySyncGroupIO ( this->guard, *this->pNotify );
}
}
@@ -66,11 +64,12 @@ template < class T >
inline sgAutoPtr < T > & sgAutoPtr < T > :: operator = ( T * pNotifyIn )
{
if ( this->pNotify ) {
list.remove ( *this->pNotify );
pNotify->destroy ( this->guard, this->sg );
this->sg.ioPendingList.remove ( *this->pNotify );
this->sg.client.
whenThereIsAnExceptionDestroySyncGroupIO ( this->guard, *this->pNotify );
}
this->pNotify = pNotifyIn;
list.add ( *this->pNotify );
this->sg.ioPendingList.add ( *this->pNotify );
return *this;
}

View File

@@ -46,29 +46,17 @@
static const unsigned CASG_MAGIC = 0xFAB4CAFE;
// used to control access to CASG's recycle routines which
// should only be indirectly invoked by CASG when its lock
// is applied
class casgRecycle { // X aCC 655
public:
virtual void recycleSyncGroupWriteNotify (
epicsGuard < epicsMutex > &, class syncGroupWriteNotify & io ) = 0;
virtual void recycleSyncGroupReadNotify (
epicsGuard < epicsMutex > &, class syncGroupReadNotify & io ) = 0;
protected:
virtual ~casgRecycle ();
};
class syncGroupNotify : public tsDLNode < syncGroupNotify > {
public:
syncGroupNotify ();
virtual void destroy (
epicsGuard < epicsMutex > & guard,
casgRecycle & ) = 0;
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard ) = 0;
virtual bool ioPending (
epicsGuard < epicsMutex > & guard ) = 0;
virtual void cancel (
epicsGuard < epicsMutex > & guard ) = 0;
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0;
virtual void show (
epicsGuard < epicsMutex > &,
unsigned level ) const = 0;
@@ -78,33 +66,38 @@ protected:
syncGroupNotify & operator = ( const syncGroupNotify & );
};
struct CASG;
class syncGroupReadNotify : public syncGroupNotify, public cacReadNotify {
public:
typedef void ( CASG :: * PRecycleFunc )
( epicsGuard < epicsMutex > &, syncGroupReadNotify & );
static syncGroupReadNotify * factory (
tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > &,
struct CASG &, chid, void *pValueIn );
CASG &, PRecycleFunc, chid, void *pValueIn );
void destroy (
epicsGuard < epicsMutex > & guard,
casgRecycle & );
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard );
bool ioPending (
epicsGuard < epicsMutex > & guard );
void begin ( epicsGuard < epicsMutex > &,
unsigned type, arrayElementCount count );
void cancel (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard );
void show ( epicsGuard < epicsMutex > &, unsigned level ) const;
protected:
syncGroupReadNotify ( struct CASG & sgIn, chid, void * pValueIn );
syncGroupReadNotify ( CASG & sgIn, PRecycleFunc, chid, void * pValueIn );
virtual ~syncGroupReadNotify ();
private:
chid chan;
struct CASG & sg;
PRecycleFunc pRecycleFunc;
CASG & sg;
void * pValue;
const unsigned magic;
cacChannel::ioid id;
bool idIsValid;
bool ioComplete;
void * operator new ( size_t );
void operator delete ( void * );
void * operator new ( size_t,
tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > & );
@@ -122,30 +115,33 @@ private:
class syncGroupWriteNotify : public syncGroupNotify, public cacWriteNotify {
public:
typedef void ( CASG :: * PRecycleFunc )
( epicsGuard < epicsMutex > &, syncGroupWriteNotify & );
static syncGroupWriteNotify * factory (
tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > &,
struct CASG &, chid );
CASG &, PRecycleFunc, chid );
void destroy (
epicsGuard < epicsMutex > & guard,
casgRecycle & );
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard );
bool ioPending (
epicsGuard < epicsMutex > & guard );
void begin ( epicsGuard < epicsMutex > &, unsigned type,
arrayElementCount count, const void * pValueIn );
void cancel (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard );
void show ( epicsGuard < epicsMutex > &, unsigned level ) const;
protected:
syncGroupWriteNotify ( struct CASG &, chid );
syncGroupWriteNotify ( struct CASG &, PRecycleFunc, chid );
virtual ~syncGroupWriteNotify (); // allocate only from pool
private:
chid chan;
struct CASG & sg;
PRecycleFunc pRecycleFunc;
CASG & sg;
const unsigned magic;
cacChannel::ioid id;
bool idIsValid;
bool ioComplete;
void * operator new ( size_t );
void operator delete ( void * );
void * operator new ( size_t,
tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > & );
@@ -163,17 +159,19 @@ struct ca_client_context;
template < class T > class sgAutoPtr;
struct CASG : public chronIntIdRes < CASG >, private casgRecycle {
struct CASG : public chronIntIdRes < CASG > {
public:
CASG ( epicsGuard < epicsMutex > &, ca_client_context & cacIn );
void destructor (
CallbackGuard &,
epicsGuard < epicsMutex > & guard );
bool ioComplete (
CallbackGuard &,
epicsGuard < epicsMutex > & guard );
bool verify ( epicsGuard < epicsMutex > & ) const;
int block ( epicsGuard < epicsMutex > * pcbGuard,
epicsGuard < epicsMutex > & guard, double timeout );
void reset ( epicsGuard < epicsMutex > & guard );
void reset ( CallbackGuard &, epicsGuard < epicsMutex > & );
void show ( epicsGuard < epicsMutex > &, unsigned level ) const;
void show ( unsigned level ) const;
void get ( epicsGuard < epicsMutex > &, chid pChan,
@@ -194,6 +192,7 @@ public:
tsFreeList < struct CASG, 128, epicsMutexNOOP > & );
epicsPlacementDeleteOperator (( void *,
tsFreeList < struct CASG, 128, epicsMutexNOOP > & ))
private:
tsDLList < syncGroupNotify > ioPendingList;
tsDLList < syncGroupNotify > ioCompletedList;
@@ -202,20 +201,21 @@ private:
unsigned magic;
tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > freeListReadOP;
tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > freeListWriteOP;
void recycleSyncGroupWriteNotify (
epicsGuard < epicsMutex > &, syncGroupWriteNotify & io );
void recycleSyncGroupReadNotify (
epicsGuard < epicsMutex > &, syncGroupReadNotify & io );
void destroyPendingIO (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard );
void destroyCompletedIO (
CallbackGuard & cbGuard,
epicsGuard < epicsMutex > & guard );
void recycleReadNotifyIO ( epicsGuard < epicsMutex > &,
syncGroupReadNotify & );
void recycleWriteNotifyIO ( epicsGuard < epicsMutex > &,
syncGroupWriteNotify & );
CASG ( const CASG & );
CASG & operator = ( const CASG & );
void * operator new ( size_t size );
void operator delete ( void * );
~CASG ();

View File

@@ -27,8 +27,10 @@
#include "oldAccess.h"
syncGroupReadNotify::syncGroupReadNotify (
CASG & sgIn, chid pChan, void * pValueIn ) :
chan ( pChan ), sg ( sgIn ), pValue ( pValueIn ),
CASG & sgIn, PRecycleFunc pRecycleFuncIn,
chid pChan, void * pValueIn ) :
chan ( pChan ), pRecycleFunc ( pRecycleFuncIn ),
sg ( sgIn ), pValue ( pValueIn ),
magic ( CASG_MAGIC ), id ( 0u ),
idIsValid ( false ), ioComplete ( false )
{
@@ -46,27 +48,30 @@ void syncGroupReadNotify::begin (
}
void syncGroupReadNotify::cancel (
epicsGuard < epicsMutex > & guard )
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExcusionGuard )
{
if ( this->idIsValid ) {
this->chan->ioCancel ( guard, this->id );
this->chan->ioCancel ( callbackGuard, mutualExcusionGuard, this->id );
this->idIsValid = false;
}
}
syncGroupReadNotify * syncGroupReadNotify::factory (
tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > & freeList,
struct CASG & sg, chid chan, void * pValueIn )
struct CASG & sg, PRecycleFunc pRecycleFunc, chid chan, void * pValueIn )
{
return new ( freeList ) // X aCC 930
syncGroupReadNotify ( sg, chan, pValueIn );
return new ( freeList )
syncGroupReadNotify ( sg, pRecycleFunc, chan, pValueIn );
}
void syncGroupReadNotify::destroy (
epicsGuard < epicsMutex > & guard, casgRecycle & recycle )
CallbackGuard &,
epicsGuard < epicsMutex > & guard )
{
CASG & sgRef ( this->sg );
this->~syncGroupReadNotify ();
recycle.recycleSyncGroupReadNotify ( guard, *this );
( sgRef.*pRecycleFunc ) ( guard, *this );
}
syncGroupReadNotify::~syncGroupReadNotify ()
@@ -122,13 +127,6 @@ void syncGroupReadNotify::show (
}
}
void * syncGroupReadNotify::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void syncGroupReadNotify::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if

View File

@@ -26,8 +26,10 @@
#include "syncGroup.h"
#include "oldAccess.h"
syncGroupWriteNotify::syncGroupWriteNotify ( CASG & sgIn, chid pChan ) :
chan ( pChan ), sg ( sgIn ), magic ( CASG_MAGIC ),
syncGroupWriteNotify::syncGroupWriteNotify ( CASG & sgIn,
PRecycleFunc pRecycleFuncIn, chid pChan ) :
chan ( pChan ), pRecycleFunc ( pRecycleFuncIn ),
sg ( sgIn ), magic ( CASG_MAGIC ),
id ( 0u ), idIsValid ( false ), ioComplete ( false )
{
}
@@ -45,26 +47,29 @@ void syncGroupWriteNotify::begin (
}
void syncGroupWriteNotify::cancel (
epicsGuard < epicsMutex > & guard )
CallbackGuard & callbackGuard,
epicsGuard < epicsMutex > & mutualExcusionGuard )
{
if ( this->idIsValid ) {
this->chan->ioCancel ( guard, this->id );
this->chan->ioCancel ( callbackGuard, mutualExcusionGuard, this->id );
this->idIsValid = false;
}
}
syncGroupWriteNotify * syncGroupWriteNotify::factory (
tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > &freeList,
struct CASG & sg, chid chan )
struct CASG & sg, PRecycleFunc pRecycleFunc, chid chan )
{
return new ( freeList ) syncGroupWriteNotify ( sg, chan );
return new ( freeList ) syncGroupWriteNotify ( sg, pRecycleFunc, chan );
}
void syncGroupWriteNotify::destroy (
epicsGuard < epicsMutex > & guard, casgRecycle & recycle )
CallbackGuard &,
epicsGuard < epicsMutex > & guard )
{
CASG & sgRef ( this->sg );
this->~syncGroupWriteNotify ();
recycle.recycleSyncGroupWriteNotify ( guard, *this );
( sgRef.*pRecycleFunc ) ( guard, *this );
}
syncGroupWriteNotify::~syncGroupWriteNotify ()
@@ -112,13 +117,6 @@ void syncGroupWriteNotify::show (
}
}
void * syncGroupWriteNotify::operator new ( size_t ) // X aCC 361
{
// The HPUX compiler seems to require this even though no code
// calls it directly
throw std::logic_error ( "why is the compiler calling private operator new" );
}
void syncGroupWriteNotify::operator delete ( void * )
{
// Visual C++ .net appears to require operator delete if

View File

@@ -23,7 +23,7 @@
/*
* ca_sg_create()
*/
extern "C" int epicsShareAPI ca_sg_create ( CA_SYNC_GID * pgid ) // X aCC 361
extern "C" int epicsShareAPI ca_sg_create ( CA_SYNC_GID * pgid )
{
ca_client_context * pcac;
int caStatus;
@@ -48,6 +48,22 @@ extern "C" int epicsShareAPI ca_sg_create ( CA_SYNC_GID * pgid ) // X aCC 361
}
}
int ca_sync_group_destroy ( CallbackGuard & cbGuard, epicsGuard < epicsMutex > & guard,
ca_client_context & cac, const CA_SYNC_GID gid )
{
int caStatus;
CASG * pcasg = cac.lookupCASG ( guard, gid );
if ( pcasg ) {
pcasg->destructor ( cbGuard, guard );
cac.casgFreeList.release ( pcasg );
caStatus = ECA_NORMAL;
}
else {
caStatus = ECA_BADSYNCGRP;
}
return caStatus;
}
/*
* ca_sg_delete()
*/
@@ -56,19 +72,51 @@ extern "C" int epicsShareAPI ca_sg_delete ( const CA_SYNC_GID gid )
ca_client_context * pcac;
int caStatus = fetchClientContext ( & pcac );
if ( caStatus == ECA_NORMAL ) {
epicsGuard < epicsMutex > guard ( pcac->mutexRef() );
CASG * pcasg = pcac->lookupCASG ( guard, gid );
if ( pcasg ) {
pcasg->destructor ( guard );
pcac->casgFreeList.release ( pcasg );
if ( pcac->pCallbackGuard.get() &&
pcac->createdByThread == epicsThreadGetIdSelf () ) {
epicsGuard < epicsMutex > guard ( pcac->mutex );
caStatus = ca_sync_group_destroy ( *pcac->pCallbackGuard.get(),
guard, *pcac, gid );
}
else {
caStatus = ECA_BADSYNCGRP;
//
// we will definately stall out here if all of the
// following are true
//
// o user creates non-preemtive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
//
CallbackGuard cbGuard ( pcac->cbMutex );
epicsGuard < epicsMutex > guard ( pcac->mutex );
caStatus = ca_sync_group_destroy ( cbGuard, guard, *pcac, gid );
}
}
return caStatus;
}
void sync_group_reset ( ca_client_context & client, CASG & sg )
{
if ( client.pCallbackGuard.get() &&
client.createdByThread == epicsThreadGetIdSelf () ) {
epicsGuard < epicsMutex > guard ( client.mutex );
sg.reset ( *client.pCallbackGuard.get(), guard );
}
else {
//
// we will definately stall out here if all of the
// following are true
//
// o user creates non-preemtive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
//
CallbackGuard cbGuard ( client.cbMutex );
epicsGuard < epicsMutex > guard ( client.mutex );
sg.reset ( cbGuard, guard );
}
}
//
// ca_sg_block ()
//
@@ -84,14 +132,20 @@ extern "C" int epicsShareAPI ca_sg_block (
ca_client_context *pcac;
int status = fetchClientContext ( &pcac );
if ( status == ECA_NORMAL ) {
CASG * pcasg;
{
epicsGuard < epicsMutex > guard ( pcac->mutex );
CASG * pcasg = pcac->lookupCASG ( guard, gid );
if ( ! pcasg ) {
status = ECA_BADSYNCGRP;
}
else {
pcasg = pcac->lookupCASG ( guard, gid );
if ( pcasg ) {
status = pcasg->block (
pcac->pCallbackGuard.get (), guard, timeout );
}
else {
status = ECA_BADSYNCGRP;
}
}
if ( pcasg ) {
sync_group_reset ( *pcac, *pcasg );
}
}
return status;
@@ -105,10 +159,14 @@ extern "C" int epicsShareAPI ca_sg_reset ( const CA_SYNC_GID gid )
ca_client_context *pcac;
int caStatus = fetchClientContext (&pcac);
if ( caStatus == ECA_NORMAL ) {
CASG * pcasg;
{
epicsGuard < epicsMutex > guard ( pcac->mutex );
CASG * pcasg = pcac->lookupCASG ( guard, gid );
pcasg = pcac->lookupCASG ( guard, gid );
}
if ( pcasg ) {
pcasg->reset ( guard );
sync_group_reset ( *pcac, *pcasg );
caStatus = ECA_NORMAL;
}
else {
caStatus = ECA_BADSYNCGRP;
@@ -143,7 +201,7 @@ extern "C" int epicsShareAPI ca_sg_stat ( const CA_SYNC_GID gid )
/*
* ca_sg_test
*/
extern "C" int epicsShareAPI ca_sg_test ( const CA_SYNC_GID gid ) // X aCC 361
extern "C" int epicsShareAPI ca_sg_test ( const CA_SYNC_GID gid )
{
ca_client_context * pcac;
int caStatus = fetchClientContext ( &pcac );
@@ -151,7 +209,26 @@ extern "C" int epicsShareAPI ca_sg_test ( const CA_SYNC_GID gid ) // X aCC 361
epicsGuard < epicsMutex > guard ( pcac->mutexRef() );
CASG * pcasg = pcac->lookupCASG ( guard, gid );
if ( pcasg ) {
if ( pcasg->ioComplete ( guard ) ) {
bool isComplete;
if ( pcac->pCallbackGuard.get() &&
pcac->createdByThread == epicsThreadGetIdSelf () ) {
epicsGuard < epicsMutex > guard ( pcac->mutex );
isComplete = pcasg->ioComplete ( *pcac->pCallbackGuard.get(), guard );
}
else {
//
// we will definately stall out here if all of the
// following are true
//
// o user creates non-preemtive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
//
CallbackGuard cbGuard ( pcac->cbMutex );
epicsGuard < epicsMutex > guard ( pcac->mutex );
isComplete = pcasg->ioComplete ( cbGuard, guard );
}
if ( isComplete ) {
caStatus = ECA_IODONE;
}
else{
@@ -172,17 +249,14 @@ extern "C" int epicsShareAPI ca_sg_array_put ( const CA_SYNC_GID gid, chtype typ
arrayElementCount count, chid pChan, const void *pValue )
{
ca_client_context *pcac;
CASG *pcasg;
int caStatus;
caStatus = fetchClientContext ( &pcac );
int caStatus = fetchClientContext ( &pcac );
if ( caStatus != ECA_NORMAL ) {
return caStatus;
}
epicsGuard < epicsMutex > guard ( pcac->mutexRef() );
pcasg = pcac->lookupCASG ( guard, gid );
CASG * const pcasg = pcac->lookupCASG ( guard, gid );
if ( ! pcasg ) {
return ECA_BADSYNCGRP;
}
@@ -237,17 +311,14 @@ extern "C" int epicsShareAPI ca_sg_array_get ( const CA_SYNC_GID gid, chtype typ
arrayElementCount count, chid pChan, void *pValue )
{
ca_client_context *pcac;
CASG *pcasg;
int caStatus;
caStatus = fetchClientContext ( &pcac );
int caStatus = fetchClientContext ( &pcac );
if ( caStatus != ECA_NORMAL ) {
return caStatus;
}
epicsGuard < epicsMutex > guard ( pcac->mutexRef() );
pcasg = pcac->lookupCASG ( guard, gid );
CASG * const pcasg = pcac->lookupCASG ( guard, gid );
if ( ! pcasg ) {
return ECA_BADSYNCGRP;
}

View File

@@ -45,7 +45,7 @@ tcpRecvWatchdog::~tcpRecvWatchdog ()
}
epicsTimerNotify::expireStatus
tcpRecvWatchdog::expire ( const epicsTime & /* currentTime */ ) // X aCC 361
tcpRecvWatchdog::expire ( const epicsTime & /* currentTime */ )
{
epicsGuard < epicsMutex > guard ( this->mutex );
if ( this->shuttingDown ) {

View File

@@ -1135,7 +1135,7 @@ void tcpiiu::show ( unsigned level ) const
}
}
bool tcpiiu::setEchoRequestPending ( epicsGuard < epicsMutex > & guard ) // X aCC 361
bool tcpiiu::setEchoRequestPending ( epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1275,12 +1275,9 @@ bool tcpiiu::processIncoming (
this->msgHeaderAvailable = false;
this->curDataBytes = 0u;
}
# if defined ( __HP_aCC ) && _HP_aCC <= 033300
return false; // to make hpux compiler happy...
# endif
}
void tcpiiu::hostNameSetRequest ( epicsGuard < epicsMutex > & guard ) // X aCC 431
void tcpiiu::hostNameSetRequest ( epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1310,7 +1307,7 @@ void tcpiiu::hostNameSetRequest ( epicsGuard < epicsMutex > & guard ) // X aCC 4
/*
* tcpiiu::userNameSetRequest ()
*/
void tcpiiu::userNameSetRequest ( epicsGuard < epicsMutex > & guard ) // X aCC 431
void tcpiiu::userNameSetRequest ( epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1338,7 +1335,7 @@ void tcpiiu::userNameSetRequest ( epicsGuard < epicsMutex > & guard ) // X aCC 4
}
void tcpiiu::disableFlowControlRequest (
epicsGuard < epicsMutex > & guard ) // X aCC 431
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1354,7 +1351,7 @@ void tcpiiu::disableFlowControlRequest (
}
void tcpiiu::enableFlowControlRequest (
epicsGuard < epicsMutex > & guard ) // X aCC 431
epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1369,7 +1366,7 @@ void tcpiiu::enableFlowControlRequest (
minder.commit ();
}
void tcpiiu::versionMessage ( epicsGuard < epicsMutex > & guard, // X aCC 431
void tcpiiu::versionMessage ( epicsGuard < epicsMutex > & guard,
const cacChannel::priLev & priority )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1389,7 +1386,7 @@ void tcpiiu::versionMessage ( epicsGuard < epicsMutex > & guard, // X aCC 431
minder.commit ();
}
void tcpiiu::echoRequest ( epicsGuard < epicsMutex > & guard ) // X aCC 431
void tcpiiu::echoRequest ( epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1410,7 +1407,7 @@ void tcpiiu::echoRequest ( epicsGuard < epicsMutex > & guard ) // X aCC 431
minder.commit ();
}
void tcpiiu::writeRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431
void tcpiiu::writeRequest ( epicsGuard < epicsMutex > & guard,
nciu &chan, unsigned type, arrayElementCount nElem, const void *pValue )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1425,7 +1422,7 @@ void tcpiiu::writeRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431
}
void tcpiiu::writeNotifyRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431
void tcpiiu::writeNotifyRequest ( epicsGuard < epicsMutex > & guard,
nciu &chan, netWriteNotifyIO &io, unsigned type,
arrayElementCount nElem, const void *pValue )
{
@@ -1444,7 +1441,7 @@ void tcpiiu::writeNotifyRequest ( epicsGuard < epicsMutex > & guard, // X aCC 43
minder.commit ();
}
void tcpiiu::readNotifyRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431
void tcpiiu::readNotifyRequest ( epicsGuard < epicsMutex > & guard,
nciu & chan, netReadNotifyIO & io,
unsigned dataType, arrayElementCount nElem )
{
@@ -1477,7 +1474,7 @@ void tcpiiu::readNotifyRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431
}
void tcpiiu::createChannelRequest (
nciu & chan, epicsGuard < epicsMutex > & guard ) // X aCC 431
nciu & chan, epicsGuard < epicsMutex > & guard )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1525,7 +1522,7 @@ void tcpiiu::createChannelRequest (
minder.commit ();
}
void tcpiiu::clearChannelRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431
void tcpiiu::clearChannelRequest ( epicsGuard < epicsMutex > & guard,
ca_uint32_t sid, ca_uint32_t cid )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1547,7 +1544,7 @@ void tcpiiu::clearChannelRequest ( epicsGuard < epicsMutex > & guard, // X aCC 4
// is to try again the next time that we reconnect
//
void tcpiiu::subscriptionRequest (
epicsGuard < epicsMutex > & guard, // X aCC 431
epicsGuard < epicsMutex > & guard,
nciu & chan, netSubscription & subscr )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1599,7 +1596,7 @@ void tcpiiu::subscriptionRequest (
// is to try again the next time that we reconnect
//
void tcpiiu::subscriptionUpdateRequest (
epicsGuard < epicsMutex > & guard, // X aCC 431
epicsGuard < epicsMutex > & guard,
nciu & chan, netSubscription & subscr )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -1634,7 +1631,7 @@ void tcpiiu::subscriptionUpdateRequest (
minder.commit ();
}
void tcpiiu::subscriptionCancelRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431
void tcpiiu::subscriptionCancelRequest ( epicsGuard < epicsMutex > & guard,
nciu & chan, netSubscription & subscr )
{
guard.assertIdenticalMutex ( this->mutex );
@@ -2052,7 +2049,7 @@ bool tcpiiu::bytesArePendingInOS () const
return false;
#else
osiSockIoctl_t bytesPending = 0; /* shut up purifys yapping */
int status = socket_ioctl ( this->sock, // X aCC 392
int status = socket_ioctl ( this->sock,
FIONREAD, & bytesPending );
if ( status >= 0 ) {
if ( bytesPending > 0 ) {

View File

@@ -78,6 +78,10 @@ template comBuf :: popStatus comBuf :: pop ( unsigned char & returnVal );
template void WireSet ( float const &, unsigned char * );
template void WireSet ( int const &, unsigned char * );
template void WireSet ( short const &, unsigned char * );
template void ca_client_context :: whenThereIsAnExceptionDestroySyncGroupIO
(epicsGuard < epicsMutex > &, syncGroupWriteNotify & );
template void ca_client_context :: whenThereIsAnExceptionDestroySyncGroupIO
( epicsGuard < epicsMutex > &, syncGroupReadNotify & );
#ifdef _MSC_VER

View File

@@ -14,7 +14,7 @@
* simple stub for testing monitors
*/
#include <stdio.h>
#include "epicsStdioRedirect.h"
#define epicsExportSharedSymbols
#include "cadef.h"
@@ -78,7 +78,7 @@ extern "C" void epicsShareAPI ca_dump_dbr (
dbr_short_t *pvalue = (dbr_short_t *)pbuffer;
for (i = 0; i < count; i++,pvalue++){
if(count!=1 && (i%10 == 0)) printf("\n");
printf("%d ",* (short *)pvalue); // X aCC 392
printf("%d ",* (short *)pvalue);
}
break;
}
@@ -96,7 +96,7 @@ extern "C" void epicsShareAPI ca_dump_dbr (
dbr_float_t *pvalue = (dbr_float_t *)pbuffer;
for (i = 0; i < count; i++,pvalue++){
if(count!=1 && (i%10 == 0)) printf("\n");
printf("%6.4f ",*(float *)pvalue); // X aCC 392
printf("%6.4f ",*(float *)pvalue);
}
break;
}

View File

@@ -201,7 +201,7 @@ udpiiu::udpiiu (
memset ( (char *)&addr, 0 , sizeof (addr) );
addr.ia.sin_family = AF_INET;
addr.ia.sin_addr.s_addr = htonl ( INADDR_ANY );
addr.ia.sin_port = htons ( PORT_ANY ); // X aCC 818
addr.ia.sin_port = htons ( PORT_ANY );
status = bind (this->sock, &addr.sa, sizeof (addr) );
if ( status < 0 ) {
char sockErrBuf[64];
@@ -471,7 +471,7 @@ void epicsShareAPI caRepeaterRegistrationMessage (
}
memset ( (char *) &msg, 0, sizeof (msg) );
AlignedWireRef < epicsUInt16 > ( msg.m_cmmd ) = REPEATER_REGISTER; // X aCC 818
AlignedWireRef < epicsUInt16 > ( msg.m_cmmd ) = REPEATER_REGISTER;
msg.m_available = saddr.ia.sin_addr.s_addr;
/*

View File

@@ -335,7 +335,6 @@ private:
tcpiiu ( const tcpiiu & );
tcpiiu & operator = ( const tcpiiu & );
void * operator new ( size_t size );
void operator delete ( void * );
};
@@ -372,7 +371,7 @@ inline bool tcpiiu::ca_v49_ok (
}
inline bool tcpiiu::alive (
epicsGuard < epicsMutex > & ) const // X aCC 361
epicsGuard < epicsMutex > & ) const
{
return ( this->state == iiucs_connecting ||
this->state == iiucs_connected );

View File

@@ -1,4 +1,4 @@
#!/usr/bin/perl
#!/usr/bin/env perl
use strict;

View File

@@ -1,4 +1,4 @@
#!/usr/bin/perl
#!/usr/bin/env perl
use strict;

View File

@@ -1,4 +1,4 @@
#!/usr/bin/perl
#!/usr/bin/env perl
use strict;

View File

@@ -1,4 +1,4 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
#######################################################################
#

View File

@@ -1,4 +1,4 @@
#!/usr/bin/perl
#!/usr/bin/env perl
use strict;

View File

@@ -1,4 +1,4 @@
#!/usr/bin/perl
#!/usr/bin/env perl
# This script is used to extract information about the Perl build
# configuration, so the EPICS build system uses the same settings.

0
src/cas/build/cas.rc Executable file → Normal file
View File

View File

@@ -3,9 +3,8 @@
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* $Revision-Id$
@@ -15,8 +14,8 @@
* 505 665 1831
*/
#include "dbMapper.h" // ait to dbr types
#include "gddAppTable.h" // EPICS application type table
#include "dbMapper.h" // ait to dbr types
#include "gddAppTable.h" // EPICS application type table
#include "fdManager.h"
#define epicsExportSharedSymbols
@@ -37,67 +36,67 @@ caServer::caServer ()
caServer::~caServer()
{
if (this->pCAS) {
delete this->pCAS;
if (this->pCAS) {
delete this->pCAS;
this->pCAS = NULL;
}
}
}
pvExistReturn caServer::pvExistTest ( const casCtx & ctx,
const caNetAddr & /* clientAddress */, const char * pPVAliasName )
const caNetAddr & /* clientAddress */, const char * pPVAliasName )
{
return this->pvExistTest ( ctx, pPVAliasName );
}
pvExistReturn caServer::pvExistTest ( const casCtx &, const char * )
{
return pverDoesNotExistHere;
return pverDoesNotExistHere;
}
pvCreateReturn caServer::createPV ( const casCtx &, const char * )
{
return S_casApp_pvNotFound;
return S_casApp_pvNotFound;
}
pvAttachReturn caServer::pvAttach ( const casCtx &ctx, const char *pAliasName )
{
// remain backwards compatible (call deprecated routine)
return this->createPV ( ctx, pAliasName );
// remain backwards compatible (call deprecated routine)
return this->createPV ( ctx, pAliasName );
}
casEventMask caServer::registerEvent (const char *pName) // X aCC 361
casEventMask caServer::registerEvent (const char *pName)
{
if (this->pCAS) {
return this->pCAS->registerEvent(pName);
}
else {
casEventMask emptyMask;
printf("caServer:: no server internals attached\n");
return emptyMask;
}
if (this->pCAS) {
return this->pCAS->registerEvent(pName);
}
else {
casEventMask emptyMask;
printf("caServer:: no server internals attached\n");
return emptyMask;
}
}
void caServer::show(unsigned level) const
{
if (this->pCAS) {
this->pCAS->show(level);
}
else {
printf("caServer:: no server internals attached\n");
}
if (this->pCAS) {
this->pCAS->show(level);
}
else {
printf("caServer:: no server internals attached\n");
}
}
void caServer::setDebugLevel (unsigned level)
{
if (pCAS) {
this->pCAS->setDebugLevel(level);
}
else {
printf("caServer:: no server internals attached\n");
}
if (pCAS) {
this->pCAS->setDebugLevel(level);
}
else {
printf("caServer:: no server internals attached\n");
}
}
unsigned caServer::getDebugLevel () const // X aCC 361
unsigned caServer::getDebugLevel () const
{
if (pCAS) {
return this->pCAS->getDebugLevel();
@@ -108,7 +107,7 @@ unsigned caServer::getDebugLevel () const // X aCC 361
}
}
casEventMask caServer::valueEventMask () const // X aCC 361
casEventMask caServer::valueEventMask () const
{
if (pCAS) {
return this->pCAS->valueEventMask();
@@ -119,7 +118,7 @@ casEventMask caServer::valueEventMask () const // X aCC 361
}
}
casEventMask caServer::logEventMask () const // X aCC 361
casEventMask caServer::logEventMask () const
{
if (pCAS) {
return this->pCAS->logEventMask();
@@ -130,7 +129,7 @@ casEventMask caServer::logEventMask () const // X aCC 361
}
}
casEventMask caServer::alarmEventMask () const // X aCC 361
casEventMask caServer::alarmEventMask () const
{
if ( pCAS ) {
return this->pCAS->alarmEventMask ();
@@ -141,12 +140,23 @@ casEventMask caServer::alarmEventMask () const // X aCC 361
}
}
casEventMask caServer::propertyEventMask () const
{
if (pCAS) {
return this->pCAS->propertyEventMask();
}
else {
printf("caServer:: no server internals attached\n");
return casEventMask();
}
}
class epicsTimer & caServer::createTimer ()
{
return fileDescriptorManager.createTimer ();
}
unsigned caServer::subscriptionEventsProcessed () const // X aCC 361
unsigned caServer::subscriptionEventsProcessed () const
{
if ( pCAS ) {
return this->pCAS->subscriptionEventsProcessed ();
@@ -156,7 +166,7 @@ unsigned caServer::subscriptionEventsProcessed () const // X aCC 361
}
}
unsigned caServer::subscriptionEventsPosted () const // X aCC 361
unsigned caServer::subscriptionEventsPosted () const
{
if ( pCAS ) {
return this->pCAS->subscriptionEventsPosted ();

View File

@@ -47,22 +47,23 @@ caServerI::caServerI ( caServer & tool ) :
nEventsPosted ( 0u ),
ioInProgressCount ( 0u )
{
assert ( & adapter != NULL );
assert ( & adapter != NULL );
// create predefined event types
this->valueEvent = registerEvent ( "value" );
this->logEvent = registerEvent ( "log" );
this->alarmEvent = registerEvent ( "alarm" );
this->logEvent = registerEvent ( "log" );
this->alarmEvent = registerEvent ( "alarm" );
this->propertyEvent = registerEvent ( "property" );
this->locateInterfaces ();
if (this->intfList.count()==0u) {
errMessage (S_cas_noInterface,
if (this->intfList.count()==0u) {
errMessage (S_cas_noInterface,
"- CA server internals init unable to continue");
throw S_cas_noInterface;
}
}
return;
return;
}
caServerI::~caServerI()
@@ -70,22 +71,22 @@ caServerI::~caServerI()
delete & this->beaconAnomalyGov;
delete & this->beaconTmr;
// delete all clients
// delete all clients
while ( casStrmClient * pClient = this->clientList.get() ) {
delete pClient;
}
delete pClient;
}
casIntfOS *pIF;
while ( ( pIF = this->intfList.get() ) ) {
delete pIF;
}
casIntfOS *pIF;
while ( ( pIF = this->intfList.get() ) ) {
delete pIF;
}
}
void caServerI::destroyClient ( casStrmClient & client )
{
{
epicsGuard < epicsMutex > locker ( this->mutex );
this->clientList.remove ( client );
this->clientList.remove ( client );
}
delete & client;
}
@@ -143,11 +144,11 @@ caStatus caServerI::attachInterface ( const caNetAddr & addrIn,
void caServerI::sendBeacon ( ca_uint32_t beaconNo )
{
epicsGuard < epicsMutex > locker ( this->mutex );
tsDLIter < casIntfOS > iter = this->intfList.firstIter ();
while ( iter.valid () ) {
iter->sendBeacon ( beaconNo );
iter++;
}
tsDLIter < casIntfOS > iter = this->intfList.firstIter ();
while ( iter.valid () ) {
iter->sendBeacon ( beaconNo );
iter++;
}
}
void caServerI::generateBeaconAnomaly ()
@@ -259,11 +260,11 @@ void caServerI::casMonitorDestroy ( casMonitor & cm )
}
//
// caServerI::dumpMsg()
// caServerI::dumpMsg()
//
// Debug aid - print the header part of a message.
// Debug aid - print the header part of a message.
//
// dp arg allowed to be null
// dp arg allowed to be null
//
//
void caServerI::dumpMsg ( const char * pHostName, const char * pUserName,

View File

@@ -44,23 +44,24 @@ caStatus convertContainerMemberToAtomic ( class gdd & dd,
aitUint32 appType, aitUint32 elemCount );
class caServerI :
public caServerIO,
public ioBlockedList,
public casEventRegistry {
public caServerIO,
public ioBlockedList,
public casEventRegistry {
public:
caServerI ( caServer &tool );
~caServerI ();
bool roomForNewChannel() const;
unsigned getDebugLevel() const { return debugLevel; }
inline void setDebugLevel ( unsigned debugLevelIn );
void show ( unsigned level ) const;
caServerI ( caServer &tool );
~caServerI ();
bool roomForNewChannel() const;
unsigned getDebugLevel() const { return debugLevel; }
inline void setDebugLevel ( unsigned debugLevelIn );
void show ( unsigned level ) const;
void destroyMonitor ( casMonitor & );
caServer * getAdapter ();
caServer * operator -> ();
void connectCB ( casIntfOS & );
casEventMask valueEventMask () const; // DBE_VALUE registerEvent("value")
casEventMask logEventMask () const; // DBE_LOG registerEvent("log")
casEventMask alarmEventMask () const; // DBE_ALARM registerEvent("alarm")
caServer * getAdapter ();
caServer * operator -> ();
void connectCB ( casIntfOS & );
casEventMask valueEventMask () const; // DBE_VALUE registerEvent("value")
casEventMask logEventMask () const; // DBE_LOG registerEvent("log")
casEventMask alarmEventMask () const; // DBE_ALARM registerEvent("alarm")
casEventMask propertyEventMask () const; // DBE_PROPERTY registerEvent("property")
unsigned subscriptionEventsProcessed () const;
void incrEventsProcessedCounter ();
unsigned subscriptionEventsPosted () const;
@@ -82,29 +83,30 @@ public:
private:
clientBufMemoryManager clientBufMemMgr;
tsFreeList < casMonitor, 1024 > casMonitorFreeList;
tsDLList < casStrmClient > clientList;
tsDLList < casStrmClient > clientList;
tsDLList < casIntfOS > intfList;
mutable epicsMutex mutex;
mutable epicsMutex diagnosticCountersMutex;
caServer & adapter;
mutable epicsMutex mutex;
mutable epicsMutex diagnosticCountersMutex;
caServer & adapter;
beaconTimer & beaconTmr;
beaconAnomalyGovernor & beaconAnomalyGov;
unsigned debugLevel;
unsigned debugLevel;
unsigned nEventsProcessed;
unsigned nEventsPosted;
unsigned ioInProgressCount;
casEventMask valueEvent; // DBE_VALUE registerEvent("value")
casEventMask logEvent; // DBE_LOG registerEvent("log")
casEventMask alarmEvent; // DBE_ALARM registerEvent("alarm")
casEventMask logEvent; // DBE_LOG registerEvent("log")
casEventMask alarmEvent; // DBE_ALARM registerEvent("alarm")
casEventMask propertyEvent; // DBE_PROPERTY registerEvent("property")
caStatus attachInterface ( const caNetAddr & addr, bool autoBeaconAddr,
bool addConfigAddr );
caStatus attachInterface ( const caNetAddr & addr, bool autoBeaconAddr,
bool addConfigAddr );
void sendBeacon ( ca_uint32_t beaconNo );
caServerI ( const caServerI & );
caServerI & operator = ( const caServerI & );
caServerI ( const caServerI & );
caServerI & operator = ( const caServerI & );
friend class beaconAnomalyGovernor;
friend class beaconTimer;
@@ -113,17 +115,17 @@ private:
inline caServer * caServerI::getAdapter()
{
return & this->adapter;
return & this->adapter;
}
inline caServer * caServerI::operator -> ()
{
return this->getAdapter();
return this->getAdapter();
}
inline void caServerI::setDebugLevel(unsigned debugLevelIn)
{
this->debugLevel = debugLevelIn;
this->debugLevel = debugLevelIn;
}
inline casEventMask caServerI::valueEventMask() const
@@ -141,6 +143,11 @@ inline casEventMask caServerI::alarmEventMask() const
return this->alarmEvent;
}
inline casEventMask caServerI::propertyEventMask() const
{
return this->propertyEvent;
}
inline bool caServerI :: ioIsPending () const
{
return ( ioInProgressCount > 0u );

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More