Compare commits

...

95 Commits

Author SHA1 Message Date
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
Andrew Johnson
1f573172b3 Creating 3.14.12.3-pre1 2012-11-19 15:02:22 -06:00
Andrew Johnson
d6f72900f8 Update release notes. 2012-11-19 13:19:04 -06:00
Andrew Johnson
5b1d3a7725 conigure: Fix iOS build warning.
from Tom Palaia.
2012-11-19 10:48:24 -06:00
Andrew Johnson
7d79a83519 Apple iOS updates from Tom Pelaia
Adds iOS 6.0, which is now the default.
- changed the default iOS SDK to version 6.0
- use xcrun to locate the selected compiler
- added armv7s as an option for architecture
- made armv7 + armv7s the default architecture
- renamed the LLVM compiler option to LLVM_GNU for clarity
  since LLVM is naturally associated with CLANG
2012-11-17 13:18:16 -06:00
Andrew Johnson
6fd9fb3066 libCom: Removed epicsSingleton workaround
This undoes commit 11565, "workaround for archaic T202 g++ bug"
which doesn't actually seem to be necessary for T202 compilation.
It also replaces 'typename' with 'class', for another compiler.

Modification provided by Dirk Zimoch.
2012-11-16 16:14:13 -06:00
Andrew Johnson
28c7fe12f3 configure: Added Guobao Shen's comments on using MacPorts GCC 2012-11-16 12:54:29 -06:00
Andrew Johnson
36be0aa783 rec: Fix minor string in + out issue.
Undo strncmp+strncpy to strcmp+strcpy change in r12048.
The 'n' versions are needed because device support was
never explicitly required to Nil-terminate the string.
The dbAccess routines do enforce termination though.
2012-11-16 12:40:57 -06:00
Andrew Johnson
69d8be78d3 startup: Recognize 64-bit Windows
For 64-bit versions of Perl on Windows, the EpicsHostArch.pl
script will now return the host architecture "windows-x64".
2012-11-01 14:57:36 -05:00
Andrew Johnson
fc61cc34ce iocLogServer fix for unsigned char arch's
Reported by Guy Jennings
2012-10-31 13:56:12 -05:00
Andrew Johnson
e889336458 db: Undefined alarm limits should return NaN
Where the record doesn't provide get_alarm_double() or for fields
where the default applies, we were still returning 0.
2012-10-17 18:08:39 -05:00
Michael Davidsaver
7cac267a4b db: Fix possible error handling in dbPut 2012-10-11 18:10:00 -05:00
Andrew Johnson
71079ede4b rec/aSub: Fixes from Michael Davidsaver
* Changing the number of elements in a VALx array triggers monitors
* Post monitors on the NEVx fields, following EFLG
* Remove artificial limit on array sizes
2012-10-11 17:51:00 -05:00
Michael Davidsaver
26173c1e0d devLib: add compatibility typedef for VME table type 2012-10-10 15:52:34 -05:00
Andrew Johnson
9c1b8ba952 rec: Fix problem with NAN in MLST/ALST fields
If MLST or ALST became NAN the associated monitor would never trigger.
Now a NAN will cause it to always trigger.
2012-10-06 21:48:01 -05:00
Andrew Johnson
c574722a9b catools: Fix syntax error from vxWorks gcc. 2012-09-11 15:19:29 -05:00
Andrew Johnson
4790578953 tools: Try harder to collapse ../ components in AbsPath
Idea from Angus Gratton, ANU
2012-09-11 12:11:55 -05:00
Ralph Lange
7e6e38060f catools: Change behaviour of camonitor when printing array of chars as string
camonitor was using strlen() to find out the length of the array to print as %s string,
which led to printing old buffer contents when the array-string was not null terminated.
Now uses the minimum of strlen(), elements received, and elements requested.

Suggested by Mark Rivers on tech-talk (11 Sep 2012)
2012-09-11 16:58:43 +02:00
Ralph Lange
709b6ef2f3 catools: Fix off-by-one bug in caput
An internal buffer was allocated one char too short, when caput was used
with the '-S' (send string as array of chars) option.

