27 Commits
4.2.1 ... 4.3.0

Author SHA1 Message Date
Andrew Johnson
b26c0ecd71 Use EPICS_BASE_PVA_CORE_LIBS 2017-12-06 22:46:27 -06:00
Andrew Johnson
e06b2b7076 Include <top>/../RELEASE.<host>.local 2017-12-06 20:38:13 -06:00
Andrew Johnson
63214b98f6 Use 'make test-results' in travis-build script 2017-11-30 12:05:58 -06:00
Andrew Johnson
a1714c9aab Unify .gitignore files 2017-11-30 12:05:40 -06:00
Andrew Johnson
64c5fd1e67 Remove ExampleRELEASE.local 2017-11-30 12:04:29 -06:00
Ralph Lange
955947fd0f jenkins: remove microbench option and pvCommon dependency from CB build 2017-11-15 17:18:57 +01:00
Marty Kraimer
c6339f4f1b Merge pull request #31 from mrkraimer/master
PVRecord::process DO NOT set userTag
2017-11-09 09:43:31 -05:00
mrkraimer
ae97789beb PVRecord::process DO NOT set userTag 2017-11-09 09:09:44 -05:00
Marty Kraimer
35d4b5c70e Merge pull request #30 from mrkraimer/master
attempt to fix macos build
2017-10-05 09:07:51 -04:00
mrkraimer
977f078246 attempt to fix macos build 2017-10-05 08:40:37 -04:00
Marty Kraimer
063313f246 Merge pull request #28 from mrkraimer/master
Remove most use of destroy
2017-10-02 16:00:47 -04:00
mrkraimer
cec282f77f Merge https://github.com/epics-base/pvDatabaseCPP 2017-10-02 15:11:37 -04:00
mrkraimer
24cf1d277e remove destroy except PVRecord, which has new semantics 2017-10-02 15:03:16 -04:00
Ralph Lange
1d5e9e7b25 travis-ci: consolidate travis configuration 2017-09-28 15:11:03 +02:00
Ralph Lange
f131f0631c travis-ci: fix requisite build for Base 3.x 2017-09-27 14:45:26 +02:00
Ralph Lange
aa44396a43 travis-ci: update/streamline configuration for EPICS 7 2017-09-27 14:06:46 +02:00
Marty Kraimer
547df7a2cd Merge pull request #27 from mrkraimer/master
create travis files
2017-09-13 10:12:12 -04:00
mrkraimer
be6527b01e another attempt at travis 2017-09-13 07:12:59 -04:00
mrkraimer
d7486622bf create travis files 2017-09-13 05:29:58 -04:00
Marty Kraimer
974bf061a2 Merge pull request #26 from mrkraimer/new-pva-api
add pvAccessIOC to LIBS
2017-07-18 15:38:30 -04:00
mrkraimer
d99087d2f6 add pvAccessIOC to LIBS 2017-07-18 15:36:01 -04:00
Marty Kraimer
8c2926ad92 Merge pull request #25 from mrkraimer/new-pva-api
change version number
2017-07-18 15:02:48 -04:00
mrkraimer
5b60025b76 change version number 2017-07-18 14:50:43 -04:00
Marty Kraimer
d080a073b1 Merge pull request #23 from mrkraimer/new-pva-api
changes for new-pva-api
2017-07-18 13:36:20 -04:00
mrkraimer
ff172cc495 changes for new-pva-api 2017-06-28 10:37:48 -04:00
Marty Kraimer
da00928e7e Merge pull request #22 from mrkraimer/master
monitor change to support filter plugin support
2017-04-07 13:32:50 -04:00
mrkraimer
9dcb68669c monitor change to support filter plugin support 2017-03-30 11:02:17 -04:00
21 changed files with 482 additions and 414 deletions

21
.ci/travis-build.sh Executable file
View File

@@ -0,0 +1,21 @@
#!/bin/sh
set -e -x
# set RTEMS to eg. "4.9" or "4.10"
# requires qemu, bison, flex, texinfo, install-info
if [ -n "$RTEMS" ]
then
# find local qemu-system-i386
export PATH="$HOME/.cache/qemu/usr/bin:$PATH"
echo -n "Using QEMU: "
type qemu-system-i386 || echo "Missing qemu"
EXTRA=RTEMS_QEMU_FIXUPS=YES
fi
make -j2 $EXTRA
if [ "$TEST" != "NO" ]
then
make tapfiles
make -s test-results
fi

177
.ci/travis-prepare.sh Executable file
View File

@@ -0,0 +1,177 @@
#!/bin/sh
set -e -x
CURDIR="$PWD"
QDIR="$HOME/.cache/qemu"
if [ -n "$RTEMS" -a "$TEST" = "YES" ]
then
git clone --quiet --branch vme --depth 10 https://github.com/mdavidsaver/qemu.git "$HOME/.build/qemu"
cd "$HOME/.build/qemu"
HEAD=`git log -n1 --pretty=format:%H`
echo "HEAD revision $HEAD"
[ -e "$HOME/.cache/qemu/built" ] && BUILT=`cat "$HOME/.cache/qemu/built"`
echo "Cached revision $BUILT"
if [ "$HEAD" != "$BUILT" ]
then
echo "Building QEMU"
git submodule --quiet update --init
install -d "$HOME/.build/qemu/build"
cd "$HOME/.build/qemu/build"
"$HOME/.build/qemu/configure" --prefix="$HOME/.cache/qemu/usr" --target-list=i386-softmmu --disable-werror
make -j2
make install
echo "$HEAD" > "$HOME/.cache/qemu/built"
fi
fi
cat << EOF > $CURDIR/configure/RELEASE.local
EPICS_BASE=$HOME/.source/epics-base
EOF
install -d "$HOME/.source"
cd "$HOME/.source"
add_base_module() {
MODULE=$1
BRANCH=$2
( cd epics-base/modules && \
git clone --quiet --depth 5 --branch $MODULE/$BRANCH https://github.com/${REPOBASE:-epics-base}/epics-base.git $MODULE && \
cd $MODULE && git log -n1 )
}
add_gh_module() {
MODULE=$1
REPOOWNER=$2
REPONAME=$3
BRANCH=$4
( cd epics-base/modules && \
git clone --quiet --depth 5 --branch $BRANCH https://github.com/$REPOOWNER/$REPONAME.git $MODULE && \
cd $MODULE && git log -n1 )
}
add_gh_flat() {
MODULE=$1
REPOOWNER=$2
REPONAME=$3
BRANCH=$4
MODULE_UC=$(echo $MODULE | tr 'a-z' 'A-Z')
( git clone --quiet --depth 5 --branch $BRANCH https://github.com/$REPOOWNER/$REPONAME.git $MODULE && \
cd $MODULE && git log -n1 )
cat < $CURDIR/configure/RELEASE.local > $MODULE/configure/RELEASE.local
cat << EOF >> $CURDIR/configure/RELEASE.local
${MODULE_UC}=$HOME/.source/$MODULE
EOF
}
if [ "$BRBASE" ]
then
git clone --quiet --depth 5 --branch "$BRBASE" https://github.com/${REPOBASE:-epics-base}/epics-base.git epics-base
(cd epics-base && git log -n1 )
add_gh_flat pvData ${REPOPVD:-epics-base} pvDataCPP ${BRPVD:-master}
add_gh_flat pvAccess ${REPOPVA:-epics-base} pvAccessCPP ${BRPVA:-master}
else
git clone --quiet --depth 5 --branch core/"${BRCORE:-master}" https://github.com/${REPOBASE:-epics-base}/epics-base.git epics-base
( cd epics-base && git log -n1 )
add_base_module libcom "${BRLIBCOM:-master}"
add_base_module ca "${BRCA:-master}"
add_base_module database "${BRDATABASE:-master}"
add_gh_module pvData ${REPOPVD:-epics-base} pvDataCPP ${BRPVD:-master}
add_gh_module pvAccess ${REPOPVA:-epics-base} pvAccessCPP ${BRPVA:-master}
fi
if [ -e $CURDIR/configure/RELEASE.local ]
then
cat $CURDIR/configure/RELEASE.local
fi
EPICS_HOST_ARCH=`sh epics-base/startup/EpicsHostArch`
# requires wine and g++-mingw-w64-i686
if [ "$WINE" = "32" ]
then
echo "Cross mingw32"
sed -i -e '/CMPLR_PREFIX/d' epics-base/configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw
cat << EOF >> epics-base/configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw
CMPLR_PREFIX=i686-w64-mingw32-
EOF
cat << EOF >> epics-base/configure/CONFIG_SITE
CROSS_COMPILER_TARGET_ARCHS+=win32-x86-mingw
EOF
fi
if [ "$STATIC" = "YES" ]
then
echo "Build static libraries/executables"
cat << EOF >> epics-base/configure/CONFIG_SITE
SHARED_LIBRARIES=NO
STATIC_BUILD=YES
EOF
fi
case "$CMPLR" in
clang)
echo "Host compiler is clang"
cat << EOF >> epics-base/configure/os/CONFIG_SITE.Common.$EPICS_HOST_ARCH
GNU = NO
CMPLR_CLASS = clang
CC = clang
CCC = clang++
EOF
# hack
sed -i -e 's/CMPLR_CLASS = gcc/CMPLR_CLASS = clang/' epics-base/configure/CONFIG.gnuCommon
clang --version
;;
*)
echo "Host compiler is default"
gcc --version
;;
esac
cat <<EOF >> epics-base/configure/CONFIG_SITE
USR_CPPFLAGS += $USR_CPPFLAGS
USR_CFLAGS += $USR_CFLAGS
USR_CXXFLAGS += $USR_CXXFLAGS
EOF
# set RTEMS to eg. "4.9" or "4.10"
# requires qemu, bison, flex, texinfo, install-info
if [ -n "$RTEMS" ]
then
echo "Cross RTEMS${RTEMS} for pc386"
install -d /home/travis/.cache
curl -L "https://github.com/mdavidsaver/rsb/releases/download/travis-20160306-2/rtems${RTEMS}-i386-trusty-20190306-2.tar.gz" \
| tar -C /home/travis/.cache -xj
sed -i -e '/^RTEMS_VERSION/d' -e '/^RTEMS_BASE/d' epics-base/configure/os/CONFIG_SITE.Common.RTEMS
cat << EOF >> epics-base/configure/os/CONFIG_SITE.Common.RTEMS
RTEMS_VERSION=$RTEMS
RTEMS_BASE=/home/travis/.cache/rtems${RTEMS}-i386
EOF
cat << EOF >> epics-base/configure/CONFIG_SITE
CROSS_COMPILER_TARGET_ARCHS+=RTEMS-pc386
EOF
# find local qemu-system-i386
export PATH="$HOME/.cache/qemu/usr/bin:$PATH"
echo -n "Using QEMU: "
type qemu-system-i386 || echo "Missing qemu"
EXTRA=RTEMS_QEMU_FIXUPS=YES
fi
make -j2 -C epics-base $EXTRA
if [ "$BRBASE" ]
then
make -j2 -C pvData $EXTRA
make -j2 -C pvAccess $EXTRA
fi