Reported by J. Lewis Muir (tech-talk on 17-Aug-2012)
2012-09-03 21:25:44 +02:00
Andrew Johnson
169b30081a Fix for vxWorks 6.x LED_ID
Use LED_ID in epicsReadline.c
Provide a typedef for vxWorks 5.x where it doesn't exist.
2012-08-31 16:05:14 -05:00
Andrew Johnson
a19e1d21da libCom: Fix epicsSnprintf() under MinGW
Use the Microsoft _vscprintf() function which was just missing
a prototype in earlier versions of MinGW's stdio.h header.
2012-08-31 15:57:59 -05:00
Andrew Johnson
1ac8ff6378 as: Make asSetFilename() warn on relative paths
Tell the user if they try this.  They'll get an error from
asInit() later, but it gets lost easily in other noise.
2012-08-28 16:35:52 -05:00
Janet Anderson
5c2ef73c4a Fixed X11 include definitions, X11_INC and XPM_INC. 2012-08-20 12:27:39 -05:00
Andrew Johnson
958aa02320 Change build defaults for darwin-x86
* Use clang and clang++
* Build for x86_64 only
2012-08-20 10:03:50 -05:00
Andrew Johnson
c93c7b5e36 configure: Fix test rules dependency 2012-08-07 10:37:13 -05:00
Andrew Johnson
b993e29fad configure: Minor fixes
Don't add extraneous characters when SHRLIB_VERSION or GNU_TARGET
are empty.  The addprefix or addsuffix functions only include the
prefix/suffix part if the list argument is not empty.

This fixes issues naming libCap5.so at build-time.
2012-08-07 09:41:21 -05:00
224 changed files with 3815 additions and 2622 deletions

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

@@ -1,5 +1,5 @@
#*************************************************************************
# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
# Copyright (c) 2012 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.
@@ -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 = 2
EPICS_PATCH_LEVEL = 4
# This will end in -DEV between official releases
EPICS_DEV_SNAPSHOT=-DEV
#EPICS_DEV_SNAPSHOT=-pre1
#EPICS_DEV_SNAPSHOT=-DEV
EPICS_DEV_SNAPSHOT=-pre1
#EPICS_DEV_SNAPSHOT=-pre1-DEV
#EPICS_DEV_SNAPSHOT=-pre2
#EPICS_DEV_SNAPSHOT=-pre2-DEV

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

@@ -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

@@ -322,10 +322,10 @@ $(OBJLIB_MUNCHNAME):%.munch : %_ctdt$(OBJ) %$(OBJ)
@$(RM) $@
$(MUNCH_CMD)
runtests: $(TESTSCRIPTS_$(BUILD_CLASS))
runtests: $(TESTSCRIPTS)
-$(PERL) -MTest::Harness -e 'runtests @ARGV if @ARGV;' $^
testspec: $(TESTSCRIPTS_$(BUILD_CLASS))
testspec: $(TESTSCRIPTS)
@$(RM) $@
@echo OS-class: $(OS_CLASS) > $@
@echo Target-arch: $(T_A) >> $@
@@ -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),$@)

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

@@ -20,8 +20,8 @@ OBJ = .o
LIB_PREFIX = lib
LIB_SUFFIX = .a
SHRLIB_SUFFIX_BASE = .so
SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE).$(SHRLIB_VERSION)
LOADABLE_SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE).$(LOADABLE_SHRLIB_VERSION)
SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)$(addprefix .,$(SHRLIB_VERSION))
LOADABLE_SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)$(addprefix .,$(LOADABLE_SHRLIB_VERSION))
LOADABLE_SHRLIB_PREFIX = lib
#-------------------------------------------------------
@@ -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

@@ -41,6 +41,7 @@ ARCH_DEP_LDFLAGS += $(ARCH_DEP_FLAGS)
#--------------------------------------------------
# Operating system flags
OP_SYS_CFLAGS += -isysroot $(SDK_DIR) -D__IPHONE_OS_VERSION_MIN_REQUIRED=30200
OP_SYS_LDFLAGS += -isysroot $(SDK_DIR)
#--------------------------------------------------
# Always compile in debugging symbol table information
@@ -53,13 +54,15 @@ OPT_CXXFLAGS_YES += -g
CC_GNU = gcc
CCC_GNU = g++
CC_LLVM = llvm-gcc
CCC_LLVM = llvm-g++
CC_LLVM_GNU = llvm-gcc
CCC_LLVM_GNU = llvm-g++
CC_CLANG = clang
CCC_CLANG = clang++
CC = $(firstword $(wildcard $(GNU_BIN)/$(CC_$(COMPILER))) $(CC_$(COMPILER)))
CCC = $(firstword $(wildcard $(GNU_BIN)/$(CCC_$(COMPILER))) $(CCC_$(COMPILER)))
# Convert the iOS platform to lowercase for passing to xcrun's sdk parameter
XCRUN_SDK_BASE = $(shell echo $(IOS_PLATFORM) | tr A-Z a-z)
#-------------------------------------------------------
# Linker flags
@@ -70,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
@@ -93,13 +96,14 @@ vpath %.m $(USR_VPATH) $(ALL_SRC_DIRS)
#--------------------------------------------------
# Header dependency file generation
#
# Use compiler when ARCH_CLASS is a single arch value
# otherwise use perl script command
SINGLE_ARCH=$(filter 1,$(words $(ARCH_CLASS)))
HDEPENDS_CFLAGS = $(if $(SINGLE_ARCH),$(HDEPENDS_CFLAGS_$(HDEPENDS)))
HDEPENDS_METHOD = $(if $(SINGLE_ARCH),CFLAGS,CMD)
HDEPENDS_METHOD = CMD
#--------------------------------------------------
# Allow site overrides
-include $(CONFIG)/os/CONFIG_SITE.Common.iosCommon
-include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).iosCommon
#--------------------------------------------------
# Find the Xcode compilers for the specified SDK just once
CC := $(shell xcrun -sdk $(XCRUN_SDK_BASE) -find $(CC_$(COMPILER)))
CCC := $(shell xcrun -sdk $(XCRUN_SDK_BASE) -find $(CCC_$(COMPILER)))