28
.gitignore vendored
View File

@@ -1,13 +1,17 @@
bin/ /cfg/
lib/ /bin/
doc/ /lib/
include/ /db/
db/ /dbd/
dbd/ /html/
documentation/html /include/
documentation/*.tag /templates/
/configure/*.local
/documentation/html
/documentation/*.tag
O.*/
/QtC-*
envPaths envPaths
configure/*.local *.orig
!configure/ExampleRELEASE.local *.log
**/O.* .*.swp
QtC-*

29
.travis.yml Normal file
View File

@@ -0,0 +1,29 @@
sudo: false
dist: trusty
language: c++
compiler:
- gcc
addons:
apt:
packages:
- libreadline6-dev
- libncurses5-dev
- perl
- clang
- g++-mingw-w64-i686
install:
- ./.ci/travis-prepare.sh
script:
- ./.ci/travis-build.sh
env:
- BRCORE=master BRLIBCOM=master BRPVD=master BRPVA=master
- CMPLR=clang
- USR_CXXFLAGS=-std=c++11
- CMPLR=clang USR_CXXFLAGS=-std=c++11
- WINE=32 TEST=NO STATIC=YES
- WINE=32 TEST=NO STATIC=NO
- RTEMS=4.10 TEST=NO
- RTEMS=4.9 TEST=NO
- BRBASE=3.16
- BRBASE=3.15
- BRBASE=3.14

View File

@@ -1,8 +0,0 @@
EPICS4_DIR=/home/epicsv4/master
PVACCESS=${EPICS4_DIR}/pvAccessCPP
PVDATA=${EPICS4_DIR}/pvDataCPP
PVCOMMON=${EPICS4_DIR}/pvCommonCPP
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
EPICS_BASE=/home/install/epics/base

View File

@@ -1,27 +1,43 @@
# pvDatabaseCPP RELEASE - Location of external support modules # RELEASE - Location of external support modules
# #
# IF YOU CHANGE this file or any file it includes you must # IF YOU CHANGE ANY PATHS in this file or make API changes to
# subsequently do a "gnumake rebuild" in the application's # any modules it refers to, you should do a "make rebuild" in
# top level directory. # this application's top level directory.
# #
# The build process does not check dependencies against files # The EPICS build process does not check dependencies against
# that are outside this application, thus you should also do a # any files from outside the application, so it is safest to
# "gnumake rebuild" in the top level directory after EPICS_BASE # rebuild it completely if any modules it depends on change.
# or any other external module pointed to below is rebuilt.
# #
# Host- or target-specific settings can be given in files named # Host- or target-specific settings can be given in files named
# RELEASE.$(EPICS_HOST_ARCH).Common # RELEASE.$(EPICS_HOST_ARCH).Common
# RELEASE.Common.$(T_A) # RELEASE.Common.$(T_A)
# RELEASE.$(EPICS_HOST_ARCH).$(T_A) # RELEASE.$(EPICS_HOST_ARCH).$(T_A)
# EPICS V4 Developers: Do not edit the locations in this file!
# #
# Create a file RELEASE.local pointing to your PVASRV, PVACCESS, # This file is parsed by both GNUmake and an EPICS Perl script,
# PVDATA, PVCOMMON and EPICS_BASE build directories, e.g. # so it may ONLY contain definititions of paths to other support
# PVACCESS = /path/to/epics/pvAccessCPP # modules, variable definitions that are used in module paths,
# PVDATA = /path/to/epics/pvDataCPP # and include statements that pull in other RELEASE files.
# PVCOMMON = /path/to/epics/pvCommonCPP # Variables may be used before their values have been set.
# EPICS_BASE = /path/to/epics/base # Build variables that are NOT used in paths should be set in
# the CONFIG_SITE file.
# Variables and paths to dependent modules:
#MODULES = /path/to/modules
#MYMODULE = $(MODULES)/my-module
# If building the EPICS modules individually, set these:
#EPICS_PVACCESS = $(MODULES)/pvAccess
#EPICS_PVDATA = $(MODULES)/pvData
#EPICS_DATABASE = $(MODULES)/database
#EPICS_CA = $(MODULES)/ca
#EPICS_LIBCOM = $(MODULES)/libcom
#EPICS_BASE = $(MODULES)/core
# Set RULES here if you want to use build rules from elsewhere:
#RULES = $(MODULES)/build-rules
# These allow developers to override the RELEASE variable settings
# without having to modify the configure/RELEASE file itself.
-include $(TOP)/../RELEASE.local -include $(TOP)/../RELEASE.local
-include $(TOP)/../RELEASE.$(EPICS_HOST_ARCH).local
-include $(TOP)/configure/RELEASE.local -include $(TOP)/configure/RELEASE.local

View File

@@ -21,28 +21,19 @@ installE4 () {
local module=$1 local module=$1
local branch=$2 local branch=$2
# If microbench version does not exist, try without wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE}/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz
if [ "${MB}" = "WITH_MICROBENCH" ]; then
if ! wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE},MB=WITH_MICROBENCH/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz; then
wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE},MB=NO_MICROBENCH/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz
fi
else
wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE},MB=NO_MICROBENCH/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz
fi
tar -xzf ${module}.CB-dist.tar.gz tar -xzf ${module}.CB-dist.tar.gz
} }
########################################### ###########################################
# Defaults for EPICS Base and MB # Defaults for EPICS Base
DEFAULT_BASE=3.15.4 DEFAULT_BASE=3.15.4
BASE=${BASE:-${DEFAULT_BASE}} BASE=${BASE:-${DEFAULT_BASE}}
MB=${MB:-"NO_MICROBENCH"}
########################################### ###########################################
# Dependent module branches # Dependent module branches
PVCOMMON_BRANCH="master"
PVDATA_BRANCH="master" PVDATA_BRANCH="master"
PVACCESS_BRANCH="master" PVACCESS_BRANCH="master"
@@ -58,7 +49,6 @@ cd ${STUFF}
installTool Boost 1.61.0 installTool Boost 1.61.0
installTool Base ${BASE} installTool Base ${BASE}
installE4 pvCommon ${PVCOMMON_BRANCH}
installE4 pvData ${PVDATA_BRANCH} installE4 pvData ${PVDATA_BRANCH}
installE4 pvAccess ${PVACCESS_BRANCH} installE4 pvAccess ${PVACCESS_BRANCH}