View File

@@ -17,7 +17,7 @@ ifeq ($(BUILD_CLASS),CROSS)
# prefix of compiler tools
CMPLR_SUFFIX =
CMPLR_PREFIX = $(GNU_TARGET)-
CMPLR_PREFIX = $(addsuffix -,$(GNU_TARGET))
# Provide a link-time path for shared libraries
SHRLIBDIR_RPATH_LDFLAGS_YES += $(SHRLIB_DEPLIB_DIRS:%=-Wl,-rpath-link,%)

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

@@ -7,17 +7,31 @@
#-------------------------------------------------------
# Select which CPU architecture(s) to include in your MacOS binaries:
# i386
# x86_64 - Needs MacOS 10.4 with the Universal SDK, or 10.5 and later
# i386, x86_64, or both (fat binaries).
ARCH_CLASS = i386
#ARCH_CLASS = x86_64
#ARCH_CLASS = i386
ARCH_CLASS = x86_64
#ARCH_CLASS = i386 x86_64
#
# Uncomment the followings lines to build with CLANG instead of GCC.
# Uncomment the following 3 lines to build with Apple's GCC instead of CLANG.
#
#CC = clang
#CCC = clang++
#GNU_LDLIBS_YES =
#CC = gcc
#CCC = g++
#GNU = YES
# 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'
# the problem is due to the ccflags configuration that your version of Perl
# was built with. You can replace the Cap5_CFLAGS setting in the Makefile
# with a hand-edited set of flags for building that Perl library, or ignore
# this problem if you don't need to use Channel Access from Perl.

View File

@@ -1,21 +1,31 @@
# CONFIG_SITE.Common.ios-arm
#
# $Revision-Id$
# This file is maintained by the build community.
#
# Site-specific settings for ios-arm target builds
#-------------------------------------------------------
# Which ARM instruction set(s) to generate code for:
# Most iOS devices can run programs compiled for both the
# ARMv6 and ARMv7 instruction sets. ARMv7 code is usually
# more efficient, but the older devices listed below can only
# use the ARMv6 instruction set. Including both architectures
# generates a Universal binary, which is larger and takes
# longer to compile but runs efficiently on all devices.
# Most iOS devices can run programs compiled for older
# instruction sets, although the newer instructions are
# more efficient.
#
# ARMv6-only devices: iPhone 1 or 3G, iPod Touch Gen 1 or 2
# Apple's compilers can build for multiple architectures,
# generating a Universal binary. This is larger and takes
# longer to compile, but runs efficiently on all devices.
#
ARCH_CLASS = armv7
# Xcode 4.5 dropped support for the ARMv6.
#
# 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
#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