View File

@@ -5,11 +5,10 @@ include $(TOP)/configure/CONFIG
PVDATABASE_SRC = $(TOP)/src PVDATABASE_SRC = $(TOP)/src
LIBRARY += pvDatabase LIBRARY += pvDatabase
# shared library ABI version. # shared library ABI version.
SHRLIB_VERSION ?= 4.2.0 SHRLIB_VERSION ?= 4.3.0
INC += pv/channelProviderLocal.h INC += pv/channelProviderLocal.h
INC += pv/pvDatabase.h INC += pv/pvDatabase.h
@@ -20,11 +19,7 @@ include $(PVDATABASE_SRC)/database/Makefile
include $(PVDATABASE_SRC)/pvAccess/Makefile include $(PVDATABASE_SRC)/pvAccess/Makefile
include $(PVDATABASE_SRC)/special/Makefile include $(PVDATABASE_SRC)/special/Makefile
pvDatabase_LIBS += $(EPICS_BASE_PVA_CORE_LIBS)
pvDatabase_LIBS += pvAccess pvData Com
pvDatabase_LIBS += $(EPICS_BASE_IOC_LIBS) pvDatabase_LIBS += $(EPICS_BASE_IOC_LIBS)
include $(TOP)/configure/RULES include $(TOP)/configure/RULES

View File