@@ -1,7 +1,6 @@
# CONFIG_SITE.Common.iosCommon
#
# $Revision-Id$
# This file is maintained by the build community.
#
# Site-specific settings for Apple iOS builds
#-------------------------------------------------------
@@ -12,16 +11,20 @@
#IOS_VERSION = 4.1
#IOS_VERSION = 4.2
#IOS_VERSION = 4.3
IOS_VERSION = 5.0
#IOS_VERSION = 5.0
#IOS_VERSION = 5.1
#IOS_VERSION = 6.0
#IOS_VERSION = 6.1
IOS_VERSION = 7.0
# Which compiler to use:
# CLANG is preferred for recent versions of Xcode
# LLVM uses the llvm-gcc and llvm-g++ compilers
# 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
COMPILER = CLANG
#COMPILER = LLVM
#COMPILER = LLVM_GNU
#COMPILER = GNU

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,192 @@
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<title>EPICS Base R3.14.12.2-DEV Release Notes</title>
<title>EPICS Base R3.14.12.4-pre1 Release Notes</title>
</head>
<body lang="en">
<h1 align="center">EPICS Base Release 3.14.12.2-DEV</h1>
<h1 align="center">EPICS Base Release 3.14.12.4-pre1</h1>
<h2 align="center">Changes between 3.14.12.3 and 3.14.12.4</h2>
<!-- Insert new items immediately below here ... -->
<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>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.</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>
<ul>
<li>Changing the number of valid elements in a VALx field now triggers
monitors</li>
<li>The NEVx fields now post monitors, following the EFLG setting</li>
<li>The artificial limit of 10,000,000 array elements has been removed</li>
</ul>
<h4>Problem with NAN values in MLST/ALST fields</h4>
<p>The ai, ao, calc, calcout, dfanout, sel and sub record types could stop
posting monitors if they got NAN values in their MLST or ALST fields. A change
has been included so this should no longer be the case.</p>
<h4>MacOS build defaults changed</h4>
<p>The default build settings for darwin-x86 targets have been changed to match
the latest version of XCode; see configure/os/CONFIG_SITE.Common.darwin-x86
if you need to revert back to building with GCC or to include the i386 CPU
architecture.</p>
<h4>Build problem with db dependencies</h4>
@@ -28,19 +205,55 @@ itself have now been added. Both the Shell and Perl versions of the startup
EpicsHostArch scripts now recognize both arm6l and arm7l CPUs and return the
generic linux-arm host architecture name for them.</p>
<h4>New Microblaze Target Architecture</h4>
<p>A new cross-compiled target architecture is included for the Xilinx
Microblaze FPGA soft-core CPU architecture running Linux.</p>
<h4>Win32 Numeric string to enum/menu/device conversions</h4>
<p>Microsoft's C run-time library has a bug in the sscanf() function such that
the "%n" format specifier does not always work. The string to enum, menu and
device conversion functions have been modified to avoid this problem, but a
numeric string will no longer be converted properly on any architecture if it
has trailing whitespace characters.</p>
<h4>Launchpad Bugs Resolved</h4>
<p>The following are links to bugs in the Launchpad bug tracker that have been
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>
<li>950555
<a href="https://launchpad.net/bugs/950555">
String substitution removes part of path when linking versioned shared
libraries</a></li>
<li>907761
<a href="https://launchpad.net/bugs/907761">
reading only 1st char of link in "long string" ($) syntax fails in read
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>
<h4>Calcout and Seq record timestamps</h4>

View File

@@ -1,11 +1,9 @@
/* share/src/as/asDbLib.c */
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* Copyright (c) 2012 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
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* Author: Marty Kraimer Date: 02-11-94*/
@@ -69,18 +67,23 @@ static long asDbAddRecords(void)
int epicsShareAPI asSetFilename(const char *acf)
{
if(pacf) free ((void *)pacf);
if(acf) {
pacf = calloc(1,strlen(acf)+1);
if(!pacf) {
errMessage(0,"asSetFilename calloc failure");
} else {
strcpy(pacf,acf);
}
if (pacf)
free (pacf);
if (acf) {
pacf = calloc(1, strlen(acf)+1);
if (!pacf) {
errMessage(0, "asSetFilename calloc failure");
} else {
strcpy(pacf, acf);
if (*pacf != '/' && !strchr(pacf, ':')) {
printf("asSetFilename: Warning - relative paths won't usually "
"work\n");
}
}
} else {
pacf = NULL;
pacf = NULL;
}
return(0);
return 0;
}
int epicsShareAPI asSetSubstitutions(const char *substitutions)

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

@@ -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

@@ -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

View File

@@ -245,6 +245,7 @@ public:
epicsShareFunc casEventMask valueEventMask () const; // DBE_VALUE
epicsShareFunc casEventMask logEventMask () const; // DBE_LOG
epicsShareFunc casEventMask alarmEventMask () const; // DBE_ALARM
epicsShareFunc casEventMask propertyEventMask () const; // DBE_PROPERTY
epicsShareFunc void setDebugLevel ( unsigned level );
epicsShareFunc unsigned getDebugLevel () const;

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