@@ -21,43 +21,21 @@ using namespace std;
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
static PVDatabasePtr pvDatabaseMaster;
PVDatabasePtr PVDatabase::getMaster() PVDatabasePtr PVDatabase::getMaster()
{ {
static PVDatabasePtr master; if(!pvDatabaseMaster) pvDatabaseMaster = PVDatabasePtr(new PVDatabase());
static Mutex mutex; return pvDatabaseMaster;
Lock xx(mutex);
if(master.get()==NULL) {
master = PVDatabasePtr(new PVDatabase());
}
return master;
} }
PVDatabase::PVDatabase() PVDatabase::PVDatabase()
: isDestroyed(false)
{ {
} }
PVDatabase::~PVDatabase() PVDatabase::~PVDatabase()
{ {
destroy(); cout << "PVDatabase::~PVDatabase()\n";
}
void PVDatabase::destroy()
{
{
epicsGuard<epics::pvData::Mutex> guard(mutex);
if(isDestroyed) {
return;
}
isDestroyed = true;
}
for(PVRecordMap::iterator iter = recordMap.begin(); iter != recordMap.end(); iter++) {
PVRecordPtr pvRecord = (*iter).second;
if(pvRecord) {
pvRecord->destroy();
}
}
recordMap.clear();
} }
void PVDatabase::lock() { void PVDatabase::lock() {
@@ -71,23 +49,19 @@ void PVDatabase::unlock() {
PVRecordPtr PVDatabase::findRecord(string const& recordName) PVRecordPtr PVDatabase::findRecord(string const& recordName)
{ {
epicsGuard<epics::pvData::Mutex> guard(mutex); epicsGuard<epics::pvData::Mutex> guard(mutex);
PVRecordPtr xxx;
if(isDestroyed) {
return xxx;
}
PVRecordMap::iterator iter = recordMap.find(recordName); PVRecordMap::iterator iter = recordMap.find(recordName);
if(iter!=recordMap.end()) { if(iter!=recordMap.end()) {
return (*iter).second; return (*iter).second;
} }
return xxx; return PVRecordPtr();
} }
bool PVDatabase::addRecord(PVRecordPtr const & record) bool PVDatabase::addRecord(PVRecordPtr const & record)
{ {
epicsGuard<epics::pvData::Mutex> guard(mutex); if(record->getTraceLevel()>0) {
if(isDestroyed) { cout << "PVDatabase::addRecord " << record->getRecordName() << endl;
return false;
} }
epicsGuard<epics::pvData::Mutex> guard(mutex);
string recordName = record->getRecordName(); string recordName = record->getRecordName();
PVRecordMap::iterator iter = recordMap.find(recordName); PVRecordMap::iterator iter = recordMap.find(recordName);
if(iter!=recordMap.end()) { if(iter!=recordMap.end()) {
@@ -100,10 +74,10 @@ bool PVDatabase::addRecord(PVRecordPtr const & record)
bool PVDatabase::removeRecord(PVRecordPtr const & record) bool PVDatabase::removeRecord(PVRecordPtr const & record)
{ {
epicsGuard<epics::pvData::Mutex> guard(mutex); if(record->getTraceLevel()>0) {
if(isDestroyed) { cout << "PVDatabase::removeRecord " << record->getRecordName() << endl;
return false;
} }
epicsGuard<epics::pvData::Mutex> guard(mutex);
string recordName = record->getRecordName(); string recordName = record->getRecordName();
PVRecordMap::iterator iter = recordMap.find(recordName); PVRecordMap::iterator iter = recordMap.find(recordName);
if(iter!=recordMap.end()) { if(iter!=recordMap.end()) {
@@ -119,9 +93,6 @@ PVStringArrayPtr PVDatabase::getRecordNames()
{ {
epicsGuard<epics::pvData::Mutex> guard(mutex); epicsGuard<epics::pvData::Mutex> guard(mutex);
PVStringArrayPtr xxx; PVStringArrayPtr xxx;
if(isDestroyed) {
return xxx;
}
PVStringArrayPtr pvStringArray = static_pointer_cast<PVStringArray> PVStringArrayPtr pvStringArray = static_pointer_cast<PVStringArray>
(getPVDataCreate()->createPVScalarArray(pvString)); (getPVDataCreate()->createPVScalarArray(pvString));
size_t len = recordMap.size(); size_t len = recordMap.size();

View File

@@ -51,7 +51,6 @@ PVRecord::~PVRecord()
if(traceLevel>0) { if(traceLevel>0) {
cout << "~PVRecord() " << recordName << endl; cout << "~PVRecord() " << recordName << endl;
} }
destroy();
} }
void PVRecord::initPVRecord() void PVRecord::initPVRecord()
@@ -113,6 +112,7 @@ void PVRecord::process()
cout << "PVRecord::process() " << recordName << endl; cout << "PVRecord::process() " << recordName << endl;
} }
if(pvTimeStamp.isAttached()) { if(pvTimeStamp.isAttached()) {
pvTimeStamp.get(timeStamp);
timeStamp.getCurrent(); timeStamp.getCurrent();
pvTimeStamp.set(timeStamp); pvTimeStamp.set(timeStamp);
} }

View File

@@ -70,10 +70,6 @@ public:
* @brief Destructor * @brief Destructor
*/ */
virtual ~MonitorFactory(); virtual ~MonitorFactory();
/**
* @brief Destroy the monitor factory.
*/
virtual void destroy();
/** /**
* @brief Create a monitor on a record. * @brief Create a monitor on a record.
* *
@@ -94,7 +90,6 @@ private:
MonitorFactory(); MonitorFactory();
friend class MonitorLocal; friend class MonitorLocal;
friend epicsShareFunc MonitorFactoryPtr getMonitorFactory(); friend epicsShareFunc MonitorFactoryPtr getMonitorFactory();
bool isDestroyed;
epics::pvData::Mutex mutex; epics::pvData::Mutex mutex;
}; };
@@ -109,10 +104,15 @@ epicsShareFunc ChannelProviderLocalPtr getChannelProviderLocal();
*/ */
class epicsShareClass ChannelProviderLocal : class epicsShareClass ChannelProviderLocal :
public epics::pvAccess::ChannelProvider, public epics::pvAccess::ChannelProvider,
public epics::pvAccess::ChannelFind,
public std::tr1::enable_shared_from_this<ChannelProviderLocal> public std::tr1::enable_shared_from_this<ChannelProviderLocal>
{ {
public: public:
POINTER_DEFINITIONS(ChannelProviderLocal); POINTER_DEFINITIONS(ChannelProviderLocal);
/**
* @brief Constructor
*/
ChannelProviderLocal();
/** /**
* @brief Destructor * @brief Destructor
*/ */
@@ -120,9 +120,8 @@ public:
/** /**
* @brief Destroy the channel provider. * @brief Destroy the channel provider.
* *
* Probably never called.
*/ */
virtual void destroy(); virtual void destroy() EPICS_DEPRECATED {};
/** /**
* @brief Returns the channel provider name. * @brief Returns the channel provider name.
* @return <b>local</b> * @return <b>local</b>
@@ -185,17 +184,32 @@ public:
epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester, epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester,
short priority, short priority,
std::string const &address); std::string const &address);
/**
* @brief get trace level (0,1,2) means (nothing,lifetime,process)
* @return the level
*/
int getTraceLevel() {return traceLevel;}
/**
* @brief set trace level (0,1,2) means (nothing,lifetime,process)
* @param level The level
*/
void setTraceLevel(int level) {traceLevel = level;}
/**
* @brief ChannelFind method.
*
* @return pointer to self.
*/
virtual std::tr1::shared_ptr<ChannelProvider> getChannelProvider();
/**
* @brief ChannelFind method.
*
*/
virtual void cancel();
private: private:
shared_pointer getPtrSelf()
{
return shared_from_this();
}
ChannelProviderLocal();
friend epicsShareFunc ChannelProviderLocalPtr getChannelProviderLocal(); friend epicsShareFunc ChannelProviderLocalPtr getChannelProviderLocal();
PVDatabasePtr pvDatabase; PVDatabasePtr pvDatabase;
epics::pvData::Mutex mutex; epics::pvData::Mutex mutex;
bool beingDestroyed; int traceLevel;
epics::pvAccess::ChannelFind::shared_pointer channelFinder;
friend class ChannelProviderLocalRun; friend class ChannelProviderLocalRun;
}; };
@@ -229,12 +243,8 @@ public:
/** /**
* @brief Destroy the channel. * @brief Destroy the channel.
* *
* It cleans up all resources used to access the record.
* Note that this assumes that client has destroyed any objects that
* have been created for the channel like channelGet, etc.
* The remote pvAccess server does this cleanup.
*/ */
virtual void destroy(); virtual void destroy() EPICS_DEPRECATED {};
/** /**
* @brief Detach from the record. * @brief Detach from the record.
* *
@@ -404,7 +414,6 @@ private:
epics::pvAccess::ChannelRequester::shared_pointer requester; epics::pvAccess::ChannelRequester::shared_pointer requester;
ChannelProviderLocalPtr provider; ChannelProviderLocalPtr provider;
PVRecordPtr pvRecord; PVRecordPtr pvRecord;
bool isDestroyed;
epics::pvData::Mutex mutex; epics::pvData::Mutex mutex;
}; };

View File

@@ -264,14 +264,6 @@ protected:
* Must be called by derived classes. * Must be called by derived classes.
*/ */
void initPVRecord(); void initPVRecord();
/**
* @brief Get shared pointer to self.
* @return The shared pointer.
*/
PVRecordPtr getPtrSelf()
{
return shared_from_this();
}
private: private:
PVRecordFieldPtr findPVRecordField( PVRecordFieldPtr findPVRecordField(
PVRecordStructurePtr const & pvrs, PVRecordStructurePtr const & pvrs,
@@ -504,12 +496,6 @@ public:
* @brief Destructor * @brief Destructor
*/ */
virtual ~PVDatabase(); virtual ~PVDatabase();
/**
* @brief Destroy the PVDatabase.
*
* For each record in the database the record is removed and it's destroy method is called.
*/
virtual void destroy();
/** /**
* Find a record. * Find a record.
* An empty pointer is returned if the record is not in the database. * An empty pointer is returned if the record is not in the database.
@@ -541,7 +527,6 @@ private:
void unlock(); void unlock();
PVRecordMap recordMap; PVRecordMap recordMap;
epics::pvData::Mutex mutex; epics::pvData::Mutex mutex;
bool isDestroyed;
}; };
}} }}

View File

@@ -54,7 +54,6 @@ private:
RemoveRecord( RemoveRecord(
std::string const & recordName, std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure); epics::pvData::PVStructurePtr const & pvStructure);
PVDatabasePtr pvDatabase;
epics::pvData::PVStringPtr pvRecordName; epics::pvData::PVStringPtr pvRecordName;
epics::pvData::PVStringPtr pvResult; epics::pvData::PVStringPtr pvResult;
}; };

View File

@@ -55,7 +55,6 @@ private:
TraceRecord( TraceRecord(
std::string const & recordName, std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure); epics::pvData::PVStructurePtr const & pvStructure);
PVDatabasePtr pvDatabase;
epics::pvData::PVStringPtr pvRecordName; epics::pvData::PVStringPtr pvRecordName;
epics::pvData::PVIntPtr pvLevel; epics::pvData::PVIntPtr pvLevel;
epics::pvData::PVStringPtr pvResult; epics::pvData::PVStringPtr pvResult;

View File

@@ -103,7 +103,7 @@ public:
PVStructurePtr const & pvRequest, PVStructurePtr const & pvRequest,
PVRecordPtr const &pvRecord); PVRecordPtr const &pvRecord);
virtual void process(); virtual void process();
virtual void destroy(); virtual void destroy() EPICS_DEPRECATED {};
virtual std::tr1::shared_ptr<Channel> getChannel() virtual std::tr1::shared_ptr<Channel> getChannel()
{return channelLocal;} {return channelLocal;}
virtual void cancel(){} virtual void cancel(){}
@@ -121,14 +121,12 @@ private:
PVRecordPtr const &pvRecord, PVRecordPtr const &pvRecord,
int nProcess) int nProcess)
: :
isDestroyed(false),
channelLocal(channelLocal), channelLocal(channelLocal),
channelProcessRequester(channelProcessRequester), channelProcessRequester(channelProcessRequester),
pvRecord(pvRecord), pvRecord(pvRecord),
nProcess(nProcess) nProcess(nProcess)
{ {
} }
bool isDestroyed;
ChannelLocalPtr channelLocal; ChannelLocalPtr channelLocal;
ChannelProcessRequester::weak_pointer channelProcessRequester; ChannelProcessRequester::weak_pointer channelProcessRequester;
PVRecordPtr pvRecord; PVRecordPtr pvRecord;
@@ -174,30 +172,10 @@ ChannelProcessLocalPtr ChannelProcessLocal::create(
return process; return process;
} }
void ChannelProcessLocal::destroy()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "ChannelProcessLocal::destroy";
cout << " destroyed " << isDestroyed << endl;
}
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
}
void ChannelProcessLocal::process() void ChannelProcessLocal::process()
{ {
ChannelProcessRequester::shared_pointer requester = channelProcessRequester.lock(); ChannelProcessRequester::shared_pointer requester = channelProcessRequester.lock();
if(!requester) return; if(!requester) return;
if(isDestroyed) {
requester->processDone(channelDestroyedStatus,getPtrSelf());
return;
}
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "ChannelProcessLocal::process"; cout << "ChannelProcessLocal::process";
@@ -236,7 +214,7 @@ public:
PVStructurePtr const & pvRequest, PVStructurePtr const & pvRequest,
PVRecordPtr const &pvRecord); PVRecordPtr const &pvRecord);
virtual void get(); virtual void get();
virtual void destroy(); virtual void destroy() EPICS_DEPRECATED {};
virtual std::tr1::shared_ptr<Channel> getChannel() virtual std::tr1::shared_ptr<Channel> getChannel()
{return channelLocal;} {return channelLocal;}
virtual void cancel(){} virtual void cancel(){}
@@ -258,7 +236,6 @@ private:
PVRecordPtr const &pvRecord) PVRecordPtr const &pvRecord)
: :
firstTime(true), firstTime(true),
isDestroyed(false),
callProcess(callProcess), callProcess(callProcess),
channelLocal(channelLocal), channelLocal(channelLocal),
channelGetRequester(channelGetRequester), channelGetRequester(channelGetRequester),
@@ -269,7 +246,6 @@ private:
{ {
} }
bool firstTime; bool firstTime;
bool isDestroyed;
bool callProcess; bool callProcess;
ChannelLocalPtr channelLocal; ChannelLocalPtr channelLocal;
ChannelGetRequester::weak_pointer channelGetRequester; ChannelGetRequester::weak_pointer channelGetRequester;
@@ -323,29 +299,10 @@ ChannelGetLocalPtr ChannelGetLocal::create(
} }
void ChannelGetLocal::destroy()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "ChannelGetLocal::destroy";
cout << " destroyed " << isDestroyed << endl;
}
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
}
void ChannelGetLocal::get() void ChannelGetLocal::get()
{ {
ChannelGetRequester::shared_pointer requester = channelGetRequester.lock(); ChannelGetRequester::shared_pointer requester = channelGetRequester.lock();
if(!requester) return; if(!requester) return;
if(isDestroyed) {
requester->getDone(
channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet);
return;
}
try { try {
bitSet->clear(); bitSet->clear();
{ {
@@ -398,7 +355,7 @@ public:
PVRecordPtr const &pvRecord); PVRecordPtr const &pvRecord);
virtual void put(PVStructurePtr const &pvStructure,BitSetPtr const &bitSet); virtual void put(PVStructurePtr const &pvStructure,BitSetPtr const &bitSet);
virtual void get(); virtual void get();
virtual void destroy(); virtual void destroy() EPICS_DEPRECATED {};
virtual std::tr1::shared_ptr<Channel> getChannel() virtual std::tr1::shared_ptr<Channel> getChannel()
{return channelLocal;} {return channelLocal;}
virtual void cancel(){} virtual void cancel(){}
@@ -417,7 +374,6 @@ private:
PVCopyPtr const &pvCopy, PVCopyPtr const &pvCopy,
PVRecordPtr const &pvRecord) PVRecordPtr const &pvRecord)
: :
isDestroyed(false),
callProcess(callProcess), callProcess(callProcess),
channelLocal(channelLocal), channelLocal(channelLocal),
channelPutRequester(channelPutRequester), channelPutRequester(channelPutRequester),
@@ -425,7 +381,6 @@ private:
pvRecord(pvRecord) pvRecord(pvRecord)
{ {
} }
bool isDestroyed;
bool callProcess; bool callProcess;
ChannelLocalPtr channelLocal; ChannelLocalPtr channelLocal;
ChannelPutRequester::weak_pointer channelPutRequester; ChannelPutRequester::weak_pointer channelPutRequester;
@@ -474,29 +429,10 @@ ChannelPutLocalPtr ChannelPutLocal::create(
return put; return put;
} }
void ChannelPutLocal::destroy()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "ChannelPutLocal::destroy";
cout << " destroyed " << isDestroyed << endl;
}
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
}
void ChannelPutLocal::get() void ChannelPutLocal::get()
{ {
ChannelPutRequester::shared_pointer requester = channelPutRequester.lock(); ChannelPutRequester::shared_pointer requester = channelPutRequester.lock();
if(!requester) return; if(!requester) return;
if(isDestroyed) {
requester->getDone(
channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet);
return;
}
try { try {
PVStructurePtr pvStructure = pvCopy->createPVStructure(); PVStructurePtr pvStructure = pvCopy->createPVStructure();
BitSetPtr bitSet(new BitSet(pvStructure->getNumberFields())); BitSetPtr bitSet(new BitSet(pvStructure->getNumberFields()));
@@ -525,10 +461,6 @@ void ChannelPutLocal::put(
{ {
ChannelPutRequester::shared_pointer requester = channelPutRequester.lock(); ChannelPutRequester::shared_pointer requester = channelPutRequester.lock();
if(!requester) return; if(!requester) return;
if(isDestroyed) {
requester->putDone(channelDestroyedStatus,getPtrSelf());
return;
}
try { try {
{ {
epicsGuard <PVRecord> guard(*pvRecord); epicsGuard <PVRecord> guard(*pvRecord);
@@ -574,7 +506,7 @@ public:
BitSetPtr const &putBitSet); BitSetPtr const &putBitSet);
virtual void getPut(); virtual void getPut();
virtual void getGet(); virtual void getGet();
virtual void destroy(); virtual void destroy() EPICS_DEPRECATED {};
virtual std::tr1::shared_ptr<Channel> getChannel() virtual std::tr1::shared_ptr<Channel> getChannel()
{return channelLocal;} {return channelLocal;}
virtual void cancel(){} virtual void cancel(){}
@@ -596,7 +528,6 @@ private:
BitSetPtr const & getBitSet, BitSetPtr const & getBitSet,
PVRecordPtr const &pvRecord) PVRecordPtr const &pvRecord)
: :
isDestroyed(false),
callProcess(callProcess), callProcess(callProcess),
channelLocal(channelLocal), channelLocal(channelLocal),
channelPutGetRequester(channelPutGetRequester), channelPutGetRequester(channelPutGetRequester),
@@ -607,7 +538,6 @@ private:
pvRecord(pvRecord) pvRecord(pvRecord)
{ {
} }
bool isDestroyed;
bool callProcess; bool callProcess;
ChannelLocalPtr channelLocal; ChannelLocalPtr channelLocal;
ChannelPutGetRequester::weak_pointer channelPutGetRequester; ChannelPutGetRequester::weak_pointer channelPutGetRequester;
@@ -668,30 +598,11 @@ ChannelPutGetLocalPtr ChannelPutGetLocal::create(
} }
void ChannelPutGetLocal::destroy()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "ChannelPutGetLocal::destroy";
cout << " destroyed " << isDestroyed << endl;
}
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
}
void ChannelPutGetLocal::putGet( void ChannelPutGetLocal::putGet(
PVStructurePtr const &pvPutStructure,BitSetPtr const &putBitSet) PVStructurePtr const &pvPutStructure,BitSetPtr const &putBitSet)
{ {
ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock(); ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
if(!requester) return; if(!requester) return;
if(isDestroyed) {
requester->putGetDone(
channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet);
return;
}
try { try {
{ {
epicsGuard <PVRecord> guard(*pvRecord); epicsGuard <PVRecord> guard(*pvRecord);
@@ -718,11 +629,6 @@ void ChannelPutGetLocal::getPut()
{ {
ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock(); ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
if(!requester) return; if(!requester) return;
if(isDestroyed) {
requester->getPutDone(
channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet);
return;
}
try { try {
PVStructurePtr pvPutStructure = pvPutCopy->createPVStructure(); PVStructurePtr pvPutStructure = pvPutCopy->createPVStructure();
BitSetPtr putBitSet(new BitSet(pvPutStructure->getNumberFields())); BitSetPtr putBitSet(new BitSet(pvPutStructure->getNumberFields()));
@@ -748,11 +654,6 @@ void ChannelPutGetLocal::getGet()
{ {
ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock(); ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
if(!requester) return; if(!requester) return;
if(isDestroyed) {
requester->getGetDone(
channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet);
return;
}
try { try {
getBitSet->clear(); getBitSet->clear();
{ {
@@ -792,7 +693,6 @@ public:
ChannelRPCRequester::shared_pointer const & channelRPCRequester, ChannelRPCRequester::shared_pointer const & channelRPCRequester,
Service::shared_pointer const & service, Service::shared_pointer const & service,
PVRecordPtr const & pvRecord) : PVRecordPtr const & pvRecord) :
isDestroyed(),
channelLocal(channelLocal), channelLocal(channelLocal),
channelRPCRequester(channelRPCRequester), channelRPCRequester(channelRPCRequester),
service(service), service(service),
@@ -807,7 +707,6 @@ public:
{ {
cout << "~ChannelRPCLocal()" << endl; cout << "~ChannelRPCLocal()" << endl;
} }
destroy();
} }
void processRequest(RPCService::shared_pointer const & service, void processRequest(RPCService::shared_pointer const & service,
@@ -819,9 +718,6 @@ public:
ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock(); ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
if(!requester) return; if(!requester) return;
requester->requestDone(status, getPtrSelf(), result); requester->requestDone(status, getPtrSelf(), result);
if (isLastRequest.get())
destroy();
} }
void processRequest(RPCServiceAsync::shared_pointer const & service, void processRequest(RPCServiceAsync::shared_pointer const & service,
@@ -841,7 +737,7 @@ public:
virtual void cancel() {} virtual void cancel() {}
virtual void destroy(); virtual void destroy() EPICS_DEPRECATED {};
virtual void lock() {} virtual void lock() {}
@@ -854,7 +750,6 @@ private:
return shared_from_this(); return shared_from_this();
} }
AtomicBoolean isDestroyed;
ChannelLocalPtr channelLocal; ChannelLocalPtr channelLocal;
ChannelRPCRequester::weak_pointer channelRPCRequester; ChannelRPCRequester::weak_pointer channelRPCRequester;
Service::shared_pointer service; Service::shared_pointer service;
@@ -990,17 +885,6 @@ void ChannelRPCLocal::request(PVStructurePtr const & pvArgument)
} }
void ChannelRPCLocal::destroy()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "ChannelRPCLocal::destroy";
cout << " destroyed " << isDestroyed.get() << endl;
}
isDestroyed.set();
}
typedef std::tr1::shared_ptr<PVArray> PVArrayPtr; typedef std::tr1::shared_ptr<PVArray> PVArrayPtr;
class ChannelArrayLocal : class ChannelArrayLocal :
@@ -1027,7 +911,7 @@ public:
size_t offset, size_t count, size_t stride); size_t offset, size_t count, size_t stride);
virtual void getLength(); virtual void getLength();
virtual void setLength(size_t length); virtual void setLength(size_t length);
virtual void destroy(); virtual void destroy() EPICS_DEPRECATED {};
virtual std::tr1::shared_ptr<Channel> getChannel() virtual std::tr1::shared_ptr<Channel> getChannel()
{return channelLocal;} {return channelLocal;}
virtual void cancel(){} virtual void cancel(){}
@@ -1046,7 +930,6 @@ private:
PVArrayPtr const &pvCopy, PVArrayPtr const &pvCopy,
PVRecordPtr const &pvRecord) PVRecordPtr const &pvRecord)
: :
isDestroyed(false),
channelLocal(channelLocal), channelLocal(channelLocal),
channelArrayRequester(channelArrayRequester), channelArrayRequester(channelArrayRequester),
pvArray(pvArray), pvArray(pvArray),
@@ -1054,7 +937,7 @@ private:
pvRecord(pvRecord) pvRecord(pvRecord)
{ {
} }
bool isDestroyed;
ChannelLocalPtr channelLocal; ChannelLocalPtr channelLocal;
ChannelArrayRequester::weak_pointer channelArrayRequester; ChannelArrayRequester::weak_pointer channelArrayRequester;
PVArrayPtr pvArray; PVArrayPtr pvArray;
@@ -1147,29 +1030,11 @@ ChannelArrayLocalPtr ChannelArrayLocal::create(
return array; return array;
} }
void ChannelArrayLocal::destroy()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "ChannelArrayLocal::destroy";
cout << " destroyed " << isDestroyed << endl;
}
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
}
void ChannelArrayLocal::getArray(size_t offset, size_t count, size_t stride) void ChannelArrayLocal::getArray(size_t offset, size_t count, size_t stride)
{ {
ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock(); ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
if(!requester) return; if(!requester) return;
if(isDestroyed) {
requester->getArrayDone(channelDestroyedStatus,getPtrSelf(),pvCopy);
return;
}
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "ChannelArrayLocal::getArray" << endl; cout << "ChannelArrayLocal::getArray" << endl;
@@ -1218,10 +1083,7 @@ void ChannelArrayLocal::putArray(
{ {
ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock(); ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
if(!requester) return; if(!requester) return;
if(isDestroyed) {
requester->putArrayDone(channelDestroyedStatus,getPtrSelf());
return;
}
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "ChannelArrayLocal::putArray" << endl; cout << "ChannelArrayLocal::putArray" << endl;
@@ -1277,10 +1139,7 @@ void ChannelArrayLocal::setLength(size_t length)
{ {
ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock(); ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
if(!requester) return; if(!requester) return;
if(isDestroyed) {
requester->setLengthDone(channelDestroyedStatus,getPtrSelf());
return;
}
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "ChannelArrayLocal::setLength" << endl; cout << "ChannelArrayLocal::setLength" << endl;
@@ -1308,8 +1167,7 @@ ChannelLocal::ChannelLocal(
: :
requester(requester), requester(requester),
provider(provider), provider(provider),
pvRecord(pvRecord), pvRecord(pvRecord)
isDestroyed(false)
{ {
if(pvRecord->getTraceLevel()>0) { if(pvRecord->getTraceLevel()>0) {
cout << "ChannelLocal::ChannelLocal()" cout << "ChannelLocal::ChannelLocal()"
@@ -1325,26 +1183,10 @@ ChannelLocal::~ChannelLocal()
{ {
cout << "~ChannelLocal()" << endl; cout << "~ChannelLocal()" << endl;
} }
destroy();
}
void ChannelLocal::destroy()
{
if(pvRecord->getTraceLevel()>0) {
cout << "ChannelLocal::destroy()"
<< " recordName " << pvRecord->getRecordName()
<< " isDestroyed " << isDestroyed
<< " requester exists " << (requester ? "true" : "false")
<< endl;
}
{
Lock xx(mutex);
if(isDestroyed) return;
isDestroyed = true;
}
pvRecord->removePVRecordClient(getPtrSelf()); pvRecord->removePVRecordClient(getPtrSelf());
} }
void ChannelLocal::detach(PVRecordPtr const & pvRecord) void ChannelLocal::detach(PVRecordPtr const & pvRecord)
{ {
if(pvRecord->getTraceLevel()>0) { if(pvRecord->getTraceLevel()>0) {
@@ -1381,10 +1223,6 @@ void ChannelLocal::message(
<< " requester exists " << (requester ? "true" : "false") << " requester exists " << (requester ? "true" : "false")
<< endl; << endl;
} }
{
Lock xx(mutex);
if(isDestroyed) return;
}
if(requester) { if(requester) {
requester->message(message,messageType); requester->message(message,messageType);
return; return;
@@ -1402,8 +1240,6 @@ string ChannelLocal::getRemoteAddress()
Channel::ConnectionState ChannelLocal::getConnectionState() Channel::ConnectionState ChannelLocal::getConnectionState()
{ {
Lock xx(mutex);
if(isDestroyed) return Channel::DESTROYED;
return Channel::CONNECTED; return Channel::CONNECTED;
} }
@@ -1419,8 +1255,6 @@ ChannelRequester::shared_pointer ChannelLocal::getChannelRequester()
bool ChannelLocal::isConnected() bool ChannelLocal::isConnected()
{ {
Lock xx(mutex);
if(isDestroyed) return false;
return true; return true;
} }

View File

@@ -9,6 +9,9 @@
* @date 2013.04 * @date 2013.04
*/ */
#include <epicsThread.h>
#include <pv/serverContext.h> #include <pv/serverContext.h>
#include <pv/syncChannelFind.h> #include <pv/syncChannelFind.h>
@@ -27,80 +30,67 @@ using std::string;
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
static string providerName("local");
class LocalChannelProviderFactory; class LocalChannelProviderFactory;
typedef std::tr1::shared_ptr<LocalChannelProviderFactory> LocalChannelProviderFactoryPtr; typedef std::tr1::shared_ptr<LocalChannelProviderFactory> LocalChannelProviderFactoryPtr;
static string providerName("local");
static ChannelProviderLocalPtr channelProvider;
class LocalChannelProviderFactory : public ChannelProviderFactory class LocalChannelProviderFactory : public ChannelProviderFactory
{ {
public: public:
POINTER_DEFINITIONS(LocalChannelProviderFactory); POINTER_DEFINITIONS(LocalChannelProviderFactory);
virtual string getFactoryName() { return providerName;} virtual string getFactoryName() { return providerName;}
static LocalChannelProviderFactoryPtr create(
ChannelProviderLocalPtr const &channelProvider)
{
LocalChannelProviderFactoryPtr xxx(
new LocalChannelProviderFactory(channelProvider));
registerChannelProviderFactory(xxx);
return xxx;
}
virtual ChannelProvider::shared_pointer sharedInstance() virtual ChannelProvider::shared_pointer sharedInstance()
{ {
if(!channelProvider) channelProvider = ChannelProviderLocalPtr(new ChannelProviderLocal());
return channelProvider; return channelProvider;
} }
virtual ChannelProvider::shared_pointer newInstance() virtual ChannelProvider::shared_pointer newInstance()
{ {
cout << "LocalChannelProviderFactory::newInstance()\n";
throw std::logic_error("newInstance not Implemented"); throw std::logic_error("newInstance not Implemented");
} }
private:
LocalChannelProviderFactory(
ChannelProviderLocalPtr const &channelProvider)
: channelProvider(channelProvider)
{}
ChannelProviderLocalPtr channelProvider;
}; };
ChannelProviderLocalPtr getChannelProviderLocal() ChannelProviderLocalPtr getChannelProviderLocal()
{ {
static ChannelProviderLocalPtr channelProviderLocal; static int firstTime = 1;
static Mutex mutex; if (firstTime) {
Lock xx(mutex); firstTime = 0;
if(!channelProviderLocal) { ChannelProviderFactory::shared_pointer factory(
channelProviderLocal = ChannelProviderLocalPtr( new LocalChannelProviderFactory());
new ChannelProviderLocal()); ChannelProviderRegistry::servers()->add(factory);
ChannelProvider::shared_pointer xxx =
dynamic_pointer_cast<ChannelProvider>(channelProviderLocal);
channelProviderLocal->channelFinder =
SyncChannelFind::shared_pointer(new SyncChannelFind(xxx));
LocalChannelProviderFactoryPtr factory(LocalChannelProviderFactory::create(channelProviderLocal));
} }
return channelProviderLocal; ChannelProvider::shared_pointer channelProvider =
ChannelProviderRegistry::servers()->getProvider(providerName);
return std::tr1::dynamic_pointer_cast<ChannelProviderLocal>(channelProvider);
} }
ChannelProviderLocal::ChannelProviderLocal() ChannelProviderLocal::ChannelProviderLocal()
: pvDatabase(PVDatabase::getMaster()), : pvDatabase(PVDatabase::getMaster()),
beingDestroyed(false) traceLevel(0)
{ {
} }
ChannelProviderLocal::~ChannelProviderLocal() ChannelProviderLocal::~ChannelProviderLocal()
{ {
destroy(); if(traceLevel>0) {
cout << "ChannelProviderLocal::~ChannelProviderLocal() \n";
}
} }
void ChannelProviderLocal::destroy() std::tr1::shared_ptr<ChannelProvider> ChannelProviderLocal::getChannelProvider()
{ {
Lock xx(mutex); return shared_from_this();
if(beingDestroyed) return;
beingDestroyed = true;
pvDatabase->destroy();
pvDatabase.reset();
} }
void ChannelProviderLocal::cancel()
{
}
string ChannelProviderLocal::getProviderName() string ChannelProviderLocal::getProviderName()
{ {
return providerName; return providerName;
@@ -110,35 +100,41 @@ ChannelFind::shared_pointer ChannelProviderLocal::channelFind(
string const & channelName, string const & channelName,
ChannelFindRequester::shared_pointer const &channelFindRequester) ChannelFindRequester::shared_pointer const &channelFindRequester)
{ {
if(traceLevel>1) {
cout << "ChannelProviderLocal::channelFind " << "channelName" << endl;
}
Lock xx(mutex); Lock xx(mutex);
PVRecordPtr pvRecord = pvDatabase->findRecord(channelName); PVRecordPtr pvRecord = pvDatabase->findRecord(channelName);
if(pvRecord) { if(pvRecord) {
channelFindRequester->channelFindResult( channelFindRequester->channelFindResult(
Status::Ok, Status::Ok,
channelFinder, shared_from_this(),
true); true);
} else { } else {
Status notFoundStatus(Status::STATUSTYPE_ERROR,"pv not found"); Status notFoundStatus(Status::STATUSTYPE_ERROR,"pv not found");
channelFindRequester->channelFindResult( channelFindRequester->channelFindResult(
notFoundStatus, notFoundStatus,
channelFinder, shared_from_this(),
false); false);
} }
return channelFinder; return shared_from_this();
} }
ChannelFind::shared_pointer ChannelProviderLocal::channelList( ChannelFind::shared_pointer ChannelProviderLocal::channelList(
ChannelListRequester::shared_pointer const & channelListRequester) ChannelListRequester::shared_pointer const & channelListRequester)
{ {
if(traceLevel>1) {
cout << "ChannelProviderLocal::channelList\n";
}
PVStringArrayPtr records; PVStringArrayPtr records;
{ {
Lock guard(mutex); Lock guard(mutex);
records = pvDatabase->getRecordNames(); records = pvDatabase->getRecordNames();
} }
channelListRequester->channelListResult(Status::Ok, channelFinder, records->view(), false); channelListRequester->channelListResult(Status::Ok, shared_from_this(), records->view(), false);
return channelFinder; return shared_from_this();
} }
Channel::shared_pointer ChannelProviderLocal::createChannel( Channel::shared_pointer ChannelProviderLocal::createChannel(
@@ -146,11 +142,14 @@ Channel::shared_pointer ChannelProviderLocal::createChannel(
ChannelRequester::shared_pointer const &channelRequester, ChannelRequester::shared_pointer const &channelRequester,
short priority) short priority)
{ {
if(traceLevel>1) {
cout << "ChannelProviderLocal::createChannel " << "channelName" << endl;
}
Lock xx(mutex); Lock xx(mutex);
PVRecordPtr pvRecord = pvDatabase->findRecord(channelName); PVRecordPtr pvRecord = pvDatabase->findRecord(channelName);
if(pvRecord) { if(pvRecord) {
ChannelLocalPtr channel(new ChannelLocal( ChannelLocalPtr channel(new ChannelLocal(
getPtrSelf(),channelRequester,pvRecord)); shared_from_this(),channelRequester,pvRecord));
channelRequester->channelCreated( channelRequester->channelCreated(
Status::Ok, Status::Ok,
channel); channel);

View File

@@ -14,7 +14,6 @@
#include <epicsGuard.h> #include <epicsGuard.h>
#include <pv/thread.h> #include <pv/thread.h>
#include <pv/bitSetUtil.h> #include <pv/bitSetUtil.h>
#include <pv/queue.h>
#include <pv/timeStamp.h> #include <pv/timeStamp.h>
#define epicsExportSharedSymbols #define epicsExportSharedSymbols
@@ -34,16 +33,93 @@ namespace epics { namespace pvDatabase {
static MonitorPtr nullMonitor; static MonitorPtr nullMonitor;
static MonitorElementPtr NULLMonitorElement; static MonitorElementPtr NULLMonitorElement;
static Status failedToCreateMonitorStatus(Status::STATUSTYPE_ERROR,"failed to create monitor"); static Status failedToCreateMonitorStatus(Status::STATUSTYPE_ERROR,"failed to create monitor");
static Status wasDestroyedStatus(Status::STATUSTYPE_ERROR,"was destroyed");
static Status alreadyStartedStatus(Status::STATUSTYPE_ERROR,"already started"); static Status alreadyStartedStatus(Status::STATUSTYPE_ERROR,"already started");
static Status notStartedStatus(Status::STATUSTYPE_ERROR,"not started"); static Status notStartedStatus(Status::STATUSTYPE_ERROR,"not started");
static Status destroyedStatus(Status::STATUSTYPE_ERROR,"record is destroyed");
class MonitorElementQueue;
typedef Queue<MonitorElement> MonitorElementQueue;
typedef std::tr1::shared_ptr<MonitorElementQueue> MonitorElementQueuePtr; typedef std::tr1::shared_ptr<MonitorElementQueue> MonitorElementQueuePtr;
typedef std::tr1::shared_ptr<MonitorRequester> MonitorRequesterPtr;
class MonitorElementQueue
{
private:
MonitorElementPtrArray elements;
// TODO use size_t instead
int size;
int numberFree;
int numberUsed;
int nextGetFree;
int nextSetUsed;
int nextGetUsed;
int nextReleaseUsed;
public:
POINTER_DEFINITIONS(MonitorElementQueue);
MonitorElementQueue(std::vector<MonitorElementPtr> monitorElementArray)
: elements(monitorElementArray),
size(monitorElementArray.size()),
numberFree(size),
numberUsed(0),
nextGetFree(0),
nextSetUsed(0),
nextGetUsed(0),
nextReleaseUsed(0)
{
}
virtual ~MonitorElementQueue() {}
void clear()
{
numberFree = size;
numberUsed = 0;
nextGetFree = 0;
nextSetUsed = 0;
nextGetUsed = 0;
nextReleaseUsed = 0;
}
MonitorElementPtr getFree()
{
if(numberFree==0) return MonitorElementPtr();
numberFree--;
int ind = nextGetFree;
MonitorElementPtr queueElement = elements[nextGetFree++];
if(nextGetFree>=size) nextGetFree = 0;
return elements[ind];
}
void setUsed(MonitorElementPtr const &element)
{
if(element!=elements[nextSetUsed++]) {
throw std::logic_error("not correct queueElement");
}
numberUsed++;
if(nextSetUsed>=size) nextSetUsed = 0;
}
MonitorElementPtr getUsed()
{
if(numberUsed==0) return MonitorElementPtr();
int ind = nextGetUsed;
MonitorElementPtr queueElement = elements[nextGetUsed++];
if(nextGetUsed>=size) nextGetUsed = 0;
return elements[ind];
}
void releaseUsed(MonitorElementPtr const &element)
{
if(element!=elements[nextReleaseUsed++]) {
throw std::logic_error(
"not queueElement returned by last call to getUsed");
}
if(nextReleaseUsed>=size) nextReleaseUsed = 0;
numberUsed--;
numberFree++;
}
};
typedef std::tr1::shared_ptr<MonitorRequester> MonitorRequesterPtr;
class MonitorLocal : class MonitorLocal :
@@ -51,15 +127,15 @@ class MonitorLocal :
public PVListener, public PVListener,
public std::tr1::enable_shared_from_this<MonitorLocal> public std::tr1::enable_shared_from_this<MonitorLocal>
{ {
enum MonitorState {idle,active, destroyed}; enum MonitorState {idle,active,destroyed};
public: public:
POINTER_DEFINITIONS(MonitorLocal); POINTER_DEFINITIONS(MonitorLocal);
virtual ~MonitorLocal(); virtual ~MonitorLocal();
virtual Status start(); virtual Status start();
virtual Status stop(); virtual Status stop();
virtual MonitorElementPtr poll(); virtual MonitorElementPtr poll();
virtual void destroy(); virtual void destroy() EPICS_DEPRECATED {};
virtual void detach(PVRecordPtr const & pvRecord){destroy();} virtual void detach(PVRecordPtr const & pvRecord){}
virtual void release(MonitorElementPtr const & monitorElement); virtual void release(MonitorElementPtr const & monitorElement);
virtual void dataPut(PVRecordFieldPtr const & pvRecordField); virtual void dataPut(PVRecordFieldPtr const & pvRecordField);
virtual void dataPut( virtual void dataPut(
@@ -109,25 +185,8 @@ MonitorLocal::~MonitorLocal()
{ {
cout << "MonitorLocal::~MonitorLocal()" << endl; cout << "MonitorLocal::~MonitorLocal()" << endl;
} }
destroy();
} }
void MonitorLocal::destroy()
{
if(pvRecord->getTraceLevel()>0)
{
cout << "MonitorLocal::destroy state " << state << endl;
}
{
Lock xx(mutex);
if(state==destroyed) return;
}
if(state==active) stop();
{
Lock xx(mutex);
state = destroyed;
}
}
Status MonitorLocal::start() Status MonitorLocal::start()
{ {
@@ -137,8 +196,8 @@ Status MonitorLocal::start()
} }
{ {
Lock xx(mutex); Lock xx(mutex);
if(state==destroyed) return wasDestroyedStatus;
if(state==active) return alreadyStartedStatus; if(state==active) return alreadyStartedStatus;
if(state==destroyed) return destroyedStatus;
} }
pvRecord->addListener(getPtrSelf(),pvCopy); pvRecord->addListener(getPtrSelf(),pvCopy);
epicsGuard <PVRecord> guard(*pvRecord); epicsGuard <PVRecord> guard(*pvRecord);
@@ -161,10 +220,10 @@ Status MonitorLocal::stop()
} }
{ {
Lock xx(mutex); Lock xx(mutex);
if(state==destroyed) return wasDestroyedStatus;
if(state==idle) return notStartedStatus; if(state==idle) return notStartedStatus;
if(state==destroyed) return destroyedStatus;
state = idle; state = idle;
} }
pvRecord->removeListener(getPtrSelf(),pvCopy); pvRecord->removeListener(getPtrSelf(),pvCopy);
return Status::Ok; return Status::Ok;
} }
@@ -204,9 +263,10 @@ void MonitorLocal::releaseActiveElement()
{ {
Lock xx(queueMutex); Lock xx(queueMutex);
if(state!=active) return; if(state!=active) return;
pvCopy->updateCopyFromBitSet(activeElement->pvStructurePtr,activeElement->changedBitSet);
if(activeElement->changedBitSet->nextSetBit(0)<0) return;
MonitorElementPtr newActive = queue->getFree(); MonitorElementPtr newActive = queue->getFree();
if(!newActive) return; if(!newActive) return;
pvCopy->updateCopyFromBitSet(activeElement->pvStructurePtr,activeElement->changedBitSet);
BitSetUtil::compress(activeElement->changedBitSet,activeElement->pvStructurePtr); BitSetUtil::compress(activeElement->changedBitSet,activeElement->pvStructurePtr);
BitSetUtil::compress(activeElement->overrunBitSet,activeElement->pvStructurePtr); BitSetUtil::compress(activeElement->overrunBitSet,activeElement->pvStructurePtr);
queue->setUsed(activeElement); queue->setUsed(activeElement);
@@ -309,6 +369,10 @@ void MonitorLocal::unlisten(PVRecordPtr const & pvRecord)
{ {
cout << "PVCopyMonitor::unlisten\n"; cout << "PVCopyMonitor::unlisten\n";
} }
{
Lock xx(mutex);
state = destroyed;
}
MonitorRequesterPtr requester = monitorRequester.lock(); MonitorRequesterPtr requester = monitorRequester.lock();
if(requester) { if(requester) {
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
@@ -317,7 +381,6 @@ void MonitorLocal::unlisten(PVRecordPtr const & pvRecord)
} }
requester->unlisten(getPtrSelf()); requester->unlisten(getPtrSelf());
} }
pvRecord->removeListener(getPtrSelf(),pvCopy);
} }
@@ -384,18 +447,12 @@ bool MonitorLocal::init(PVStructurePtr const & pvRequest)
MonitorFactory::MonitorFactory() MonitorFactory::MonitorFactory()
: isDestroyed(false)
{ {
} }
MonitorFactory::~MonitorFactory() MonitorFactory::~MonitorFactory()
{ {
}
void MonitorFactory::destroy()
{
Lock lock(mutex);
isDestroyed = true;
} }
MonitorPtr MonitorFactory::createMonitor( MonitorPtr MonitorFactory::createMonitor(
@@ -404,10 +461,6 @@ MonitorPtr MonitorFactory::createMonitor(
PVStructurePtr const & pvRequest) PVStructurePtr const & pvRequest)
{ {
Lock xx(mutex); Lock xx(mutex);
if(isDestroyed) {
monitorRequester->message("MonitorFactory is destroyed",errorMessage);
return nullMonitor;
}
MonitorLocalPtr monitor(new MonitorLocal( MonitorLocalPtr monitor(new MonitorLocal(
monitorRequester,pvRecord)); monitorRequester,pvRecord));
bool result = monitor->init(pvRequest); bool result = monitor->init(pvRequest);
@@ -419,8 +472,8 @@ MonitorPtr MonitorFactory::createMonitor(
} }
if(pvRecord->getTraceLevel()>0) if(pvRecord->getTraceLevel()>0)
{ {
cout << "MonitorFactory::createMonitor"; cout << "MonitorFactory::createMonitor"
cout << " recordName " << pvRecord->getRecordName() << endl; << " recordName " << pvRecord->getRecordName() << endl;
} }
return monitor; return monitor;
} }

View File

@@ -53,18 +53,15 @@ extern "C" void pvdbl(const iocshArgBuf *args)
for(size_t i=0; i<xxx.size(); ++i) cout<< xxx[i] << endl; for(size_t i=0; i<xxx.size(); ++i) cout<< xxx[i] << endl;
} }
static void channelProviderLocalExitHandler(void* /*pPrivate*/) {
getChannelProviderLocal()->destroy();
}
static void registerChannelProviderLocal(void) static void registerChannelProviderLocal(void)
{ {
static int firstTime = 1; static int firstTime = 1;
cout << "registerChannelProviderLocal firstTime " << (firstTime ? "true" : "false") << endl;
if (firstTime) { if (firstTime) {
firstTime = 0; firstTime = 0;
iocshRegister(&pvdblFuncDef, pvdbl); iocshRegister(&pvdblFuncDef, pvdbl);
getChannelProviderLocal(); getChannelProviderLocal();
epicsAtExit(channelProviderLocalExitHandler, NULL);
} }
} }

View File

@@ -42,8 +42,7 @@ RemoveRecordPtr RemoveRecord::create(
RemoveRecord::RemoveRecord( RemoveRecord::RemoveRecord(
std::string const & recordName, std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure) epics::pvData::PVStructurePtr const & pvStructure)
: PVRecord(recordName,pvStructure), : PVRecord(recordName,pvStructure)
pvDatabase(PVDatabase::getMaster())
{ {
} }
@@ -61,7 +60,7 @@ bool RemoveRecord::init()
void RemoveRecord::process() void RemoveRecord::process()
{ {
string name = pvRecordName->get(); string name = pvRecordName->get();
PVRecordPtr pvRecord = pvDatabase->findRecord(name); PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name);
if(!pvRecord) { if(!pvRecord) {
pvResult->put(name + " not found"); pvResult->put(name + " not found");
return; return;

View File

@@ -43,8 +43,7 @@ TraceRecordPtr TraceRecord::create(
TraceRecord::TraceRecord( TraceRecord::TraceRecord(
std::string const & recordName, std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure) epics::pvData::PVStructurePtr const & pvStructure)
: PVRecord(recordName,pvStructure), : PVRecord(recordName,pvStructure)
pvDatabase(PVDatabase::getMaster())
{ {
} }
@@ -65,7 +64,7 @@ bool TraceRecord::init()
void TraceRecord::process() void TraceRecord::process()
{ {
string name = pvRecordName->get(); string name = pvRecordName->get();
PVRecordPtr pvRecord = pvDatabase->findRecord(name); PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name);
if(!pvRecord) { if(!pvRecord) {
pvResult->put(name + " not found"); pvResult->put(name + " not found");
return; return;

View File

@@ -5,7 +5,9 @@ include $(TOP)/configure/CONFIG
PVDATABASE_TEST = $(TOP)/test PVDATABASE_TEST = $(TOP)/test
PROD_LIBS += pvDatabase pvAccess pvData Com PROD_LIBS += pvDatabase
PROD_LIBS += $(EPICS_BASE_PVA_CORE_LIBS)
PROD_LIBS += $(EPICS_BASE_IOC_LIBS)
include $(PVDATABASE_TEST)/src/Makefile include $(PVDATABASE_TEST)/src/Makefile
@@ -24,5 +26,3 @@ TESTSPEC_RTEMS = rtemsTestHarness.$(MUNCH_SUFFIX); pvDatabaseAllTests
TESTSCRIPTS_HOST += $(TESTS:%=%.t) TESTSCRIPTS_HOST += $(TESTS:%=%.t)
include $(TOP)/configure/RULES include $(TOP)/configure/RULES