Compare commits
147 Commits
R3.13.0-be
...
R3.13.0-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22b550ed35 | ||
|
|
a17b659a86 | ||
|
|
b5e120d082 | ||
|
|
b8d6a8216e | ||
|
|
5587867f6f | ||
|
|
be33ae291e | ||
|
|
932a4b0d5c | ||
|
|
7452aea2bc | ||
|
|
178e034e75 | ||
|
|
cbb5a6acde | ||
|
|
08a8e874eb | ||
|
|
29f381b8f4 | ||
|
|
5d123c6a4d | ||
|
|
2d999ed858 | ||
|
|
956fba853e | ||
|
|
97b96da957 | ||
|
|
63a377ce99 | ||
|
|
84df076e38 | ||
|
|
582d4b64cd | ||
|
|
ebebde9539 | ||
|
|
8771c33c46 | ||
|
|
3eae90a803 | ||
|
|
693de689e9 | ||
|
|
a30a0fcbaa | ||
|
|
0283890686 | ||
|
|
c1d0a4ad5a | ||
|
|
b2fcff709b | ||
|
|
aed16987e2 | ||
|
|
b6a5423a1f | ||
|
|
9610b9a07d | ||
|
|
98df963844 | ||
|
|
19f9d0c14d | ||
|
|
a5e1223b0c | ||
|
|
0db9c03505 | ||
|
|
a3ce428cdd | ||
|
|
057e1723cb | ||
|
|
0f156d5219 | ||
|
|
1d39b11b7f | ||
|
|
9e12de8e4f | ||
|
|
4aa19f07d7 | ||
|
|
142b7515e3 | ||
|
|
8feefadabf | ||
|
|
6a9030e5e6 | ||
|
|
bece5d0b9a | ||
|
|
24e0989142 | ||
|
|
815668143f | ||
|
|
737278aa41 | ||
|
|
c14d23494c | ||
|
|
d611fa2d75 | ||
|
|
1aa384308d | ||
|
|
2e80e8c2ee | ||
|
|
0830382ec7 | ||
|
|
c253066bc7 | ||
|
|
6fca0cd260 | ||
|
|
470152454b | ||
|
|
4a8507cb0d | ||
|
|
6917b31975 | ||
|
|
0cf19108db | ||
|
|
01b3617614 | ||
|
|
27567a54ed | ||
|
|
c04f34be42 | ||
|
|
0d2b196be2 | ||
|
|
7c23cf9c8c | ||
|
|
2d0dd7828f | ||
|
|
6fbc050c96 | ||
|
|
5856008613 | ||
|
|
f3003d9052 | ||
|
|
340ffec332 | ||
|
|
91c6f156ff | ||
|
|
2008c19e7d | ||
|
|
4dcb0e3ae6 | ||
|
|
74bc7758b5 | ||
|
|
17143d0e12 | ||
|
|
40be4d1cd5 | ||
|
|
d1ba9be665 | ||
|
|
7f6bd17474 | ||
|
|
6a534ca2b5 | ||
|
|
26ec4dd5c8 | ||
|
|
a0db9a2eb2 | ||
|
|
b5a102ef79 | ||
|
|
ed1491bb7b | ||
|
|
7fabc325bb | ||
|
|
5b546d2467 | ||
|
|
6440239832 | ||
|
|
cb6c444a19 | ||
|
|
c251b05020 | ||
|
|
1f7cc343c5 | ||
|
|
d67eb28145 | ||
|
|
3001f7e82f | ||
|
|
3982ea7d17 | ||
|
|
3fe00ec2a9 | ||
|
|
11fa08c1e0 | ||
|
|
b8d2273683 | ||
|
|
77fc9734b1 | ||
|
|
289302f603 | ||
|
|
a01241aa19 | ||
|
|
525842b076 | ||
|
|
03a4c8ad01 | ||
|
|
8a7158b3c6 | ||
|
|
08c57574d5 | ||
|
|
a6c40247f1 | ||
|
|
86969d7b3a | ||
|
|
a3c13f6da6 | ||
|
|
0d0566253e | ||
|
|
15fda603a5 | ||
|
|
7c0895bd82 | ||
|
|
5311ba4c15 | ||
|
|
27b0c05bcf | ||
|
|
435208afa8 | ||
|
|
0f1f7fc30c | ||
|
|
471acea0fc | ||
|
|
e122d8f4a6 | ||
|
|
53bde9e545 | ||
|
|
2ccaa6dcb6 | ||
|
|
8c8b971221 | ||
|
|
dd43f91278 | ||
|
|
6b3a62de9f | ||
|
|
4bd45337bf | ||
|
|
9351447cf2 | ||
|
|
b9cdf72ee1 | ||
|
|
81000e9391 | ||
|
|
19b81912fb | ||
|
|
b7df13b4fe | ||
|
|
2f3befc845 | ||
|
|
826b68b652 | ||
|
|
aece23e6ee | ||
|
|
3a9ddfbdbb | ||
|
|
11bdb5f6d4 | ||
|
|
741450ce9e | ||
|
|
868e6c417d | ||
|
|
0c19e23835 | ||
|
|
342ffb5d83 | ||
|
|
afa44fae79 | ||
|
|
333b379287 | ||
|
|
36f74c934e | ||
|
|
8f41686a98 | ||
|
|
75feb3a5d4 | ||
|
|
50ace741fe | ||
|
|
036cd8dd26 | ||
|
|
9758aa4a45 | ||
|
|
cf1cb554f6 | ||
|
|
ee68f746c6 | ||
|
|
85f2cf5833 | ||
|
|
5819ac0c48 | ||
|
|
3e26a12948 | ||
|
|
279385ecb9 | ||
|
|
75c91c8035 |
@@ -10,6 +10,9 @@
|
||||
# [-b] - For fully built release
|
||||
#
|
||||
# $Log$
|
||||
# Revision 1.8 1996/07/02 13:45:09 jba
|
||||
# Added dbd and base/config dirs. Removed epics/config and base/rec.
|
||||
#
|
||||
# Revision 1.7 1996/06/25 21:54:42 jba
|
||||
# Command line parm now base dir
|
||||
#
|
||||
@@ -75,9 +78,13 @@ fi
|
||||
|
||||
|
||||
FULLY_BUILT=NO
|
||||
if [ "${2}" = "-b" ]; then
|
||||
if [ "${1}" = "-b" ]; then
|
||||
FULLY_BUILT=YES
|
||||
shift
|
||||
if [ "${1}" != "." ]; then
|
||||
echo "TOP: Cannot create a fully built release.";
|
||||
exit 1;
|
||||
fi
|
||||
fi
|
||||
|
||||
# Retrieve EPICS release string from src/include/epicsVersion.h
|
||||
|
||||
6
Makefile
6
Makefile
@@ -22,11 +22,11 @@ include $(TOP)/config/RULES_TOP
|
||||
|
||||
release:
|
||||
@echo TOP: Creating Release...
|
||||
@./MakeRelease ${TOP}
|
||||
@./MakeRelease
|
||||
|
||||
built_release: install
|
||||
built_release:
|
||||
@echo TOP: Creating Fully Built Release...
|
||||
@./MakeRelease ${TOP} -b
|
||||
@./MakeRelease -b $(INSTALL_LOCATION)
|
||||
|
||||
uninstall::
|
||||
@DIR1=`pwd`;cd $(INSTALL_LOCATION);DIR2=`pwd`;cd $$DIR1;\
|
||||
|
||||
36
README
36
README
@@ -1,7 +1,7 @@
|
||||
$Id$
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
3.12 EPICS BASE Notes and Build Instructions.
|
||||
3.13 EPICS BASE Notes and Build Instructions.
|
||||
- By Matthew Needes
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
@@ -41,19 +41,43 @@ Notes:
|
||||
1.3 To build EPICS:
|
||||
|
||||
cd epics/base
|
||||
gnumake - To build and install EPICS.
|
||||
gnumake - To install include files, build and install EPICS.
|
||||
(Same as "gnumake inc install")
|
||||
gnumake all - Same as "gnumake"
|
||||
gnumake clean - To clean temporary object files. Top level
|
||||
clean will remove all the O.ARCH dirs, not
|
||||
only those specified in BUILD_ARCHS.
|
||||
gnumake uninstall - Only available at the top level directory.
|
||||
Cleans directories created by the install.
|
||||
gnumake rebuild - Same as "gnumake clean uninstall all"
|
||||
|
||||
1.4 "Partial" build commands:
|
||||
|
||||
gnumake clean.sun4 - Cleans sun4 binaries in O.sun4 dirs only.
|
||||
gnumake install.sun4 - Builds sun4 only.
|
||||
gnumake install.mv167 - Builds mv167 only (a HOST_ARCH build must
|
||||
be complete before this can be issued).
|
||||
The complete set of targets now supported are:
|
||||
|
||||
action
|
||||
arch
|
||||
action.arch
|
||||
dir
|
||||
dir.action
|
||||
dir.arch
|
||||
dir.action.arch
|
||||
|
||||
where:
|
||||
action can be clean, inc, install, depends, or build
|
||||
action can also be uninstall or rebuild at top level only
|
||||
dir is the name of a subdirectory.
|
||||
arch can be host, cross, sun4, solaris, mv167, ...
|
||||
|
||||
Examples are:
|
||||
|
||||
gnumake inc - To install include files
|
||||
gnumake install.host - To build and install EPICS for host arch.
|
||||
gnumake install.cross - To build and install EPICS for Vx archs.
|
||||
gnumake clean.sun4 - Cleans sun4 binaries in O.sun4 dirs only.
|
||||
gnumake install.sun4 - Builds sun4 only.
|
||||
gnumake install.mv167 - Builds mv167 only (a HOST_ARCH build must
|
||||
be complete before this can be issued).
|
||||
|
||||
NOTES:
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ YACC = $(EYACC)
|
||||
LEX = $(ELEX)
|
||||
G++ = g++
|
||||
CCC = CC
|
||||
MV = mv
|
||||
RMDIR = rm -rf
|
||||
MKDIR = mkdir
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ YACC = $(EYACC)
|
||||
LEX = $(ELEX)
|
||||
G++ = g++
|
||||
CCC = CC
|
||||
MV = mv
|
||||
RMDIR = rm -rf
|
||||
MKDIR = mkdir
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ YACC = $(EYACC)
|
||||
LEX = $(ELEX)
|
||||
G++ = g++
|
||||
CCC = CC
|
||||
MV = mv
|
||||
RMDIR = rm -rf
|
||||
MKDIR = mkdir
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ YACC = $(EYACC)
|
||||
LEX = $(ELEX)
|
||||
G++ = g++
|
||||
CCC = CC
|
||||
MV = mv
|
||||
RMDIR = rm -rf
|
||||
MKDIR = mkdir
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ YACC = $(EYACC)
|
||||
LEX = $(ELEX)
|
||||
G++ = /opt/gnu/bin/g++
|
||||
CCC = /opt/SUNWspro/bin/CC
|
||||
MV = mv
|
||||
RMDIR = rm -rf
|
||||
MKDIR = mkdir
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ YACC = $(EYACC)
|
||||
LEX = $(ELEX)
|
||||
G++ = g++
|
||||
CCC = /usr/lang/CC
|
||||
MV = mv
|
||||
RMDIR = rm -rf
|
||||
MKDIR = mkdir
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
# the order of following list is important
|
||||
|
||||
# for c++ build add the dirs gdd and cas after ca
|
||||
|
||||
DIRS = \
|
||||
tools \
|
||||
include \
|
||||
@@ -16,8 +18,6 @@ DIRS = \
|
||||
db \
|
||||
bpt \
|
||||
ca \
|
||||
gdd \
|
||||
cas \
|
||||
util \
|
||||
misc \
|
||||
sequencer \
|
||||
|
||||
@@ -36,7 +36,7 @@ endif
|
||||
# hkv2f
|
||||
# niCpu030
|
||||
#
|
||||
CROSS_COMPILER_TARGET_ARCHS=mv167
|
||||
CROSS_COMPILER_TARGET_ARCHS=mv167 mv162
|
||||
|
||||
# If only a subset of the host architectures perform
|
||||
# the build for the CROSS_COMPILER_TARGET_ARCHS
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# $Id$
|
||||
|
||||
VPATH += .:..
|
||||
|
||||
INSTALL_PROD=$(PROD:%=$(INSTALL_BIN)/%)
|
||||
INSTALL_LIBS=$(LIBNAME:%=$(INSTALL_LIB)/%)
|
||||
INSTALL_INC=$(INC:%=$(INSTALL_INCLUDE)/%)
|
||||
@@ -25,6 +23,8 @@ all:: install
|
||||
|
||||
pre_build::
|
||||
|
||||
rebuild:: clean install
|
||||
|
||||
build:: pre_build $(LIBNAME) $(TARGETS) $(PROD)
|
||||
|
||||
inc:: $(INSTALL_INC)
|
||||
@@ -59,7 +59,7 @@ $(TARGETS) $(PROD): $(DEPLIBS)
|
||||
$(RM) $@
|
||||
$(LINK.c) -o $@ $< $(LDLIBS)
|
||||
|
||||
#$(PROD): $(OBJS) $(DEPLIBS)
|
||||
#$(PROD): $(OBJS)
|
||||
# $(RM) $@
|
||||
# $(LINK.c) -o $@ ${OBJS} $(LDLIBS)
|
||||
|
||||
@@ -67,32 +67,40 @@ $(TARGETS) $(PROD): $(DEPLIBS)
|
||||
$(RM) $@
|
||||
$(COMPILE.c) $<
|
||||
|
||||
%.o: ../%.c
|
||||
$(RM) $@
|
||||
$(COMPILE.c) $<
|
||||
|
||||
%.o: %.cc
|
||||
$(RM) $@
|
||||
$(COMPILE.cc) $<
|
||||
|
||||
%.c: %.y
|
||||
%.o: ../%.cc
|
||||
$(RM) $@
|
||||
$(COMPILE.cc) $<
|
||||
|
||||
%.c: ../%.y
|
||||
$(RM) y.tab.c y.tab.h
|
||||
$(YACC) $(YACCOPT) $<
|
||||
@if [ -f y.tab.c ]; \
|
||||
then \
|
||||
echo "/bin/mv y.tab.c $*.c"; \
|
||||
/bin/mv y.tab.c $*.c; \
|
||||
echo "$(MV) y.tab.c $*.c"; \
|
||||
$(MV) y.tab.c $*.c; \
|
||||
fi
|
||||
@if [ -f y.tab.h ]; \
|
||||
then \
|
||||
echo "/bin/mv y.tab.h $*.h"; \
|
||||
/bin/mv y.tab.h $*.h; \
|
||||
echo "$(MV) y.tab.h $*.h"; \
|
||||
$(MV) y.tab.h $*.h; \
|
||||
fi
|
||||
|
||||
%.c: %.l
|
||||
%.c: ../%.l
|
||||
$(RM) lex.yy.c
|
||||
$(LEX) $(LEXOPT) $<
|
||||
$(RM) $@
|
||||
/bin/mv lex.yy.c $@
|
||||
$(MV) lex.yy.c $@
|
||||
|
||||
#state notation language rules
|
||||
%.c: %.st
|
||||
#state notation language rule
|
||||
%.c: ../%.st
|
||||
@echo "preprocessing $*.st"
|
||||
@$(RM) $*.i
|
||||
$(CPP) $(CPPFLAGS) $< $*.i
|
||||
@@ -109,6 +117,9 @@ $(TARGETS) $(PROD): $(DEPLIBS)
|
||||
%.db: %.edf
|
||||
$(E2DB) $(E2SR_SYSFLAGS) $(E2SR_FLAGS) $<
|
||||
|
||||
%.db: ../%.edf
|
||||
$(E2DB) $(E2SR_SYSFLAGS) $(E2SR_FLAGS) $<
|
||||
|
||||
%.edf: ../%.sch $(DEPSCHS)
|
||||
@if [ ! -f cad.rc -a -r ../cad.rc ] ; then ln -s ../cad.rc ; fi
|
||||
$(SCH2EDIF) $(SCH2EDIF_SYSFLAGS) $(SCH2EDIF_FLAGS) $<
|
||||
@@ -119,8 +130,15 @@ $(TARGETS) $(PROD): $(DEPLIBS)
|
||||
$(RM) $(<F).nr
|
||||
ln -s $<
|
||||
$(MANGEN) -s $(<F)
|
||||
mv $(<F).nr $(<F).1
|
||||
$(MV) $(<F).nr $(<F).1
|
||||
|
||||
# Mangen Rule:
|
||||
%.1:../%
|
||||
$(RM) $(<F)
|
||||
$(RM) $(<F).nr
|
||||
ln -s $<
|
||||
$(MANGEN) -s $(<F)
|
||||
$(MV) $(<F).nr $(<F).1
|
||||
|
||||
$(LIBNAME): $(LIBOBJS)
|
||||
@echo Building library $@
|
||||
@@ -137,6 +155,12 @@ $(INSTALL_BIN)/%: %
|
||||
@test -d $(INSTALL_BIN) || mkdir $(INSTALL_BIN)
|
||||
@$(INSTALL_PRODUCT) -m 555 $< $(INSTALL_BIN)
|
||||
|
||||
$(INSTALL_BIN)/%: ../%
|
||||
@echo "Installing $@"
|
||||
@test -d $(INSTALL_LOCATION_BIN) || mkdir $(INSTALL_LOCATION_BIN)
|
||||
@test -d $(INSTALL_BIN) || mkdir $(INSTALL_BIN)
|
||||
@$(INSTALL_PRODUCT) -m 555 $< $(INSTALL_BIN)
|
||||
|
||||
$(INSTALL_LIB)/%.a: %.a
|
||||
@echo "Installing library $@"
|
||||
@test -d $(INSTALL_LOCATION_LIB) || mkdir $(INSTALL_LOCATION_LIB)
|
||||
@@ -151,7 +175,12 @@ $(INSTALL_CONFIG)/%: %
|
||||
@test -d $(INSTALL_CONFIG) || mkdir $(INSTALL_CONFIG)
|
||||
@$(INSTALL) -m 644 $< $(INSTALL_CONFIG)
|
||||
|
||||
$(INSTALL_TCLLIB)/%: %
|
||||
$(INSTALL_CONFIG)/%: ../%
|
||||
@echo "Installing $@"
|
||||
@test -d $(INSTALL_CONFIG) || mkdir $(INSTALL_CONFIG)
|
||||
@$(INSTALL) -m 644 $< $(INSTALL_CONFIG)
|
||||
|
||||
$(INSTALL_TCLLIB)/%: ../%
|
||||
@echo "Installing Tcl library $@"
|
||||
@test -d $(INSTALL_LOCATION_LIB) || mkdir $(INSTALL_LOCATION_LIB)
|
||||
@test -d $(INSTALL_LIB) || mkdir $(INSTALL_LIB)
|
||||
@@ -175,23 +204,57 @@ $(INSTALL_MAN)/man1/%: %
|
||||
@test -d $(@D) || mkdir $(@D)
|
||||
@$(INSTALL) -m 644 $< $(@D)
|
||||
|
||||
$(INSTALL_MAN)/man9/% \
|
||||
$(INSTALL_MAN)/man8/% \
|
||||
$(INSTALL_MAN)/man7/% \
|
||||
$(INSTALL_MAN)/man6/% \
|
||||
$(INSTALL_MAN)/man5/% \
|
||||
$(INSTALL_MAN)/man4/% \
|
||||
$(INSTALL_MAN)/man3/% \
|
||||
$(INSTALL_MAN)/man2/% \
|
||||
$(INSTALL_MAN)/man1/%: ../%
|
||||
@echo "Installing $@"
|
||||
@test -d $(INSTALL_MAN) || mkdir $(INSTALL_MAN)
|
||||
@test -d $(@D) || mkdir $(@D)
|
||||
@$(INSTALL) -m 644 $< $(@D)
|
||||
|
||||
$(INSTALL_INCLUDE)/%: %
|
||||
@echo "Installing $@"
|
||||
@test -d $(INSTALL_INCLUDE) || mkdir $(INSTALL_INCLUDE)
|
||||
@$(INSTALL) -m 644 $< $(INSTALL_INCLUDE)
|
||||
|
||||
$(INSTALL_INCLUDE)/%: ../%
|
||||
@echo "Installing $@"
|
||||
@test -d $(INSTALL_INCLUDE) || mkdir $(INSTALL_INCLUDE)
|
||||
@$(INSTALL) -m 644 $< $(INSTALL_INCLUDE)
|
||||
|
||||
$(INSTALL_DOC)/%: %
|
||||
@echo "Installing $@"
|
||||
@test -d $(INSTALL_DOC) || mkdir $(INSTALL_DOC)
|
||||
@$(INSTALL) -m 644 $< $(INSTALL_DOC)
|
||||
|
||||
$(INSTALL_DOC)/%: ../%
|
||||
@echo "Installing $@"
|
||||
@test -d $(INSTALL_DOC) || mkdir $(INSTALL_DOC)
|
||||
@$(INSTALL) -m 644 $< $(INSTALL_DOC)
|
||||
|
||||
$(INSTALL_TEMPLATES)/$(TEMPLATES_DIR)/%: ../%
|
||||
@echo "Installing $@"
|
||||
@test -d $(INSTALL_TEMPLATES) || mkdir $(INSTALL_TEMPLATES)
|
||||
@test -d $(INSTALL_TEMPLATES)/$(TEMPLATES_DIR) || \
|
||||
mkdir $(INSTALL_TEMPLATES)/$(TEMPLATES_DIR)
|
||||
@$(INSTALL) -d -m 644 $< $(INSTALL_TEMPLATES)/$(TEMPLATES_DIR)
|
||||
|
||||
$(INSTALL_TEMPLATES)/$(TEMPLATES_DIR)/%: %
|
||||
@echo "Installing $@"
|
||||
@test -d $(INSTALL_TEMPLATES) || mkdir $(INSTALL_TEMPLATES)
|
||||
@test -d $(INSTALL_TEMPLATES)/$(TEMPLATES_DIR) || \
|
||||
mkdir $(INSTALL_TEMPLATES)/$(TEMPLATES_DIR)
|
||||
@$(INSTALL) -d -m 644 $< $(INSTALL_TEMPLATES)/$(TEMPLATES_DIR)
|
||||
|
||||
.PRECIOUS: %.o %.c
|
||||
|
||||
.PHONY: all inc depends build install pre-build clean
|
||||
.PHONY: all inc depends build install pre-build clean rebuild
|
||||
|
||||
-include .DEPENDS
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# $Id$
|
||||
|
||||
VPATH += .:..
|
||||
|
||||
INCREC +=$(RECTYPES) $(MENUS)
|
||||
INSTALL_PROD=$(PROD:%=$(INSTALL_BIN)/%)
|
||||
INSTALL_LIBS=$(LIBNAME:%=$(INSTALL_BIN)/%)
|
||||
@@ -29,10 +27,12 @@ INSTALL_DBDNAME=$(DBDNAME:%=$(INSTALL_DBD)/%)
|
||||
|
||||
all:: install
|
||||
|
||||
rebuild:: clean install
|
||||
|
||||
pre_build::
|
||||
|
||||
build:: pre_build $(MENUS) $(RECTYPES) $(BPTS)\
|
||||
$(LIBNAME) $(TARGETS) $(PROD) $(DBDEXPAND)
|
||||
$(LIBNAME) $(TARGETS) $(PROD) $(DBDNAME)
|
||||
|
||||
inc:: $(INSTALL_INC)
|
||||
|
||||
@@ -57,7 +57,7 @@ endif
|
||||
clean::
|
||||
@echo "Cleaning"
|
||||
@$(RM) *.i *.o *.a $(TARGETS) $(PROD) $(LIBNAME) $(INC) \
|
||||
$(DBDINSTALL) $(MENUS) $(RECTYPES) $(BPTS) $(DBDEXPAND)
|
||||
$(DBDINSTALL) $(MENUS) $(RECTYPES) $(BPTS) $(DBDNAME)
|
||||
|
||||
|
||||
# The order of the following dependencies is
|
||||
@@ -75,32 +75,40 @@ clean::
|
||||
$(RM) $@
|
||||
$(COMPILE.c) $<
|
||||
|
||||
%.o: ../%.c
|
||||
$(RM) $@
|
||||
$(COMPILE.c) $<
|
||||
|
||||
%.o: %.cc
|
||||
$(RM) $@
|
||||
$(COMPILE.cc) $<
|
||||
|
||||
%.c: %.y
|
||||
%.o: ../%.cc
|
||||
$(RM) $@
|
||||
$(COMPILE.cc) $<
|
||||
|
||||
%.c: ../%.y
|
||||
$(RM) y.tab.c y.tab.h
|
||||
$(YACC) $(YACCOPT) $<
|
||||
@if [ -f y.tab.c ]; \
|
||||
then \
|
||||
echo "/bin/mv y.tab.c $*.c"; \
|
||||
/bin/mv y.tab.c $*.c; \
|
||||
echo "$(MV) y.tab.c $*.c"; \
|
||||
$(MV) y.tab.c $*.c; \
|
||||
fi
|
||||
@if [ -f y.tab.h ]; \
|
||||
then \
|
||||
echo "/bin/mv y.tab.h $*.h"; \
|
||||
/bin/mv y.tab.h $*.h; \
|
||||
echo "$(MV) y.tab.h $*.h"; \
|
||||
$(MV) y.tab.h $*.h; \
|
||||
fi
|
||||
|
||||
%.c: %.l
|
||||
%.c: ../%.l
|
||||
$(RM) lex.yy.c
|
||||
$(LEX) $(LEXOPT) $<
|
||||
$(RM) $@
|
||||
/bin/mv lex.yy.c $@
|
||||
$(MV) lex.yy.c $@
|
||||
|
||||
#state notation language rules
|
||||
%.c: %.st
|
||||
%.c: ../%.st
|
||||
@echo "preprocessing $*.st"
|
||||
@$(RM) $*.i
|
||||
$(CPP) $(CPPFLAGS) $< $*.i
|
||||
@@ -117,6 +125,9 @@ clean::
|
||||
%.db: %.edf
|
||||
$(E2DB) $(E2SR_SYSFLAGS) $(E2SR_FLAGS) $<
|
||||
|
||||
%.db: ../%.edf
|
||||
$(E2DB) $(E2SR_SYSFLAGS) $(E2SR_FLAGS) $<
|
||||
|
||||
%.edf: ../%.sch $(DEPSCHS)
|
||||
@if [ ! -f cad.rc -a -r ../cad.rc ] ; then ln -s ../cad.rc ; fi
|
||||
$(SCH2EDIF) $(SCH2EDIF_SYSFLAGS) $(SCH2EDIF_FLAGS) $<
|
||||
@@ -127,7 +138,7 @@ clean::
|
||||
$(RM) $(<F).nr
|
||||
ln -s $<
|
||||
$(MANGEN) -s $(<F)
|
||||
mv $(<F).nr $(<F).1
|
||||
$(MV) $(<F).nr $(<F).1
|
||||
|
||||
|
||||
$(INSTALL_DBD)/%: %
|
||||
@@ -135,32 +146,43 @@ $(INSTALL_DBD)/%: %
|
||||
@test -d $(INSTALL_DBD) || mkdir $(INSTALL_DBD)
|
||||
@$(INSTALL) -m 644 $< $(INSTALL_DBD)
|
||||
|
||||
$(INSTALL_DBD)/%: ../%
|
||||
@echo "Installing $@"
|
||||
@test -d $(INSTALL_DBD) || mkdir $(INSTALL_DBD)
|
||||
@$(INSTALL) -m 644 $< $(INSTALL_DBD)
|
||||
|
||||
%Record.h: %Record.dbd
|
||||
$(RM) $@
|
||||
$(EPICS_BASE)/bin/$(HOST_ARCH)/dbToRecordtypeH \
|
||||
$(USER_DBDFLAGS) $<
|
||||
|
||||
%Record.h: ../%Record.dbd
|
||||
$(RM) $@
|
||||
$(EPICS_BASE)/bin/$(HOST_ARCH)/dbToRecordtypeH \
|
||||
$(USER_DBDFLAGS) $<
|
||||
|
||||
menu%.h: menu%.dbd
|
||||
$(RM) $@
|
||||
$(EPICS_BASE)/bin/$(HOST_ARCH)/dbToMenuH $<
|
||||
|
||||
menu%.h: ../menu%.dbd
|
||||
$(RM) $@
|
||||
$(EPICS_BASE)/bin/$(HOST_ARCH)/dbToMenuH $<
|
||||
|
||||
bpt%.dbd: bpt%.data
|
||||
$(RM) $@
|
||||
$(EPICS_BASE)/bin/$(HOST_ARCH)/makeBpt $<
|
||||
|
||||
$(DBDNAME): $(DBDEXPAND)
|
||||
bpt%.dbd: ../bpt%.data
|
||||
$(RM) $@
|
||||
$(EPICS_BASE)/bin/$(HOST_ARCH)/makeBpt $<
|
||||
|
||||
$(DBDNAME): ../$(DBDEXPAND)
|
||||
@echo expanding dbd
|
||||
@$(RM) $@
|
||||
$(EPICS_BASE)/bin/$(HOST_ARCH)/dbExpand\
|
||||
$(USER_DBDFLAGS) $< > $@
|
||||
|
||||
%.1:%
|
||||
$(RM) $(<F)
|
||||
$(RM) $(<F).nr
|
||||
ln -s $<
|
||||
$(MANGEN) -s $(<F)
|
||||
mv $(<F).nr $(<F).1
|
||||
|
||||
$(LIBNAME): $(LIBOBJS)
|
||||
@echo Building library $@
|
||||
@$(RM) $@
|
||||
@@ -172,6 +194,12 @@ $(INSTALL_BIN)/%: %
|
||||
@test -d $(INSTALL_BIN) || mkdir $(INSTALL_BIN)
|
||||
@$(INSTALL) -m 555 $< $(INSTALL_BIN)
|
||||
|
||||
$(INSTALL_BIN)/%: ../%
|
||||
@echo "Installing $@"
|
||||
@test -d $(INSTALL_LOCATION_BIN) || mkdir $(INSTALL_LOCATION_BIN)
|
||||
@test -d $(INSTALL_BIN) || mkdir $(INSTALL_BIN)
|
||||
@$(INSTALL) -m 555 $< $(INSTALL_BIN)
|
||||
|
||||
$(INSTALL_BIN)/%: $(EPICS_BASE_BIN)/%
|
||||
@echo "Installing $@"
|
||||
@test -d $(INSTALL_LOCATION_BIN) || mkdir $(INSTALL_LOCATION_BIN)
|
||||
@@ -192,19 +220,43 @@ $(INSTALL_MAN)/man1/%: %
|
||||
@test -d $(@D) || mkdir $(@D)
|
||||
@$(INSTALL) -m 644 $< $(@D)
|
||||
|
||||
$(INSTALL_MAN)/man9/% \
|
||||
$(INSTALL_MAN)/man8/% \
|
||||
$(INSTALL_MAN)/man7/% \
|
||||
$(INSTALL_MAN)/man6/% \
|
||||
$(INSTALL_MAN)/man5/% \
|
||||
$(INSTALL_MAN)/man4/% \
|
||||
$(INSTALL_MAN)/man3/% \
|
||||
$(INSTALL_MAN)/man2/% \
|
||||
$(INSTALL_MAN)/man1/%: ../%
|
||||
@echo "Installing $@"
|
||||
@test -d $(INSTALL_MAN) || mkdir $(INSTALL_MAN)
|
||||
@test -d $(@D) || mkdir $(@D)
|
||||
@$(INSTALL) -m 644 $< $(@D)
|
||||
|
||||
$(INSTALL_INCLUDE)/%: %
|
||||
@echo "Installing $@"
|
||||
@test -d $(INSTALL_INCLUDE) || mkdir $(INSTALL_INCLUDE)
|
||||
@$(INSTALL) -m 644 $< $(INSTALL_INCLUDE)
|
||||
|
||||
$(INSTALL_INCLUDE)/%: ../%
|
||||
@echo "Installing $@"
|
||||
@test -d $(INSTALL_INCLUDE) || mkdir $(INSTALL_INCLUDE)
|
||||
@$(INSTALL) -m 644 $< $(INSTALL_INCLUDE)
|
||||
|
||||
$(INSTALL_DOC)/%: %
|
||||
@echo "Installing $@"
|
||||
@test -d $(INSTALL_DOC) || mkdir $(INSTALL_DOC)
|
||||
@$(INSTALL) -m 644 $< $(INSTALL_DOC)
|
||||
|
||||
$(INSTALL_DOC)/%: ../%
|
||||
@echo "Installing $@"
|
||||
@test -d $(INSTALL_DOC) || mkdir $(INSTALL_DOC)
|
||||
@$(INSTALL) -m 644 $< $(INSTALL_DOC)
|
||||
|
||||
.PRECIOUS: %.o %.c
|
||||
|
||||
.PHONY: all inc depends build install pre-build clean
|
||||
.PHONY: all inc depends build install pre-build clean rebuild
|
||||
|
||||
-include .DEPENDS
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ ACTIONS += inc
|
||||
ACTIONS += build
|
||||
ACTIONS += install
|
||||
ACTIONS += depends
|
||||
ACTIONS += rebuild
|
||||
|
||||
actionPart = $(word 1, $(subst $(DIVIDER), ,$@))
|
||||
archPart = $(word 2, $(subst $(DIVIDER), ,$@))
|
||||
@@ -18,7 +19,7 @@ archPart = $(word 2, $(subst $(DIVIDER), ,$@))
|
||||
#
|
||||
# hostActionArchTargets
|
||||
#
|
||||
hostArchs = $(HOST_ARCH) $(filter-out $(HOST_ARCH),$(CROSS_COMPILER_HOST_ARCHS))
|
||||
hostArchs = $(HOST_ARCH)
|
||||
hostActionArchTargets = $(foreach x, $(ACTIONS),\
|
||||
$(foreach arch,$(hostArchs), $(x)$(DIVIDER)$(arch)))
|
||||
ifeq (Makefile.$(BUILD_TYPE), $(wildcard Makefile.$(BUILD_TYPE)))
|
||||
@@ -35,7 +36,7 @@ endif
|
||||
#
|
||||
# crossActionArchTargets
|
||||
#
|
||||
crossArchs = $(CROSS_COMPILER_TARGET_ARCHS)
|
||||
crossArchs = $(filter-out $(hostArchs),$(BUILD_ARCHS))
|
||||
crossActionArchTargets = $(foreach x, $(ACTIONS), \
|
||||
$(foreach arch, $(CROSS_COMPILER_TARGET_ARCHS), $(x)$(DIVIDER)$(arch)))
|
||||
ifeq (Makefile.Vx, $(wildcard Makefile.Vx))
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#
|
||||
|
||||
|
||||
ARCHS= $(BUILD_ARCHS) host cross
|
||||
ACTIONS = clean inc install depends
|
||||
ARCHS += $(BUILD_ARCHS) host cross
|
||||
ACTIONS += clean inc install depends
|
||||
|
||||
dirPart = $(word 1, $(subst $(DIVIDER), ,$@))
|
||||
actionArchPart = $(subst $(dirPart)$(DIVIDER), ,$@)
|
||||
@@ -26,7 +26,7 @@ actionArchTargets = $(foreach action, $(ACTIONS),\
|
||||
|
||||
all:: inc install
|
||||
|
||||
rebuild:: clean uninstall all
|
||||
rebuild:: clean all
|
||||
|
||||
$(DIRS) $(dirActionTargets) $(dirArchTargets)$(dirActionArchTargets) ::
|
||||
$(MAKE) -C $(dirPart) $(actionArchPart)
|
||||
|
||||
@@ -168,9 +168,8 @@ LOCAL void asCaTask(void)
|
||||
pasg->inpBad |= (1<<pasginp->inpIndex);
|
||||
pcapvt = pasginp->capvt = asCalloc(1,sizeof(CAPVT));
|
||||
/*Note calls connectCallback immediately called for local Pvs*/
|
||||
SEVCHK(ca_build_and_connect(pasginp->inp,TYPENOTCONN,0,
|
||||
&pcapvt->chid,0,connectCallback,pasginp),
|
||||
"ca_build_and_connect");
|
||||
SEVCHK(ca_search_and_connect(pasginp->inp,&pcapvt->chid,
|
||||
connectCallback,pasginp),"ca_build_and_connect");
|
||||
/*Note calls accessRightsCallback immediately called for local Pvs*/
|
||||
SEVCHK(ca_replace_access_rights_event(pcapvt->chid,accessRightsCallback),
|
||||
"ca_replace_access_rights_event");
|
||||
|
||||
@@ -9,7 +9,7 @@ PROD = makeBpt
|
||||
|
||||
include $(TOP)/config/RULES.Unix
|
||||
|
||||
$(PROD): $(OBJS) $(DEPLIBS)
|
||||
$(PROD): $(OBJS)
|
||||
$(RM) $@
|
||||
$(LINK.c) -o $@ ${OBJS} $(LDLIBS)
|
||||
|
||||
|
||||
@@ -99,6 +99,12 @@
|
||||
/************************************************************************/
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.85 1996/09/04 20:02:00 jhill
|
||||
* test for non-nill piiu under vxWorks
|
||||
*
|
||||
* Revision 1.84 1996/07/10 23:30:09 jhill
|
||||
* fixed GNU warnings
|
||||
*
|
||||
* Revision 1.83 1996/07/09 22:43:29 jhill
|
||||
* silence gcc warnings and default CLOCKS_PER_SEC if it isnt defined (for sunos4 and gcc)
|
||||
*
|
||||
@@ -635,7 +641,7 @@ LOCAL void create_udp_fd()
|
||||
|
||||
status = taskPriorityGet(VXTASKIDSELF, &pri);
|
||||
if(status<0)
|
||||
ca_signal(ECA_INTERNAL,NULL);
|
||||
genLocalExcep (ECA_INTERNAL,NULL);
|
||||
|
||||
strcpy(name,"RD ");
|
||||
strncat(
|
||||
@@ -660,7 +666,7 @@ LOCAL void create_udp_fd()
|
||||
0,
|
||||
0);
|
||||
if (status<0) {
|
||||
ca_signal(ECA_INTERNAL,NULL);
|
||||
genLocalExcep (ECA_INTERNAL,NULL);
|
||||
}
|
||||
|
||||
ca_static->recv_tid = status;
|
||||
@@ -833,8 +839,7 @@ void ca_process_exit()
|
||||
FALSE);
|
||||
}
|
||||
if (socket_close(piiu->sock_chan) < 0){
|
||||
ca_signal(
|
||||
ECA_INTERNAL,
|
||||
genLocalExcep ( ECA_INTERNAL,
|
||||
"Corrupt iiu list- at close");
|
||||
}
|
||||
piiu = (struct ioc_in_use *) piiu->node.next;
|
||||
@@ -1544,14 +1549,16 @@ void *usrarg
|
||||
|
||||
piiu = chix->piiu;
|
||||
|
||||
if(!CA_V41(CA_PROTOCOL_VERSION, piiu->minor_version_number)){
|
||||
return ECA_NOSUPPORT;
|
||||
if (piiu) {
|
||||
if(!CA_V41(CA_PROTOCOL_VERSION, piiu->minor_version_number)){
|
||||
return ECA_NOSUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef vxWorks
|
||||
if (!piiu) {
|
||||
CACLIENTPUTNOTIFY *ppn;
|
||||
int size;
|
||||
unsigned size;
|
||||
|
||||
size = dbr_size_n(type,count);
|
||||
LOCK;
|
||||
@@ -2959,11 +2966,41 @@ int epicsShareAPI ca_test_io()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* generateLocalExceptionWithFileAndLine ()
|
||||
*/
|
||||
void generateLocalExceptionWithFileAndLine (long stat, char *ctx,
|
||||
char *pFile, unsigned lineNo)
|
||||
{
|
||||
struct exception_handler_args args;
|
||||
|
||||
/*
|
||||
* NOOP if they disable exceptions
|
||||
*/
|
||||
if (!ca_static->ca_exception_func) {
|
||||
return;
|
||||
}
|
||||
|
||||
args.usr = ca_static->ca_exception_arg;
|
||||
args.chid = NULL;
|
||||
args.type = -1;
|
||||
args.count = 0u;
|
||||
args.addr = NULL;
|
||||
args.stat = stat;
|
||||
args.op = CA_OP_OTHER;
|
||||
args.ctx = ctx;
|
||||
args.pFile = pFile;
|
||||
args.lineNo = lineNo;
|
||||
|
||||
LOCKEVENTS;
|
||||
(*ca_static->ca_exception_func) (args);
|
||||
UNLOCKEVENTS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CA_SIGNAL()
|
||||
*
|
||||
*
|
||||
*/
|
||||
void epicsShareAPI ca_signal(long ca_status,char *message)
|
||||
{
|
||||
@@ -2980,7 +3017,7 @@ void epicsShareAPI ca_signal(long ca_status,char *message)
|
||||
* of this routine is calling this routine
|
||||
* (if they call this routine again).
|
||||
*/
|
||||
const char *ca_message(long ca_status)
|
||||
READONLY char * epicsShareAPI ca_message (long ca_status)
|
||||
{
|
||||
unsigned msgNo = CA_EXTRACT_MSG_NO(ca_status);
|
||||
|
||||
@@ -3323,27 +3360,26 @@ void issue_claim_channel(struct ioc_in_use *piiu, chid pchan)
|
||||
*/
|
||||
LOCAL void ca_default_exception_handler(struct exception_handler_args args)
|
||||
{
|
||||
char *pName;
|
||||
|
||||
if(args.chid){
|
||||
pName = ca_name(args.chid);
|
||||
}
|
||||
else{
|
||||
pName = "?";
|
||||
}
|
||||
char *pCtx;
|
||||
|
||||
/*
|
||||
* LOCK around use of sprintf buffer
|
||||
*/
|
||||
LOCK;
|
||||
sprintf(sprintf_buf,
|
||||
"%s - with request chan=%s op=%ld data type=%s count=%ld",
|
||||
args.ctx,
|
||||
pName,
|
||||
args.op,
|
||||
dbr_type_to_text(args.type),
|
||||
args.count);
|
||||
ca_signal(args.stat, sprintf_buf);
|
||||
if (args.chid && args.op != CA_OP_OTHER) {
|
||||
sprintf(sprintf_buf,
|
||||
"%s - with request chan=%s op=%ld data type=%s count=%ld",
|
||||
args.ctx,
|
||||
ca_name(args.chid),
|
||||
args.op,
|
||||
dbr_type_to_text(args.type),
|
||||
args.count);
|
||||
pCtx = sprintf_buf;
|
||||
}
|
||||
else {
|
||||
pCtx = args.ctx;
|
||||
}
|
||||
ca_signal_with_file_and_lineno(args.stat, pCtx, args.pFile, args.lineNo);
|
||||
UNLOCK;
|
||||
}
|
||||
|
||||
@@ -3418,6 +3454,16 @@ int epicsShareAPI ca_v42_ok(chid chan)
|
||||
return v42;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ca_version()
|
||||
* function that returns the CA version string
|
||||
*/
|
||||
READONLY char * epicsShareAPI ca_version()
|
||||
{
|
||||
return CA_VERSION_STRING;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
|
||||
@@ -7,6 +7,12 @@ static char *sccsId = "@(#) $Id$";
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.37 1996/09/16 16:31:01 jhill
|
||||
* fixed NT warnings
|
||||
*
|
||||
* Revision 1.36 1996/07/24 21:55:33 jhill
|
||||
* fixed gnu warnings
|
||||
*
|
||||
* Revision 1.35 1996/07/01 19:49:15 jhill
|
||||
* turned on analog value wrap-around test
|
||||
*
|
||||
@@ -141,6 +147,11 @@ int doacctst(char *pname)
|
||||
lib$init_timer();
|
||||
#endif /*VMS*/
|
||||
|
||||
printf("CA Client V%s\n", ca_version());
|
||||
|
||||
/*
|
||||
* CA pend event delay accuracy test
|
||||
*/
|
||||
{
|
||||
TS_STAMP end_time;
|
||||
TS_STAMP start_time;
|
||||
@@ -158,12 +169,28 @@ int doacctst(char *pname)
|
||||
accuracy = 100.0*(delay-request)/request;
|
||||
printf("CA pend event delay accuracy = %f %%\n",
|
||||
accuracy);
|
||||
assert (abs(accuracy) < 10.0);
|
||||
assert (fabs(accuracy) < 10.0);
|
||||
}
|
||||
|
||||
size = dbr_size_n(DBR_GR_FLOAT, NUM);
|
||||
ptr = (struct dbr_gr_float *) malloc(size);
|
||||
|
||||
/*
|
||||
* verify that we dont print a disconnect message when
|
||||
* we delete the last channel
|
||||
* (this fails if we see a disconnect message)
|
||||
*/
|
||||
status = ca_search( pname, &chix3);
|
||||
SEVCHK(status, NULL);
|
||||
status = ca_pend_io(1000.0);
|
||||
SEVCHK(status, NULL);
|
||||
status = ca_clear_channel(chix3);
|
||||
SEVCHK(status, NULL);
|
||||
|
||||
/*
|
||||
* verify lots of disconnects
|
||||
* verify channel connected state variables
|
||||
*/
|
||||
printf("Connect/disconnect test");
|
||||
fflush(stdout);
|
||||
for (i = 0; i < 10; i++) {
|
||||
@@ -290,32 +317,32 @@ int doacctst(char *pname)
|
||||
ca_read_access(chix1) &&
|
||||
ca_write_access(chix1)){
|
||||
|
||||
dbr_double_t incr;
|
||||
dbr_double_t epsil;
|
||||
dbr_double_t base;
|
||||
dbr_float_t incr;
|
||||
dbr_float_t epsil;
|
||||
dbr_float_t base;
|
||||
unsigned long iter;
|
||||
|
||||
printf ("float test ...");
|
||||
fflush(stdout);
|
||||
epsil = FLT_EPSILON*4;
|
||||
epsil = FLT_EPSILON*4.0F;
|
||||
base = FLT_MIN;
|
||||
for (i=FLT_MIN_EXP; i<FLT_MAX_EXP; i+=FLT_MAX_EXP/10) {
|
||||
incr = ldexp (0.5,i);
|
||||
iter = FLT_MAX/fabs(incr);
|
||||
incr = (dbr_float_t) ldexp (0.5F,i);
|
||||
iter = (unsigned long) (FLT_MAX/fabs(incr));
|
||||
iter = min (iter,10);
|
||||
floatTest(chix1, base, incr, epsil, iter);
|
||||
}
|
||||
base = FLT_MAX;
|
||||
for (i=FLT_MIN_EXP; i<FLT_MAX_EXP; i+=FLT_MAX_EXP/10) {
|
||||
incr = - ldexp (0.5,i);
|
||||
iter = FLT_MAX/fabs(incr);
|
||||
incr = (dbr_float_t) - ldexp (0.5F,i);
|
||||
iter = (unsigned long) (FLT_MAX/fabs(incr));
|
||||
iter = min (iter,10);
|
||||
floatTest(chix1, base, incr, epsil, iter);
|
||||
}
|
||||
base = - FLT_MAX;
|
||||
for (i=FLT_MIN_EXP; i<FLT_MAX_EXP; i+=FLT_MAX_EXP/10) {
|
||||
incr = ldexp (0.5,i);
|
||||
iter = FLT_MAX/fabs(incr);
|
||||
incr = (dbr_float_t) ldexp (0.5F,i);
|
||||
iter = (unsigned long) (FLT_MAX/fabs(incr));
|
||||
iter = min (iter,10);
|
||||
floatTest(chix1, base, incr, epsil, iter);
|
||||
}
|
||||
@@ -341,21 +368,21 @@ int doacctst(char *pname)
|
||||
base = DBL_MIN;
|
||||
for (i=DBL_MIN_EXP; i<DBL_MAX_EXP; i+=DBL_MAX_EXP/10) {
|
||||
incr = ldexp (0.5,i);
|
||||
iter = DBL_MAX/fabs(incr);
|
||||
iter = (unsigned long) (DBL_MAX/fabs(incr));
|
||||
iter = min (iter,10);
|
||||
doubleTest(chix1, base, incr, epsil, iter);
|
||||
}
|
||||
base = DBL_MAX;
|
||||
for (i=DBL_MIN_EXP; i<DBL_MAX_EXP; i+=DBL_MAX_EXP/10) {
|
||||
incr = - ldexp (0.5,i);
|
||||
iter = DBL_MAX/fabs(incr);
|
||||
iter = (unsigned long) (DBL_MAX/fabs(incr));
|
||||
iter = min (iter,10);
|
||||
doubleTest(chix1, base, incr, epsil, iter);
|
||||
}
|
||||
base = - DBL_MAX;
|
||||
for (i=DBL_MIN_EXP; i<DBL_MAX_EXP; i+=DBL_MAX_EXP/10) {
|
||||
incr = ldexp (0.5,i);
|
||||
iter = DBL_MAX/fabs(incr);
|
||||
iter = (unsigned long) (DBL_MAX/fabs(incr));
|
||||
iter = min (iter,10);
|
||||
doubleTest(chix1, base, incr, epsil, iter);
|
||||
}
|
||||
@@ -366,8 +393,8 @@ int doacctst(char *pname)
|
||||
* ca_pend_io() must block
|
||||
*/
|
||||
if(ca_read_access(chix4)){
|
||||
dbr_float_t req = 3.3;
|
||||
dbr_float_t resp = 0.0;
|
||||
dbr_float_t req = 3.3F;
|
||||
dbr_float_t resp = 0.0F;
|
||||
|
||||
printf ("get TMO test ...");
|
||||
fflush(stdout);
|
||||
@@ -378,10 +405,10 @@ int doacctst(char *pname)
|
||||
assert (resp == req);
|
||||
}
|
||||
else {
|
||||
assert (resp == 0.0);
|
||||
assert (resp == 0.0F);
|
||||
}
|
||||
|
||||
resp = 0.0;
|
||||
resp = 0.0F;
|
||||
SEVCHK (ca_put(DBR_FLOAT, chix4, &req),NULL);
|
||||
SEVCHK (ca_get(DBR_FLOAT, chix4, &resp),NULL);
|
||||
SEVCHK (ca_pend_io(2000.0),NULL);
|
||||
@@ -657,7 +684,7 @@ int doacctst(char *pname)
|
||||
accuracy = 100.0*(delay-request)/request;
|
||||
printf("CA pend event delay accuracy = %f %%\n",
|
||||
accuracy);
|
||||
assert (abs(accuracy) < 10.0);
|
||||
assert (fabs(accuracy) < 10.0);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.1 1996/06/20 18:02:22 jhill
|
||||
* installed into CVS
|
||||
*
|
||||
* Revision 1.1.1.1 1996/06/20 00:28:15 jhill
|
||||
* ca server installation
|
||||
*
|
||||
@@ -62,6 +65,9 @@
|
||||
*
|
||||
* .10 050594 joh New command added for CA V4.3 - wakeup the server
|
||||
* $Log$
|
||||
* Revision 1.1 1996/06/20 18:02:22 jhill
|
||||
* installed into CVS
|
||||
*
|
||||
* Revision 1.1.1.1 1996/06/20 00:28:15 jhill
|
||||
* ca server installation
|
||||
*
|
||||
@@ -70,9 +76,24 @@
|
||||
|
||||
#define __CAPROTO__
|
||||
|
||||
/* TCP/UDP port number (bumped each protocol change) */
|
||||
#define CA_PROTOCOL_VERSION 4u
|
||||
#define CA_MINOR_VERSION 7u
|
||||
/*
|
||||
* CA protocol number
|
||||
* TCP/UDP port number (bumped each major protocol change)
|
||||
*/
|
||||
#define CA_PROTOCOL_VERSION_STR 4
|
||||
#define CA_MINOR_VERSION_STR 7
|
||||
|
||||
/*
|
||||
* add unsigned to the above numbers for numerical
|
||||
* comparisons (two defines above are used to create
|
||||
* version number string - prefer not to have u there)
|
||||
*/
|
||||
#ifndef CONCAT
|
||||
#define CONCAT(A,B) A ## B
|
||||
#endif
|
||||
#define UNSIGNED(N) CONCAT(N,u)
|
||||
#define CA_PROTOCOL_VERSION UNSIGNED(CA_PROTOCOL_VERSION_STR)
|
||||
#define CA_MINOR_VERSION UNSIGNED(CA_MINOR_VERSION_STR)
|
||||
#define CA_UKN_MINOR_VERSION 0u /* unknown minor version */
|
||||
#if CA_PROTOCOL_VERSION == 4u
|
||||
#define CA_V41(MAJOR,MINOR) ((MINOR)>=1u)
|
||||
@@ -228,5 +249,14 @@ struct monops { /* monitor req opi to ioc */
|
||||
*/
|
||||
#define unreasonablePVNameSize 500u
|
||||
|
||||
#ifndef STRINGOF
|
||||
#define STRINGOF(A) #A
|
||||
#endif
|
||||
#ifndef EXPANDTOSTRING
|
||||
#define EXPANDTOSTRING(A) STRINGOF(A)
|
||||
#endif
|
||||
#define CA_VERSION_STRING \
|
||||
(EXPANDTOSTRING(CA_PROTOCOL_VERSION_STR)"."EXPANDTOSTRING(CA_MINOR_VERSION_STR))
|
||||
|
||||
#endif /* __CAPROTO__ */
|
||||
|
||||
|
||||
@@ -258,6 +258,8 @@ struct exception_handler_args{
|
||||
long stat; /* Channel access std status code */
|
||||
long op; /* External codes for channel access operations */
|
||||
char *ctx; /* A character string containing context info */
|
||||
char *pFile; /* source file name (may be NULL) */
|
||||
unsigned lineNo; /* source file line number */
|
||||
};
|
||||
|
||||
|
||||
@@ -984,6 +986,11 @@ int epicsShareAPI ca_v42_ok(chid chan);
|
||||
int epicsShareAPI ca_v42_ok();
|
||||
#endif /*CAC_FUNC_PROTO*/
|
||||
|
||||
/*
|
||||
* function that returns the CA version string
|
||||
*/
|
||||
READONLY char * epicsShareAPI ca_version();
|
||||
|
||||
/*
|
||||
* ca_replace_printf_handler ()
|
||||
*
|
||||
|
||||
@@ -214,7 +214,7 @@ READONLY char *ca_message_text[]
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
READONLY char *ca_message(long ca_status);
|
||||
READONLY char * epicsShareAPI ca_message(long ca_status);
|
||||
#else /* __STDC__ */
|
||||
READONLY char *ca_message();
|
||||
#endif
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
/* (dont send all chans in a block) */
|
||||
/* */
|
||||
/* $Log$
|
||||
* Revision 1.35 1996/06/19 17:59:04 jhill
|
||||
* many 3.13 beta changes
|
||||
*
|
||||
* Revision 1.34 1995/08/22 00:19:21 jhill
|
||||
* use current time var to init time stamp in a beacon hash entry
|
||||
* */
|
||||
@@ -262,7 +265,7 @@ LOCAL void retrySearchRequest (int silent)
|
||||
if (status == ECA_NORMAL) {
|
||||
retry_cnt++;
|
||||
if (!(silent || chix->pConnFunc)) {
|
||||
ca_signal (
|
||||
genLocalExcep (
|
||||
ECA_CHIDNOTFND,
|
||||
(char *)(chix+1));
|
||||
retry_cnt_no_handler++;
|
||||
@@ -314,7 +317,7 @@ LOCAL void retrySearchRequest (int silent)
|
||||
sprintf_buf,
|
||||
"%d channels outstanding",
|
||||
retry_cnt);
|
||||
ca_signal (ECA_CHIDRETRY, sprintf_buf);
|
||||
genLocalExcep (ECA_CHIDRETRY, sprintf_buf);
|
||||
}
|
||||
}
|
||||
UNLOCK;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -88,7 +88,7 @@ int local_addr(int s, struct sockaddr_in *plcladdr)
|
||||
#endif
|
||||
|
||||
for ( pifreq = ifconf.ifc_req;
|
||||
ifconf.ifc_len >= sizeof(*pifreq);
|
||||
((size_t)ifconf.ifc_len) >= sizeof(*pifreq);
|
||||
pifreq++, ifconf.ifc_len -= sizeof(*pifreq)) {
|
||||
|
||||
status = socket_ioctl(s, SIOCGIFFLAGS, pifreq);
|
||||
|
||||
@@ -47,6 +47,9 @@
|
||||
/* address in use so that test works on UNIX */
|
||||
/* kernels that support multicast */
|
||||
/* $Log$
|
||||
* Revision 1.64 1996/08/13 23:15:36 jhill
|
||||
* fixed warning
|
||||
*
|
||||
* Revision 1.63 1996/07/09 22:41:28 jhill
|
||||
* silence gcc warning
|
||||
*
|
||||
@@ -425,7 +428,7 @@ int net_proto
|
||||
sizeof(saddr));
|
||||
if(status<0){
|
||||
ca_printf("CAC: bind (err=%s)\n",strerror(MYERRNO));
|
||||
ca_signal(ECA_INTERNAL,"bind failed");
|
||||
genLocalExcep (ECA_INTERNAL,"bind failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -451,7 +454,7 @@ int net_proto
|
||||
|
||||
default:
|
||||
free(piiu);
|
||||
ca_signal(ECA_INTERNAL,"alloc_ioc: ukn protocol\n");
|
||||
genLocalExcep (ECA_INTERNAL,"alloc_ioc: ukn protocol");
|
||||
/*
|
||||
* turn off gcc warnings
|
||||
*/
|
||||
@@ -541,7 +544,7 @@ void caSetupBCastAddrList (ELLLIST *pList, SOCKET sock, unsigned port)
|
||||
port);
|
||||
|
||||
if (ellCount(pList)==0) {
|
||||
ca_signal (ECA_NOSEARCHADDR, NULL);
|
||||
genLocalExcep (ECA_NOSEARCHADDR, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1206,6 +1209,7 @@ LOCAL void close_ioc (IIU *piiu)
|
||||
caAddrNode *pNode;
|
||||
chid chix;
|
||||
int status;
|
||||
unsigned chanDisconnectCount;
|
||||
|
||||
/*
|
||||
* dont close twice
|
||||
@@ -1224,10 +1228,13 @@ LOCAL void close_ioc (IIU *piiu)
|
||||
|
||||
if (piiu == piiuCast) {
|
||||
piiuCast = NULL;
|
||||
chanDisconnectCount = 0u;
|
||||
}
|
||||
else {
|
||||
chid pNext;
|
||||
|
||||
chanDisconnectCount = ellCount(&piiu->chidlist);
|
||||
|
||||
/*
|
||||
* remove IOC from the hash table
|
||||
*/
|
||||
@@ -1277,7 +1284,9 @@ LOCAL void close_ioc (IIU *piiu)
|
||||
|
||||
ellFree (&piiu->destAddr);
|
||||
|
||||
ca_signal (ECA_DISCONN,piiu->host_name_str);
|
||||
if (chanDisconnectCount) {
|
||||
genLocalExcep (ECA_DISCONN, piiu->host_name_str);
|
||||
}
|
||||
|
||||
free (piiu);
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
/************************************************************************/
|
||||
|
||||
/* $Log$
|
||||
* Revision 1.56 1996/08/13 23:16:19 jhill
|
||||
* removed os specific code
|
||||
*
|
||||
* Revision 1.55 1996/08/05 19:21:26 jhill
|
||||
* removed unused proto
|
||||
*
|
||||
@@ -633,6 +636,10 @@ void clearChannelResources(unsigned id);
|
||||
void caSetDefaultPrintfHandler (void);
|
||||
void cacDisconnectChannel(chid chix, enum channel_state state);
|
||||
int caSendMsgPending(void);
|
||||
void generateLocalExceptionWithFileAndLine(long stat, char *ctx,
|
||||
char *pFile, unsigned line);
|
||||
#define genLocalExcep(STAT, PCTX) \
|
||||
generateLocalExceptionWithFileAndLine (STAT, PCTX, __FILE__, __LINE__)
|
||||
|
||||
/*
|
||||
* !!KLUDGE!!
|
||||
|
||||
@@ -63,6 +63,9 @@
|
||||
* datagram socket (and watching for ECONNREFUSED)
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.36 1996/07/12 00:40:48 jhill
|
||||
* fixed client disconnect problem under solaris
|
||||
*
|
||||
* Revision 1.32.6.1 1996/07/12 00:39:59 jhill
|
||||
* fixed client disconnect problem under solaris
|
||||
*
|
||||
@@ -115,13 +118,13 @@ LOCAL void fanOut(struct sockaddr_in *pFrom, const char *pMsg, unsigned msgSize)
|
||||
*/
|
||||
void ca_repeater()
|
||||
{
|
||||
int status;
|
||||
int size;
|
||||
SOCKET sock;
|
||||
struct sockaddr_in from;
|
||||
struct sockaddr_in local;
|
||||
int from_size = sizeof from;
|
||||
unsigned short port;
|
||||
int status;
|
||||
int size;
|
||||
SOCKET sock;
|
||||
struct sockaddr_in from;
|
||||
struct sockaddr_in local;
|
||||
int from_size = sizeof from;
|
||||
unsigned short port;
|
||||
|
||||
port = caFetchPortConfig(
|
||||
&EPICS_CA_REPEATER_PORT,
|
||||
@@ -186,7 +189,7 @@ void ca_repeater()
|
||||
* both zero length message and a registration message
|
||||
* will register a new client
|
||||
*/
|
||||
if(size >= sizeof(*pMsg)){
|
||||
if( ((size_t)size) >= sizeof(*pMsg)){
|
||||
if(ntohs(pMsg->m_cmmd) == REPEATER_REGISTER){
|
||||
register_new_client(&local, &from);
|
||||
|
||||
|
||||
@@ -579,6 +579,8 @@ const struct in_addr *pnet_addr
|
||||
*/
|
||||
monix = NULL;
|
||||
args.addr = NULL;
|
||||
args.pFile = NULL;
|
||||
args.lineNo = 0u;
|
||||
LOCK;
|
||||
switch (ntohs(req->m_cmmd)) {
|
||||
case CA_PROTO_READ_NOTIFY:
|
||||
@@ -813,7 +815,7 @@ const struct in_addr *pnet_addr
|
||||
(char *)(chan + 1),
|
||||
chpiiu->host_name_str,
|
||||
rej);
|
||||
ca_signal(ECA_DBLCHNL, sprintf_buf);
|
||||
genLocalExcep (ECA_DBLCHNL, sprintf_buf);
|
||||
}
|
||||
UNLOCK;
|
||||
return;
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
* Revision 1.25 1996/08/13 23:16:23 jhill
|
||||
* removed os specific code
|
||||
*
|
||||
* Revision 1.23 1996/08/05 19:18:56 jhill
|
||||
* better msg for lack of fp
|
||||
*
|
||||
@@ -739,7 +742,7 @@ LOCAL void ca_check_for_fp()
|
||||
|
||||
assert(taskOptionsGet(taskIdSelf(), &options) == OK);
|
||||
if (!(options & VX_FP_TASK)) {
|
||||
ca_signal(ECA_NEEDSFP, taskName(taskIdSelf()));
|
||||
genLocalExcep (ECA_NEEDSFP, taskName(taskIdSelf()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,11 +32,17 @@
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
* Revision 1.21 1996/08/05 19:20:29 jhill
|
||||
* removed incorrect ver number
|
||||
*
|
||||
* Revision 1.20 1995/12/19 19:36:20 jhill
|
||||
* function prototype changes
|
||||
*
|
||||
* Revision 1.19 1995/11/29 19:15:42 jhill
|
||||
* added $Log$
|
||||
* added Revision 1.21 1996/08/05 19:20:29 jhill
|
||||
* added removed incorrect ver number
|
||||
* added
|
||||
* Revision 1.20 1995/12/19 19:36:20 jhill
|
||||
* function prototype changes
|
||||
* to the header
|
||||
@@ -49,6 +55,7 @@
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#include <mmsystem.h>
|
||||
#include <epicsVersion.h>
|
||||
|
||||
#include "iocinf.h"
|
||||
|
||||
@@ -469,7 +476,7 @@ BOOL epicsShareAPI DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
|
||||
|
||||
#if _DEBUG /* for gui applications, setup console for error messages */
|
||||
if (AllocConsole()) {
|
||||
SetConsoleTitle("Channel Access Status");
|
||||
SetConsoleTitle(EPICS_VERSION_STRING);
|
||||
freopen( "CONOUT$", "a", stderr );
|
||||
}
|
||||
fprintf(stderr, "Process attached to ca.dll\n");
|
||||
|
||||
8
src/cas/build/multiThread/Makefile
Normal file
8
src/cas/build/multiThread/Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
TOP=../../../..
|
||||
|
||||
include $(TOP)/config/CONFIG_BASE
|
||||
|
||||
include $(TOP)/config/RULES_ARCHS
|
||||
|
||||
|
||||
93
src/cas/build/multiThread/Makefile.Vx
Normal file
93
src/cas/build/multiThread/Makefile.Vx
Normal file
@@ -0,0 +1,93 @@
|
||||
|
||||
#HERE := $(shell pwd)
|
||||
HERE = .
|
||||
CAS = $(HERE)/../../..
|
||||
TOP = $(CAS)/../..
|
||||
SRC = $(CAS)/generic
|
||||
CA = $(CAS)/../ca
|
||||
IOSRC = $(CAS)/io/bsdSocket
|
||||
OSSRC = $(CAS)/os/vxWorks
|
||||
VPATH = $(SRC) $(IOSRC) $(OSSRC)
|
||||
|
||||
include $(TOP)/config/CONFIG_BASE
|
||||
|
||||
CXXCMPLR = STRICT
|
||||
|
||||
USR_INCLUDES = -I$(SRC) -I$(OSSRC) -I$(IOSRC) -I$(CA)\
|
||||
-I$(TOP)/src/include/os/vxWorks
|
||||
|
||||
DEPLIBS_BASE = $(EPICS_BASE_LIB)
|
||||
|
||||
SRCS.cc += $(SRC)/caServer.cc
|
||||
SRCS.cc += $(SRC)/caServerI.cc
|
||||
SRCS.cc += $(SRC)/casCoreClient.cc
|
||||
SRCS.cc += $(SRC)/casClient.cc
|
||||
SRCS.cc += $(SRC)/casDGClient.cc
|
||||
SRCS.cc += $(SRC)/casStrmClient.cc
|
||||
SRCS.cc += $(SRC)/casPV.cc
|
||||
SRCS.cc += $(SRC)/casPVI.cc
|
||||
SRCS.cc += $(SRC)/casChannel.cc
|
||||
SRCS.cc += $(SRC)/casChannelI.cc
|
||||
SRCS.cc += $(SRC)/casClientMon.cc
|
||||
SRCS.cc += $(SRC)/casChanDelEv.cc
|
||||
SRCS.cc += $(SRC)/casMsgIO.cc
|
||||
SRCS.cc += $(SRC)/casAsyncIO.cc
|
||||
SRCS.cc += $(SRC)/casAsyncIOI.cc
|
||||
SRCS.cc += $(SRC)/casEventSys.cc
|
||||
SRCS.cc += $(SRC)/casMonitor.cc
|
||||
SRCS.cc += $(SRC)/casMonEvent.cc
|
||||
SRCS.cc += $(SRC)/outBuf.cc
|
||||
SRCS.cc += $(SRC)/inBuf.cc
|
||||
SRCS.cc += $(SRC)/casEventMask.cc
|
||||
|
||||
SRCS.cc += $(OSSRC)/caServerOS.cc
|
||||
SRCS.cc += $(OSSRC)/casDGOS.cc
|
||||
SRCS.cc += $(OSSRC)/casStreamOS.cc
|
||||
|
||||
SRCS.cc += $(IOSRC)/caServerIO.cc
|
||||
SRCS.cc += $(IOSRC)/casDGIO.cc
|
||||
SRCS.cc += $(IOSRC)/casStreamIO.cc
|
||||
SRCS.c += $(IOSRC)/sigPipeIgnore.c
|
||||
|
||||
LIBOBJS += caServer.o
|
||||
LIBOBJS += caServerI.o
|
||||
LIBOBJS += casCoreClient.o
|
||||
LIBOBJS += casClient.o
|
||||
LIBOBJS += casDGClient.o
|
||||
LIBOBJS += casStrmClient.o
|
||||
LIBOBJS += casPV.o
|
||||
LIBOBJS += casPVI.o
|
||||
LIBOBJS += casChannel.o
|
||||
LIBOBJS += casChannelI.o
|
||||
LIBOBJS += casClientMon.o
|
||||
LIBOBJS += casChanDelEv.o
|
||||
LIBOBJS += casMsgIO.o
|
||||
LIBOBJS += casAsyncIO.o
|
||||
LIBOBJS += casAsyncIOI.o
|
||||
LIBOBJS += casEventSys.o
|
||||
LIBOBJS += casMonitor.o
|
||||
LIBOBJS += casMonEvent.o
|
||||
LIBOBJS += outBuf.o
|
||||
LIBOBJS += inBuf.o
|
||||
LIBOBJS += casEventMask.o
|
||||
|
||||
LIBOBJS += caServerOS.o
|
||||
LIBOBJS += casDGOS.o
|
||||
LIBOBJS += casStreamOS.o
|
||||
|
||||
LIBOBJS += caServerIO.o
|
||||
LIBOBJS += casDGIO.o
|
||||
LIBOBJS += casStreamIO.o
|
||||
LIBOBJS += sigPipeIgnore.o
|
||||
|
||||
LIBNAME = libcas.o
|
||||
|
||||
include $(TOP)/config/RULES.Vx
|
||||
|
||||
obj: $(LIBOBJS)
|
||||
|
||||
test.o:
|
||||
|
||||
clean::
|
||||
@$(RM) -rf Templates.DB
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
|
||||
CAS = ../../..
|
||||
#HERE := $(shell pwd)
|
||||
HERE = .
|
||||
CAS := $(HERE)/../../..
|
||||
TOP = $(CAS)/../..
|
||||
SRC = $(CAS)/generic
|
||||
CA = $(CAS)/../ca
|
||||
@@ -11,7 +13,8 @@ include $(TOP)/config/CONFIG_BASE
|
||||
|
||||
CXXCMPLR = STRICT
|
||||
|
||||
USR_INCLUDES = -I$(SRC) -I$(OSSRC) -I$(IOSRC) -I$(CA)
|
||||
USR_INCLUDES = -I$(SRC) -I$(OSSRC) -I$(IOSRC) -I$(CA) \
|
||||
-I$(TOP)/src/include/os/$(T_A)
|
||||
|
||||
DEPLIBS_BASE = $(EPICS_BASE_LIB)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
CAS = ../../
|
||||
CAS = ../..
|
||||
TOP = $(CAS)/../..
|
||||
|
||||
include $(TOP)/config/CONFIG_BASE
|
||||
@@ -16,12 +16,14 @@ DEPLIBSWOCAS = $(DEPLIBS_BASE)/libca.a $(DEPLIBS_BASE)/libCom.a \
|
||||
$(DEPLIBS_BASE)/libgdd.a
|
||||
DEPLIBS = $(DEPLIBS_BASE)/libcas.a $(DEPLIBSWOCAS)
|
||||
|
||||
SRCS.cc += ../main.cc
|
||||
SRCS.cc += ../exServer.cc
|
||||
SRCS.cc += ../exPV.cc
|
||||
SRCS.cc += ../exSyncPV.cc
|
||||
SRCS.cc += ../exAsyncPV.cc
|
||||
SRCS.cc += ../exChannel.cc
|
||||
|
||||
OBJS += main.o
|
||||
OBJS += exServer.o
|
||||
OBJS += exPV.o
|
||||
OBJS += exSyncPV.o
|
||||
@@ -69,16 +71,21 @@ excas: $(OBJS) $(DEPLIBS)
|
||||
$(LINK.cc) -o $@ $(OBJS) $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
#
|
||||
# fast link (without library build)
|
||||
# fast link (without waiting for library build)
|
||||
#
|
||||
#PURIFY = /remote/lear_local/pure/purify-3.0a-sunos4/purify
|
||||
nolib: $(OBJS) $(GLOMBOBJ) $(DEPLIBSWOCAS)
|
||||
$(PURIFY) $(LINK.cc) -o $@ $(OBJS) $(GLOMBOBJ) $(DEPLIBSWOCAS)
|
||||
$(LINK.cc) -o $@ $(OBJS) $(GLOMBOBJ) $(DEPLIBSWOCAS)
|
||||
|
||||
#
|
||||
# build with purify
|
||||
#
|
||||
purify: $(OBJS) $(GLOMBOBJ) $(DEPLIBSWOCAS)
|
||||
$(PURIFY) -best-effort $(LINK.cc) -o $@ $(OBJS) $(GLOMBOBJ) $(DEPLIBSWOCAS)
|
||||
|
||||
clean::
|
||||
@$(RM) excas
|
||||
@$(RM) nolib
|
||||
@$(RM) purify
|
||||
@$(RM) -rf Templates.DB
|
||||
|
||||
|
||||
@$(RM) core
|
||||
|
||||
|
||||
@@ -350,6 +350,14 @@ caStatus exPV::getUnits(gdd &units)
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
//
|
||||
// exPV::getEnums()
|
||||
//
|
||||
caStatus exPV::getEnums(gdd &)
|
||||
{
|
||||
return S_cas_noConvert;
|
||||
}
|
||||
|
||||
//
|
||||
// exPV::getValue()
|
||||
//
|
||||
|
||||
@@ -7,9 +7,7 @@
|
||||
// Example EPICS CA server
|
||||
//
|
||||
|
||||
|
||||
#include <exServer.h>
|
||||
#include <fdManager.h>
|
||||
|
||||
const pvInfo exServer::pvList[] = {
|
||||
pvInfo (1.0e-1, "jane", 10.0f, 0.0f, excasIoSync),
|
||||
@@ -18,68 +16,11 @@ const pvInfo exServer::pvList[] = {
|
||||
pvInfo (2.0, "freddy", 10.0f, -10.0f, excasIoAsync)
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// static data for exServer
|
||||
//
|
||||
gddAppFuncTable<exPV> exServer::ft;
|
||||
|
||||
//
|
||||
// main()
|
||||
//
|
||||
int main (int argc, const char **argv)
|
||||
{
|
||||
osiTime begin(osiTime::getCurrent());
|
||||
exServer *pCAS;
|
||||
unsigned debugLevel = 0u;
|
||||
float executionTime;
|
||||
aitBool forever = aitTrue;
|
||||
int i;
|
||||
|
||||
pCAS = new exServer(32u,5u,500u);
|
||||
if (!pCAS) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
for (i=1; i<argc; i++) {
|
||||
if (sscanf(argv[i], "-d %u", &debugLevel)==1) {
|
||||
continue;
|
||||
}
|
||||
if (sscanf(argv[i],"-t %f", &executionTime)==1) {
|
||||
forever = aitFalse;
|
||||
continue;
|
||||
}
|
||||
printf ("usage: %s -d<debug level> -t<execution time>\n",
|
||||
argv[0]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
pCAS->setDebugLevel(debugLevel);
|
||||
|
||||
if (forever) {
|
||||
osiTime delay(1000u,0u);
|
||||
//
|
||||
// loop here forever
|
||||
//
|
||||
while (aitTrue) {
|
||||
fileDescriptorManager.process(delay);
|
||||
}
|
||||
}
|
||||
else {
|
||||
osiTime total(executionTime);
|
||||
osiTime delay(osiTime::getCurrent() - begin);
|
||||
//
|
||||
// loop here untime the specified execution time
|
||||
// expires
|
||||
//
|
||||
while (delay < total) {
|
||||
fileDescriptorManager.process(delay);
|
||||
delay = osiTime::getCurrent() - begin;
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
//
|
||||
// exServer::exServer()
|
||||
//
|
||||
@@ -102,6 +43,7 @@ exServer::exServer(unsigned pvMaxNameLength, unsigned pvCountEstimate,
|
||||
ft.installReadFunc("alarmLowWarning",exPV::getLowLimit);
|
||||
ft.installReadFunc("units",exPV::getUnits);
|
||||
ft.installReadFunc("value",exPV::getValue);
|
||||
ft.installReadFunc("enums",exPV::getEnums);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -62,6 +62,17 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// for use when MSVC++ will not build a defualt copy constructor
|
||||
// for this class
|
||||
//
|
||||
pvInfo (const pvInfo ©In) :
|
||||
scanRate(copyIn.scanRate), name(copyIn.name),
|
||||
hopr(copyIn.hopr), lopr(copyIn.lopr),
|
||||
ioType(copyIn.ioType)
|
||||
{
|
||||
}
|
||||
|
||||
const double getScanRate () const { return this->scanRate; }
|
||||
const aitString &getName () const { return this->name; }
|
||||
const double getHopr () const { return this->hopr; }
|
||||
@@ -149,6 +160,7 @@ public:
|
||||
gddAppFuncTableStatus getLowLimit(gdd &value);
|
||||
gddAppFuncTableStatus getUnits(gdd &value);
|
||||
gddAppFuncTableStatus getValue(gdd &value);
|
||||
gddAppFuncTableStatus getEnums(gdd &value);
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
61
src/cas/example/main.cc
Normal file
61
src/cas/example/main.cc
Normal file
@@ -0,0 +1,61 @@
|
||||
|
||||
#include <exServer.h>
|
||||
#include <fdManager.h>
|
||||
|
||||
//
|
||||
// main()
|
||||
//
|
||||
int main (int argc, const char **argv)
|
||||
{
|
||||
osiTime begin(osiTime::getCurrent());
|
||||
exServer *pCAS;
|
||||
unsigned debugLevel = 0u;
|
||||
float executionTime;
|
||||
aitBool forever = aitTrue;
|
||||
int i;
|
||||
|
||||
pCAS = new exServer(32u,5u,500u);
|
||||
if (!pCAS) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
for (i=1; i<argc; i++) {
|
||||
if (sscanf(argv[i], "-d %u", &debugLevel)==1) {
|
||||
continue;
|
||||
}
|
||||
if (sscanf(argv[i],"-t %f", &executionTime)==1) {
|
||||
forever = aitFalse;
|
||||
continue;
|
||||
}
|
||||
printf ("usage: %s -d<debug level> -t<execution time>\n",
|
||||
argv[0]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
pCAS->setDebugLevel(debugLevel);
|
||||
|
||||
if (forever) {
|
||||
osiTime delay(1000u,0u);
|
||||
//
|
||||
// loop here forever
|
||||
//
|
||||
while (aitTrue) {
|
||||
fileDescriptorManager.process(delay);
|
||||
}
|
||||
}
|
||||
else {
|
||||
osiTime total(executionTime);
|
||||
osiTime delay(osiTime::getCurrent() - begin);
|
||||
//
|
||||
// loop here untime the specified execution time
|
||||
// expires
|
||||
//
|
||||
while (delay < total) {
|
||||
fileDescriptorManager.process(delay);
|
||||
delay = osiTime::getCurrent() - begin;
|
||||
}
|
||||
}
|
||||
delete pCAS;
|
||||
return (0);
|
||||
}
|
||||
|
||||
70
src/cas/example/vxEntry.cc
Normal file
70
src/cas/example/vxEntry.cc
Normal file
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// $Id$
|
||||
// Author: Jeff HIll (LANL)
|
||||
//
|
||||
// $Log$
|
||||
//
|
||||
|
||||
#include <exServer.h>
|
||||
#include <taskLib.h>
|
||||
|
||||
//
|
||||
// so we can call this from the vxWorks shell
|
||||
//
|
||||
extern "C" {
|
||||
|
||||
exServer *pExampleCAS;
|
||||
|
||||
//
|
||||
// excas ()
|
||||
// (vxWorks example server entry point)
|
||||
//
|
||||
int excas (unsigned debugLevel, unsigned delaySec)
|
||||
{
|
||||
osiTime begin(osiTime::getCurrent());
|
||||
exServer *pCAS;
|
||||
|
||||
pCAS = new exServer(32u,5u,500u);
|
||||
if (!pCAS) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
pCAS->setDebugLevel(debugLevel);
|
||||
pExampleCAS = pCAS;
|
||||
|
||||
if (delaySec==0u) {
|
||||
//
|
||||
// loop here forever
|
||||
//
|
||||
while (1) {
|
||||
taskDelay(10);
|
||||
}
|
||||
}
|
||||
else {
|
||||
osiTime total( ((float)delaySec) );
|
||||
osiTime delay(osiTime::getCurrent() - begin);
|
||||
//
|
||||
// loop here untill the specified execution time
|
||||
// expires
|
||||
//
|
||||
while (delay < total) {
|
||||
taskDelay(10);
|
||||
delay = osiTime::getCurrent() - begin;
|
||||
}
|
||||
}
|
||||
pCAS->show(debugLevel);
|
||||
pExampleCAS = NULL;
|
||||
delete pCAS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int excasShow(unsigned level)
|
||||
{
|
||||
if (pExampleCAS!=NULL) {
|
||||
pExampleCAS->show(level);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
this directory contains the generic source for
|
||||
the EPICS ca server
|
||||
this directory contains the generic (os and io independent) source for
|
||||
the EPICS ca server library
|
||||
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.2 1996/06/21 02:30:52 jhill
|
||||
* solaris port
|
||||
*
|
||||
* Revision 1.1.1.1 1996/06/20 00:28:14 jhill
|
||||
* ca server installation
|
||||
*
|
||||
@@ -115,6 +118,9 @@ void caServer::show(unsigned level)
|
||||
if (this->pCAS) {
|
||||
this->pCAS->show(level);
|
||||
}
|
||||
else {
|
||||
printf("caServer:: no server internals attached\n");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -29,6 +29,12 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.4 1996/09/04 20:12:04 jhill
|
||||
* added arg to serverToolDebugFunc()
|
||||
*
|
||||
* Revision 1.3 1996/08/13 22:56:12 jhill
|
||||
* added init for mutex class
|
||||
*
|
||||
* Revision 1.2 1996/08/05 19:25:17 jhill
|
||||
* removed unused code
|
||||
*
|
||||
@@ -58,13 +64,15 @@ void caServerI::show (unsigned level)
|
||||
printf( "Channel Access Server Status V%d.%d\n",
|
||||
CA_PROTOCOL_VERSION, CA_MINOR_VERSION);
|
||||
|
||||
this->lock();
|
||||
this->osiMutex::show(level);
|
||||
|
||||
this->osiLock();
|
||||
while ( (pClient = iter()) ) {
|
||||
pClient->show(level);
|
||||
}
|
||||
|
||||
this->dgClient.show(level);
|
||||
this->unlock();
|
||||
this->osiUnlock();
|
||||
|
||||
bytes_reserved = 0u;
|
||||
#if 0
|
||||
@@ -91,14 +99,14 @@ void caServerI::show (unsigned level)
|
||||
#endif
|
||||
printf(
|
||||
"The server's integer resource id conversion table:\n");
|
||||
this->lock();
|
||||
this->osiLock();
|
||||
this->uintResTable<casRes>::show(level);
|
||||
this->unlock();
|
||||
this->osiUnlock();
|
||||
printf(
|
||||
"The server's character string resource id conversion table:\n");
|
||||
this->lock();
|
||||
this->osiLock();
|
||||
this->stringResTbl.show(level);
|
||||
this->unlock();
|
||||
this->osiUnlock();
|
||||
}
|
||||
|
||||
// @@@@@@ caPrintAddrList(&destAddr);
|
||||
@@ -190,7 +198,7 @@ caServerI::~caServerI()
|
||||
{
|
||||
casClient *pClient;
|
||||
|
||||
this->lock();
|
||||
this->osiLock();
|
||||
|
||||
//
|
||||
// delete all clients
|
||||
@@ -199,6 +207,8 @@ caServerI::~caServerI()
|
||||
delete pClient;
|
||||
}
|
||||
|
||||
this->osiUnlock();
|
||||
|
||||
//
|
||||
// verify that we didnt leak a PV
|
||||
//
|
||||
@@ -211,9 +221,9 @@ caServerI::~caServerI()
|
||||
//
|
||||
void caServerI::installClient(casStrmClient *pClient)
|
||||
{
|
||||
this->lock();
|
||||
this->osiLock();
|
||||
this->clientList.add(*pClient);
|
||||
this->unlock();
|
||||
this->osiUnlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -222,9 +232,9 @@ void caServerI::installClient(casStrmClient *pClient)
|
||||
//
|
||||
void caServerI::removeClient(casStrmClient *pClient)
|
||||
{
|
||||
this->lock();
|
||||
this->osiLock();
|
||||
this->clientList.remove(*pClient);
|
||||
this->unlock();
|
||||
this->osiUnlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -300,10 +310,10 @@ void casVerifyFunc(const char *pFile, unsigned line, const char *pExp)
|
||||
//
|
||||
// serverToolDebugFunc()
|
||||
//
|
||||
void serverToolDebugFunc(const char *pFile, unsigned line)
|
||||
void serverToolDebugFunc(const char *pFile, unsigned line, const char *pComment)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Bad server tool response detected at line %u in \"%s\"\n",
|
||||
line, pFile);
|
||||
"Bad server tool response detected at line %u in \"%s\" because \"%s\"\n",
|
||||
line, pFile, pComment);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.1.1.1 1996/06/20 00:28:16 jhill
|
||||
* ca server installation
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -110,10 +113,10 @@ inline void caServerI::installPV (casPVI &pv)
|
||||
{
|
||||
int resLibStatus;
|
||||
|
||||
this->lock ();
|
||||
this->osiLock ();
|
||||
this->pvCount++;
|
||||
resLibStatus = this->stringResTbl.add (pv);
|
||||
this->unlock ();
|
||||
this->osiUnlock ();
|
||||
assert (resLibStatus==0);
|
||||
}
|
||||
|
||||
@@ -124,11 +127,11 @@ inline void caServerI::removePV(casPVI &pv)
|
||||
{
|
||||
casPVI *pPV;
|
||||
|
||||
this->lock();
|
||||
this->osiLock();
|
||||
casVerify (this->pvCount>=1u);
|
||||
this->pvCount--;
|
||||
pPV = this->stringResTbl.remove (pv);
|
||||
this->unlock();
|
||||
this->osiUnlock();
|
||||
casVerify (pPV!=0);
|
||||
casVerify (pPV==&pv);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.2 1996/06/26 21:18:50 jhill
|
||||
* now matches gdd api revisions
|
||||
*
|
||||
* Revision 1.1.1.1 1996/06/20 00:28:14 jhill
|
||||
* ca server installation
|
||||
*
|
||||
@@ -45,7 +48,9 @@
|
||||
// casAsyncIOI::casAsyncIOI()
|
||||
//
|
||||
casAsyncIOI::casAsyncIOI(const casCtx &ctx, casAsyncIO &ioIn, gdd *pDD) :
|
||||
msg(*ctx.getMsg()), client(*ctx.getClient()),
|
||||
msg(*ctx.getMsg()),
|
||||
client(*ctx.getClient()),
|
||||
asyncIO(ioIn),
|
||||
pChan(ctx.getChannel()),
|
||||
pDesc(pDD),
|
||||
completionStatus(S_cas_internal),
|
||||
@@ -56,10 +61,7 @@ casAsyncIOI::casAsyncIOI(const casCtx &ctx, casAsyncIO &ioIn, gdd *pDD) :
|
||||
{
|
||||
assert (&this->client);
|
||||
assert (&this->msg);
|
||||
//
|
||||
// casAsyncIOI must be a base of casAsyncIO
|
||||
//
|
||||
assert (this == (casAsyncIOI *)&ioIn);
|
||||
assert (&this->asyncIO);
|
||||
|
||||
if (this->pChan) {
|
||||
this->pChan->installAsyncIO(*this);
|
||||
|
||||
@@ -29,6 +29,12 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.2 1996/09/04 20:16:24 jhill
|
||||
* moved operator -> here
|
||||
*
|
||||
* Revision 1.1.1.1 1996/06/20 00:28:16 jhill
|
||||
* ca server installation
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -41,7 +47,7 @@
|
||||
//
|
||||
inline void casAsyncIOI::lock()
|
||||
{
|
||||
client.lock();
|
||||
client.osiLock();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -49,7 +55,15 @@ inline void casAsyncIOI::lock()
|
||||
//
|
||||
inline void casAsyncIOI::unlock()
|
||||
{
|
||||
client.unlock();
|
||||
client.osiUnlock();
|
||||
}
|
||||
|
||||
//
|
||||
// casAsyncIO * casAsyncIOI::operator -> ()
|
||||
//
|
||||
inline casAsyncIO * casAsyncIOI::operator -> ()
|
||||
{
|
||||
return &this->asyncIO;
|
||||
}
|
||||
|
||||
#endif // casAsyncIOIIL_h
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.3 1996/08/13 22:52:31 jhill
|
||||
* changes for MVC++
|
||||
*
|
||||
* Revision 1.2 1996/07/01 19:56:09 jhill
|
||||
* one last update prior to first release
|
||||
*
|
||||
@@ -60,10 +63,10 @@ casChannel::~casChannel()
|
||||
|
||||
casPV *casChannel::getPV()
|
||||
{
|
||||
casPVI pvi = this->casChannelI::getPVI();
|
||||
casPVI *pPVI = &this->casChannelI::getPVI();
|
||||
|
||||
if (&pvi!=NULL) {
|
||||
return pvi.intefaceObjectPointer();
|
||||
if (pPVI!=NULL) {
|
||||
return pPVI->interfaceObjectPointer();
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
|
||||
@@ -29,11 +29,15 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.1.1.1 1996/06/20 00:28:14 jhill
|
||||
* ca server installation
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <server.h>
|
||||
#include <casEventSysIL.h> // casEventSys inline func
|
||||
#include <casAsyncIOIIL.h> // casAsyncIOI inline func
|
||||
#include <casPVIIL.h> // casPVI inline func
|
||||
|
||||
|
||||
@@ -43,14 +47,12 @@
|
||||
casChannelI::casChannelI(const casCtx &ctx, casChannel &chanAdapter) :
|
||||
client(* (casStrmClient *) ctx.getClient()),
|
||||
pv(*ctx.getPV()),
|
||||
chan(chanAdapter),
|
||||
cid(ctx.getMsg()->m_cid)
|
||||
{
|
||||
assert(&this->client);
|
||||
assert(&this->pv);
|
||||
//
|
||||
// enforce that casChannelI is always a base of casChannel
|
||||
//
|
||||
assert(&chanAdapter == (casChannel *) this);
|
||||
assert(&this->chan);
|
||||
|
||||
this->client.installChannel(*this);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,12 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.3 1996/09/04 20:18:27 jhill
|
||||
* moved operator -> here
|
||||
*
|
||||
* Revision 1.2 1996/07/01 19:56:10 jhill
|
||||
* one last update prior to first release
|
||||
*
|
||||
* Revision 1.1.1.1 1996/06/20 00:28:16 jhill
|
||||
* ca server installation
|
||||
*
|
||||
@@ -39,12 +45,20 @@
|
||||
#ifndef casChannelIIL_h
|
||||
#define casChannelIIL_h
|
||||
|
||||
//
|
||||
// casChannelI::operator -> ()
|
||||
//
|
||||
inline casChannel * casChannelI::operator -> ()
|
||||
{
|
||||
return &this->chan;
|
||||
}
|
||||
|
||||
//
|
||||
// casChannelI::lock()
|
||||
//
|
||||
inline void casChannelI::lock()
|
||||
{
|
||||
this->client.lock();
|
||||
this->client.osiLock();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -52,7 +66,7 @@ inline void casChannelI::lock()
|
||||
//
|
||||
inline void casChannelI::unlock()
|
||||
{
|
||||
this->client.unlock();
|
||||
this->client.osiUnlock();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -162,5 +176,6 @@ inline const caResId casChannelI::getSID()
|
||||
return this->uintId::getId();
|
||||
}
|
||||
|
||||
|
||||
#endif // casChannelIIL_h
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.3 1996/08/13 22:56:13 jhill
|
||||
* added init for mutex class
|
||||
*
|
||||
* Revision 1.2 1996/07/09 22:54:31 jhill
|
||||
* store msg copy in the ctx
|
||||
*
|
||||
@@ -41,6 +44,7 @@
|
||||
|
||||
#include <server.h>
|
||||
#include <casClientIL.h> // inline func for casClient
|
||||
#include <db_access.h>
|
||||
|
||||
VERSIONID(camsgtaskc,"%W% %G%")
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.2 1996/08/13 22:53:14 jhill
|
||||
* changes for MVC++
|
||||
*
|
||||
* Revision 1.1.1.1 1996/06/20 00:28:16 jhill
|
||||
* ca server installation
|
||||
*
|
||||
@@ -107,6 +110,8 @@ casCoreClient::~casCoreClient()
|
||||
ca_printf ("CAS: Connection Terminated\n");
|
||||
}
|
||||
|
||||
this->osiLock();
|
||||
|
||||
//
|
||||
// cancel any pending asynchronous IO
|
||||
//
|
||||
@@ -120,6 +125,8 @@ casCoreClient::~casCoreClient()
|
||||
delete pCurIO;
|
||||
pCurIO = pNextIO;
|
||||
}
|
||||
|
||||
this->osiUnlock();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -29,6 +29,12 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.5 1996/09/04 20:19:47 jhill
|
||||
* added missing byte swap on search reply port no
|
||||
*
|
||||
* Revision 1.4 1996/08/13 22:54:20 jhill
|
||||
* fixed little endian problem
|
||||
*
|
||||
* Revision 1.3 1996/08/05 19:26:15 jhill
|
||||
* made os specific code smaller
|
||||
*
|
||||
@@ -95,8 +101,7 @@ caStatus casDGClient::searchAction()
|
||||
// longest PV name then just ignore this request
|
||||
// (and let the client to try again later)
|
||||
//
|
||||
// set correct appl type here !!!!
|
||||
pCanonicalName = new gddAtomic(0u, aitEnumString, 1u);
|
||||
pCanonicalName = new gddScalar(gddAppType_name, aitEnumString);
|
||||
if (!pCanonicalName) {
|
||||
return S_cas_success;
|
||||
}
|
||||
@@ -210,7 +215,7 @@ caStatus casDGClient::searchResponse(casChannelI *nullPtr, const caHdr &msg,
|
||||
*search_reply = msg;
|
||||
search_reply->m_postsize = sizeof(*pMinorVersion);
|
||||
search_reply->m_cid = ~0U;
|
||||
search_reply->m_type = htons(this->ctx.getServer()->serverPortNumber());
|
||||
search_reply->m_type = this->ctx.getServer()->serverPortNumber();
|
||||
search_reply->m_count = 0ul;
|
||||
|
||||
/*
|
||||
@@ -309,7 +314,8 @@ void casDGClient::process()
|
||||
// force all replies to be sent to the client
|
||||
// that made the request
|
||||
//
|
||||
this->clear();
|
||||
this->inBuf::clear();
|
||||
this->outBuf::clear();
|
||||
|
||||
//
|
||||
// read in new input
|
||||
@@ -317,12 +323,11 @@ void casDGClient::process()
|
||||
fillCond = this->fill();
|
||||
if (fillCond == casFillDisconnect) {
|
||||
casVerify(0);
|
||||
return;
|
||||
}
|
||||
//
|
||||
// verify that we have a message to process
|
||||
//
|
||||
if (this->inBuf::bytesPresent()>0u) {
|
||||
else if (this->inBuf::bytesPresent()>0u) {
|
||||
//
|
||||
// process the message
|
||||
//
|
||||
@@ -330,22 +335,20 @@ void casDGClient::process()
|
||||
if (status) {
|
||||
errMessage (status,
|
||||
"unexpected error processing stateless protocol");
|
||||
//
|
||||
// clear the input buffer so this will
|
||||
// not effect future input
|
||||
//
|
||||
this->clear();
|
||||
}
|
||||
else {
|
||||
//
|
||||
// force all replies to go to the sender
|
||||
//
|
||||
flushCond = this->flush();
|
||||
if (flushCond!=casFlushCompleted) {
|
||||
this->clear();
|
||||
casVerify(0);
|
||||
}
|
||||
}
|
||||
//
|
||||
// force all replies to go to the sender
|
||||
//
|
||||
flushCond = this->flush();
|
||||
if (flushCond!=casFlushCompleted) {
|
||||
casVerify(0);
|
||||
}
|
||||
}
|
||||
//
|
||||
// clear the input/output buffers so replies
|
||||
// are always sent to the sender of the request
|
||||
//
|
||||
this->inBuf::clear();
|
||||
this->outBuf::clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.1.1.1 1996/06/20 00:28:16 jhill
|
||||
* ca server installation
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -91,7 +94,7 @@ inline casEventMask casEventRegistry::maskAllocator()
|
||||
{
|
||||
casEventMask evMask;
|
||||
|
||||
if (this->allocator>=CHAR_BIT*sizeof(casEventMask::mask)) {
|
||||
if (this->allocator>=CHAR_BIT*sizeof(evMask.mask)) {
|
||||
return evMask;
|
||||
}
|
||||
evMask.mask = 1u<<(this->allocator++);
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.2 1996/07/24 22:00:49 jhill
|
||||
* added pushOnToEventQueue()
|
||||
*
|
||||
* Revision 1.1.1.1 1996/06/20 00:28:15 jhill
|
||||
* ca server installation
|
||||
*
|
||||
@@ -79,16 +82,18 @@ casEventSys::~casEventSys()
|
||||
{
|
||||
casEvent *pE;
|
||||
|
||||
this->mutex.lock();
|
||||
|
||||
/*
|
||||
* They must cancel all active event blocks first
|
||||
* all active event blocks must be canceled first
|
||||
*/
|
||||
assert (this->numEventBlocks==0);
|
||||
|
||||
this->mutex.osiLock();
|
||||
|
||||
while ( (pE = this->eventLogQue.get()) ) {
|
||||
delete pE;
|
||||
}
|
||||
|
||||
this->mutex.osiUnlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -97,10 +102,10 @@ casEventSys::~casEventSys()
|
||||
//
|
||||
void casEventSys::installMonitor()
|
||||
{
|
||||
this->mutex.lock();
|
||||
this->mutex.osiLock();
|
||||
this->numEventBlocks++;
|
||||
this->maxLogEntries += averageEventEntries;
|
||||
this->mutex.unlock();
|
||||
this->mutex.osiUnlock();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -108,11 +113,11 @@ void casEventSys::installMonitor()
|
||||
//
|
||||
void casEventSys::removeMonitor()
|
||||
{
|
||||
this->mutex.lock();
|
||||
this->mutex.osiLock();
|
||||
assert (this->numEventBlocks>=1u);
|
||||
this->numEventBlocks--;
|
||||
this->maxLogEntries -= averageEventEntries;
|
||||
this->mutex.unlock();
|
||||
this->mutex.osiUnlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -126,7 +131,7 @@ casProcCond casEventSys::process()
|
||||
casProcCond cond = casProcOk;
|
||||
unsigned long nAccepted = 0u;
|
||||
|
||||
this->mutex.lock();
|
||||
this->mutex.osiLock();
|
||||
|
||||
while ( (pEvent = this->eventLogQue.get()) ) {
|
||||
|
||||
@@ -166,7 +171,7 @@ casProcCond casEventSys::process()
|
||||
this->coreClient.eventFlush();
|
||||
}
|
||||
|
||||
this->mutex.unlock();
|
||||
this->mutex.osiUnlock();
|
||||
|
||||
return cond;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.1.1.1 1996/06/20 00:28:16 jhill
|
||||
* ca server installation
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -41,9 +44,9 @@
|
||||
//
|
||||
inline void casEventSys::addToEventQueue(casEvent &event)
|
||||
{
|
||||
this->mutex.lock();
|
||||
this->mutex.osiLock();
|
||||
this->eventLogQue.add(event);
|
||||
this->mutex.unlock();
|
||||
this->mutex.osiUnlock();
|
||||
//
|
||||
// wakes up the event queue consumer
|
||||
//
|
||||
|
||||
@@ -29,6 +29,12 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.6 1996/09/04 20:21:41 jhill
|
||||
* removed operator -> and added member pv
|
||||
*
|
||||
* Revision 1.5 1996/07/01 19:56:11 jhill
|
||||
* one last update prior to first release
|
||||
*
|
||||
* Revision 1.4 1996/06/26 23:32:17 jhill
|
||||
* changed where caProto.h comes from (again)
|
||||
*
|
||||
@@ -125,7 +131,7 @@ inline ioBlockedList::~ioBlockedList ()
|
||||
// ioBlockedList::signal ()
|
||||
//
|
||||
// works from a temporary list to avoid problems
|
||||
// where the virtual function adds ites to the
|
||||
// where the virtual function adds items to the
|
||||
// list
|
||||
//
|
||||
inline void ioBlockedList::signal ()
|
||||
@@ -353,14 +359,7 @@ public:
|
||||
|
||||
caServer *getCAS();
|
||||
|
||||
//
|
||||
// casAsyncIOI must always be a base for casAsyncIO
|
||||
// (the constructor assert fails if this isnt the case)
|
||||
//
|
||||
casAsyncIO * operator -> ()
|
||||
{
|
||||
return (casAsyncIO *) this;
|
||||
}
|
||||
inline casAsyncIO * operator -> ();
|
||||
|
||||
void setServerDelete()
|
||||
{
|
||||
@@ -393,6 +392,7 @@ private:
|
||||
|
||||
caHdr const msg;
|
||||
casCoreClient &client;
|
||||
casAsyncIO &asyncIO;
|
||||
casChannelI *pChan; // optional
|
||||
gdd *pDesc; // optional
|
||||
caStatus completionStatus;
|
||||
@@ -461,24 +461,19 @@ public:
|
||||
return casChanT;
|
||||
}
|
||||
|
||||
//
|
||||
// casChannelI must always be a base for casPV
|
||||
// (the constructor assert fails if this isnt the case)
|
||||
//
|
||||
casChannel * operator -> ()
|
||||
{
|
||||
return (casChannel *) this;
|
||||
}
|
||||
|
||||
inline void lock();
|
||||
inline void unlock();
|
||||
|
||||
inline void clientDestroy();
|
||||
|
||||
inline casChannel * operator -> ();
|
||||
|
||||
protected:
|
||||
tsDLList<casMonitor> monitorList;
|
||||
tsDLList<casAsyncIOI> ioInProgList;
|
||||
casCoreClient &client;
|
||||
casPVI &pv;
|
||||
casChannel &chan;
|
||||
caResId const cid; // client id
|
||||
unsigned clientDestroyPending:1;
|
||||
};
|
||||
@@ -493,7 +488,6 @@ public:
|
||||
inline ~casPVListChan();
|
||||
};
|
||||
|
||||
class caServer;
|
||||
class caServerI;
|
||||
class casCtx;
|
||||
class casChannel;
|
||||
@@ -509,7 +503,7 @@ public:
|
||||
// The PV name here must be the canonical and unique name
|
||||
// for the PV in this system
|
||||
//
|
||||
casPVI (caServerI &cas, const char * const pName, casPV &pvAdapter);
|
||||
casPVI (caServerI &cas, const char * const pNameIn, casPV &pvAdapter);
|
||||
~casPVI();
|
||||
|
||||
//
|
||||
@@ -556,23 +550,12 @@ public:
|
||||
|
||||
inline void postEvent (const casEventMask &select, gdd &event);
|
||||
|
||||
casPV *intefaceObjectPointer() const
|
||||
{
|
||||
return (casPV *) this;
|
||||
}
|
||||
inline casPV *interfaceObjectPointer() const;
|
||||
|
||||
//
|
||||
// casPVI must always be a base for casPV
|
||||
// (the constructor assert fails if this isnt the case)
|
||||
//
|
||||
casPV * operator -> () const
|
||||
{
|
||||
return intefaceObjectPointer();
|
||||
}
|
||||
inline casPV * operator -> () const;
|
||||
|
||||
caServer *getExtServer();
|
||||
|
||||
|
||||
//
|
||||
// bestDBRType()
|
||||
//
|
||||
@@ -580,12 +563,14 @@ public:
|
||||
|
||||
inline aitBool okToBeginNewIO() const;
|
||||
|
||||
inline void lock();
|
||||
inline void unlock();
|
||||
private:
|
||||
tsDLList<casPVListChan> chanList;
|
||||
caServerI &cas;
|
||||
casPV &pv;
|
||||
unsigned nMonAttached;
|
||||
unsigned nIOAttached;
|
||||
|
||||
inline void lock();
|
||||
inline void unlock();
|
||||
};
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.4 1996/07/24 22:00:49 jhill
|
||||
* added pushOnToEventQueue()
|
||||
*
|
||||
* Revision 1.3 1996/07/01 19:56:11 jhill
|
||||
* one last update prior to first release
|
||||
*
|
||||
@@ -82,7 +85,7 @@ casMonitor::~casMonitor()
|
||||
{
|
||||
casCoreClient &client = this->ciu.getClient();
|
||||
|
||||
this->mutex.lock();
|
||||
this->mutex.osiLock();
|
||||
|
||||
this->disable();
|
||||
|
||||
@@ -97,6 +100,8 @@ casMonitor::~casMonitor()
|
||||
this->pModifiedValue = NULL;
|
||||
}
|
||||
this->ciu.deleteMonitor(*this);
|
||||
|
||||
this->mutex.osiUnlock();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -106,24 +111,16 @@ void casMonitor::enable()
|
||||
{
|
||||
caStatus status;
|
||||
|
||||
this->mutex.lock();
|
||||
if (this->enabled) {
|
||||
this->mutex.unlock();
|
||||
return;
|
||||
this->mutex.osiLock();
|
||||
if (!this->enabled && this->ciu->readAccess()) {
|
||||
this->enabled = TRUE;
|
||||
status = this->ciu.getPVI().registerEvent();
|
||||
if (status) {
|
||||
errMessage(status,
|
||||
"Server tool failed to register event\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->ciu->readAccess()) {
|
||||
this->mutex.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
this->enabled = TRUE;
|
||||
status = this->ciu.getPVI().registerEvent();
|
||||
if (status) {
|
||||
errMessage(status,
|
||||
"Server tool failed to register event\n");
|
||||
}
|
||||
this->mutex.unlock();
|
||||
this->mutex.osiUnlock();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -131,14 +128,12 @@ void casMonitor::enable()
|
||||
//
|
||||
void casMonitor::disable()
|
||||
{
|
||||
this->mutex.lock();
|
||||
if (!this->enabled) {
|
||||
this->mutex.unlock();
|
||||
return;
|
||||
this->mutex.osiLock();
|
||||
if (this->enabled) {
|
||||
this->enabled = FALSE;
|
||||
this->ciu.getPVI().unregisterEvent();
|
||||
}
|
||||
this->enabled = FALSE;
|
||||
this->ciu.getPVI().unregisterEvent();
|
||||
this->mutex.unlock();
|
||||
this->mutex.osiUnlock();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -150,7 +145,7 @@ void casMonitor::push(gdd &newValue)
|
||||
casMonEvent *pLog = NULL;
|
||||
char full;
|
||||
|
||||
this->mutex.lock();
|
||||
this->mutex.osiLock();
|
||||
|
||||
//
|
||||
// get a new block if we havent exceeded quotas
|
||||
@@ -205,7 +200,7 @@ void casMonitor::push(gdd &newValue)
|
||||
|
||||
client.addToEventQueue(*pLog);
|
||||
|
||||
this->mutex.unlock();
|
||||
this->mutex.osiUnlock();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -219,7 +214,7 @@ caStatus casMonitor::executeEvent(casMonEvent *pEV)
|
||||
pVal = pEV->getValue ();
|
||||
assert (pVal);
|
||||
|
||||
this->mutex.lock();
|
||||
this->mutex.osiLock();
|
||||
if (this->ciu.getClient().getEventsOff()==aitFalse) {
|
||||
status = this->callBack (*pVal);
|
||||
}
|
||||
@@ -236,7 +231,7 @@ caStatus casMonitor::executeEvent(casMonEvent *pEV)
|
||||
this->pModifiedValue = pVal;
|
||||
status = S_cas_success;
|
||||
}
|
||||
this->mutex.unlock();
|
||||
this->mutex.osiUnlock();
|
||||
|
||||
//
|
||||
// if the event isnt accepted we will try
|
||||
@@ -285,12 +280,12 @@ void casMonitor::show(unsigned level)
|
||||
//
|
||||
void casMonitor::postIfModified()
|
||||
{
|
||||
this->mutex.lock();
|
||||
this->mutex.osiLock();
|
||||
if (this->pModifiedValue) {
|
||||
this->callBack (*this->pModifiedValue);
|
||||
this->pModifiedValue->unreference ();
|
||||
this->pModifiedValue = NULL;
|
||||
}
|
||||
this->mutex.unlock();
|
||||
this->mutex.osiUnlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.1.1.1 1996/06/20 00:28:15 jhill
|
||||
* ca server installation
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -39,8 +42,9 @@
|
||||
|
||||
casMsgIO::casMsgIO()
|
||||
{
|
||||
elapsedAtLastSend = this->elapsedAtLastRecv
|
||||
this->elapsedAtLastSend = this->elapsedAtLastRecv
|
||||
= osiTime::getCurrent ();
|
||||
this->blockingStatus = xIsBlocking;
|
||||
}
|
||||
|
||||
casMsgIO::~casMsgIO()
|
||||
@@ -81,15 +85,41 @@ xRecvStatus casMsgIO::xRecv(char *pBuf, bufSizeT nBytes, bufSizeT &nActualBytes)
|
||||
return stat;
|
||||
}
|
||||
|
||||
xSendStatus casMsgIO::xSend(char *pBuf, bufSizeT nBytes, bufSizeT &nActualBytes)
|
||||
xSendStatus casMsgIO::xSend(char *pBuf, bufSizeT nBytesAvailableToSend,
|
||||
bufSizeT nBytesNeedToBeSent, bufSizeT &nActualBytes)
|
||||
{
|
||||
xSendStatus stat;
|
||||
bufSizeT nActualBytesDelta;
|
||||
|
||||
stat = this->osdSend(pBuf, nBytes, nActualBytes);
|
||||
if (stat == xSendOK) {
|
||||
this->elapsedAtLastSend = osiTime::getCurrent();
|
||||
assert (nBytesAvailableToSend>=nBytesNeedToBeSent);
|
||||
|
||||
nActualBytes = 0u;
|
||||
if (this->blockingStatus == xIsntBlocking) {
|
||||
stat = this->osdSend(pBuf, nBytesAvailableToSend,
|
||||
nActualBytes);
|
||||
if (stat == xSendOK) {
|
||||
this->elapsedAtLastSend = osiTime::getCurrent();
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
return stat;
|
||||
|
||||
while (nBytesNeedToBeSent) {
|
||||
stat = this->osdSend(pBuf, nBytesAvailableToSend,
|
||||
nActualBytesDelta);
|
||||
if (stat != xSendOK) {
|
||||
return stat;
|
||||
}
|
||||
|
||||
this->elapsedAtLastSend = osiTime::getCurrent();
|
||||
nActualBytes += nActualBytesDelta;
|
||||
if (nBytesNeedToBeSent>nActualBytesDelta) {
|
||||
nBytesNeedToBeSent -= nActualBytesDelta;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return xSendOK;
|
||||
}
|
||||
|
||||
void casMsgIO::sendBeacon(char & /*msg*/, bufSizeT /*length*/,
|
||||
@@ -103,9 +133,9 @@ int casMsgIO::getFileDescriptor() const
|
||||
return -1; // some os will not have file descriptors
|
||||
}
|
||||
|
||||
void casMsgIO::setNonBlocking()
|
||||
void casMsgIO::xSetNonBlocking()
|
||||
{
|
||||
printf("virtual base setNonBlocking() called?\n");
|
||||
printf("virtual base casMsgIO::xSetNonBlocking() called?\n");
|
||||
}
|
||||
|
||||
bufSizeT casMsgIO::incommingBytesPresent() const
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.3 1996/07/01 19:56:13 jhill
|
||||
* one last update prior to first release
|
||||
*
|
||||
* Revision 1.2 1996/06/26 21:18:57 jhill
|
||||
* now matches gdd api revisions
|
||||
*
|
||||
@@ -49,16 +52,14 @@
|
||||
//
|
||||
casPVI::casPVI(caServerI &casIn, const char * const pNameIn,
|
||||
casPV &pvAdapterIn) :
|
||||
cas(casIn),
|
||||
stringId(pNameIn),
|
||||
cas(casIn),
|
||||
pv(pvAdapterIn),
|
||||
nMonAttached(0u),
|
||||
nIOAttached(0u)
|
||||
{
|
||||
assert(&cas);
|
||||
//
|
||||
// casPVI must always be a base of casPV
|
||||
//
|
||||
assert(&pvAdapterIn == (casPV *)this);
|
||||
assert(&this->cas);
|
||||
assert(&this->pv);
|
||||
this->cas.installPV(*this);
|
||||
}
|
||||
|
||||
@@ -108,22 +109,22 @@ caStatus casPVI::verifyPVName(gdd &name)
|
||||
//
|
||||
gddStatus = name.reference();
|
||||
if (gddStatus) {
|
||||
serverToolDebug();
|
||||
serverToolDebug("GDD PV name must not be \"no ref\"");
|
||||
return S_cas_badPVName;
|
||||
}
|
||||
gddStatus = name.unreference();
|
||||
if (gddStatus) {
|
||||
serverToolDebug();
|
||||
serverToolDebug("corruption expected");
|
||||
return S_cas_badPVName;
|
||||
}
|
||||
|
||||
if (name.primitiveType() != aitEnumString) {
|
||||
serverToolDebug();
|
||||
serverToolDebug("GDD PV name must be stored as an aitString");
|
||||
return S_cas_badPVName;
|
||||
}
|
||||
|
||||
if (name.dimension() != 1u) {
|
||||
serverToolDebug();
|
||||
if (name.dimension() != 0u) {
|
||||
serverToolDebug("GDD Dimension must be zero (gddScaler)");
|
||||
return S_cas_badPVName;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,12 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.5 1996/09/04 20:23:59 jhill
|
||||
* added operator ->
|
||||
*
|
||||
* Revision 1.4 1996/07/01 19:56:13 jhill
|
||||
* one last update prior to first release
|
||||
*
|
||||
* Revision 1.3 1996/06/26 21:18:58 jhill
|
||||
* now matches gdd api revisions
|
||||
*
|
||||
@@ -47,12 +53,38 @@
|
||||
|
||||
#include <dbMapper.h>
|
||||
|
||||
|
||||
//
|
||||
// casPVI::interfaceObjectPointer()
|
||||
//
|
||||
// casPVI must always be a base for casPV
|
||||
// (the constructor assert fails if this isnt the case)
|
||||
//
|
||||
inline casPV *casPVI::interfaceObjectPointer() const
|
||||
{
|
||||
return &this->pv;
|
||||
}
|
||||
|
||||
//
|
||||
// casPVI::operator -> ()
|
||||
//
|
||||
casPV * casPVI::operator -> () const
|
||||
{
|
||||
return interfaceObjectPointer();
|
||||
}
|
||||
|
||||
//
|
||||
// casPVI::lock()
|
||||
//
|
||||
inline void casPVI::lock()
|
||||
{
|
||||
this->cas.lock();
|
||||
//
|
||||
// NOTE:
|
||||
// if this lock becomes something else besides the
|
||||
// server's lock then look carefully at the
|
||||
// comment in casPVI::deleteSignal()
|
||||
//
|
||||
this->cas.osiLock();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -60,7 +92,7 @@ inline void casPVI::lock()
|
||||
//
|
||||
inline void casPVI::unlock()
|
||||
{
|
||||
this->cas.unlock();
|
||||
this->cas.osiUnlock();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -88,8 +120,7 @@ inline void casPVI::removeChannel(casPVListChan &chan)
|
||||
//
|
||||
inline aitBool casPVI::okToBeginNewIO() const
|
||||
{
|
||||
if (this->nIOAttached >= (*this)->maxSimultAsyncOps())
|
||||
{
|
||||
if (this->nIOAttached >= (*this)->maxSimultAsyncOps()) {
|
||||
return aitFalse;
|
||||
}
|
||||
else {
|
||||
@@ -126,13 +157,29 @@ inline void casPVI::unregisterIO()
|
||||
//
|
||||
inline void casPVI::deleteSignal()
|
||||
{
|
||||
this->lock();
|
||||
caServerI &localCASRef(this->cas);
|
||||
|
||||
//
|
||||
// We dont take the PV lock here because
|
||||
// the PV may be destroyed and we must
|
||||
// keep the lock unlock pairs consistent
|
||||
// (because the PV's lock is really a ref
|
||||
// to the server's lock)
|
||||
//
|
||||
// This is safe to do because we take the PV
|
||||
// lock when we add a new channel (and the
|
||||
// PV lock is realy the server's lock)
|
||||
//
|
||||
localCASRef.osiLock();
|
||||
|
||||
if (this->chanList.count()==0u) {
|
||||
(*this)->destroy();
|
||||
//
|
||||
// !! dont access self after destroy !!
|
||||
//
|
||||
}
|
||||
else {
|
||||
this->unlock();
|
||||
}
|
||||
|
||||
localCASRef.osiUnlock();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -178,7 +225,6 @@ inline void casPVI::postEvent (const casEventMask &select, gdd &event)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // casPVIIL_h
|
||||
|
||||
|
||||
|
||||
@@ -29,6 +29,13 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.9 1996/09/04 20:25:53 jhill
|
||||
* use correct app type for exist test gdd, correct byte
|
||||
* oder for mon mask, and efficient use of PV name gdd
|
||||
*
|
||||
* Revision 1.8 1996/08/05 23:22:57 jhill
|
||||
* gddScaler => gddScalar
|
||||
*
|
||||
* Revision 1.7 1996/08/05 19:26:51 jhill
|
||||
* doc
|
||||
*
|
||||
@@ -116,8 +123,7 @@ inline caStatus casStrmClient::createChannel (const char *pName)
|
||||
int gddStatus;
|
||||
gdd *pCanonicalName;
|
||||
|
||||
// set correct appl type here !!!!
|
||||
pCanonicalName = new gddAtomic(0u, aitEnumString, 1u);
|
||||
pCanonicalName = new gddScalar(gddAppType_name, aitEnumString);
|
||||
if (!pCanonicalName) {
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
@@ -212,7 +218,7 @@ casStrmClient::~casStrmClient()
|
||||
delete [] this->pHostName;
|
||||
}
|
||||
|
||||
this->lock();
|
||||
this->osiLock();
|
||||
|
||||
//
|
||||
// delete all channel attached
|
||||
@@ -226,6 +232,10 @@ casStrmClient::~casStrmClient()
|
||||
pChan->clientDestroy();
|
||||
pChan = pNextChan;
|
||||
}
|
||||
|
||||
delete &this->msgIO;
|
||||
|
||||
this->osiUnlock();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -810,7 +820,7 @@ caStatus casStrmClient::hostNameAction()
|
||||
size-1);
|
||||
pMalloc[size-1]='\0';
|
||||
|
||||
this->lock();
|
||||
this->osiLock();
|
||||
|
||||
if (this->pHostName) {
|
||||
delete [] this->pHostName;
|
||||
@@ -821,7 +831,7 @@ caStatus casStrmClient::hostNameAction()
|
||||
(*pciu)->setOwner(this->pUserName, this->pHostName);
|
||||
}
|
||||
|
||||
this->unlock();
|
||||
this->osiUnlock();
|
||||
|
||||
return S_cas_success;
|
||||
}
|
||||
@@ -855,7 +865,7 @@ caStatus casStrmClient::clientNameAction()
|
||||
size-1);
|
||||
pMalloc[size-1]='\0';
|
||||
|
||||
this->lock();
|
||||
this->osiLock();
|
||||
if (this->pUserName) {
|
||||
delete [] this->pUserName;
|
||||
}
|
||||
@@ -864,7 +874,7 @@ caStatus casStrmClient::clientNameAction()
|
||||
while ( (pciu = iter()) ) {
|
||||
(*pciu)->setOwner(this->pUserName, this->pHostName);
|
||||
}
|
||||
this->unlock();
|
||||
this->osiUnlock();
|
||||
|
||||
return S_cas_success;
|
||||
}
|
||||
@@ -1013,11 +1023,11 @@ caStatus casStrmClient::eventsOnAction ()
|
||||
// perhaps this is to slow - perhaps there
|
||||
// should be a queue of modified events
|
||||
//
|
||||
this->lock();
|
||||
this->osiLock();
|
||||
while ( (pciu = iter()) ) {
|
||||
pciu->postAllModifiedEvents();
|
||||
}
|
||||
this->unlock();
|
||||
this->osiUnlock();
|
||||
|
||||
return S_cas_success;
|
||||
}
|
||||
@@ -1058,6 +1068,11 @@ caStatus casStrmClient::eventAddAction ()
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
//
|
||||
// place monitor mask in correct byte order
|
||||
//
|
||||
pMonInfo->m_mask = ntohs (pMonInfo->m_mask);
|
||||
|
||||
if (pMonInfo->m_mask&DBE_VALUE) {
|
||||
mask |= this->getCAS().getAdapter()->valueEventMask;
|
||||
}
|
||||
@@ -1566,15 +1581,15 @@ caStatus createDBRDD (unsigned dbrType, aitIndex dbrCount, gdd *&pDescRet)
|
||||
pVal = pCont->getDD(valIndex);
|
||||
assert (pVal);
|
||||
gddStatus = pVal->setBound (0, 0u, dbrCount);
|
||||
assert (gddStatus==0)
|
||||
assert (gddStatus==0);
|
||||
}
|
||||
else if (pDescRet->isAtomic()) {
|
||||
gddAtomic *pAtomic = (gddAtomic *) pDescRet;
|
||||
gddStatus = pAtomic->setBound(0, 0u, dbrCount);
|
||||
assert (gddStatus==0)
|
||||
assert (gddStatus==0);
|
||||
}
|
||||
else {
|
||||
assert(dbrCount==1u);
|
||||
assert (dbrCount==1u);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1632,13 +1647,13 @@ caStatus casStrmClient::createChanResponse(casChannelI *,
|
||||
// prevent problems such as the PV being deleted before the
|
||||
// channel references it
|
||||
//
|
||||
this->lock();
|
||||
this->osiLock();
|
||||
|
||||
pCanonicalName->markConstant();
|
||||
|
||||
pPV = this->ctx.getServer()->createPV(*pCanonicalName);
|
||||
if (!pPV) {
|
||||
this->unlock();
|
||||
this->osiUnlock();
|
||||
return this->channelCreateFailed(&msg, S_cas_noMemory);
|
||||
}
|
||||
|
||||
@@ -1649,12 +1664,12 @@ caStatus casStrmClient::createChanResponse(casChannelI *,
|
||||
pChan = (*pPV)->createChannel(this->ctx,
|
||||
this->pUserName, this->pHostName);
|
||||
if (!pChan) {
|
||||
this->unlock();
|
||||
this->osiUnlock();
|
||||
pPV->deleteSignal();
|
||||
return this->channelCreateFailed(&msg, S_cas_noMemory);
|
||||
}
|
||||
|
||||
this->unlock();
|
||||
this->osiUnlock();
|
||||
|
||||
pChanI = (casChannelI *) pChan;
|
||||
|
||||
@@ -1683,6 +1698,7 @@ casPVI *caServerI::createPV (gdd &name)
|
||||
{
|
||||
casPVI *pPVI;
|
||||
caStatus status;
|
||||
aitString *pNameStr;
|
||||
|
||||
//
|
||||
// dont proceed unless its a valid PV name
|
||||
@@ -1700,15 +1716,15 @@ casPVI *caServerI::createPV (gdd &name)
|
||||
// way currently to test) it will prove fatal
|
||||
// to the server
|
||||
//
|
||||
aitString aitStr(name);
|
||||
stringId id (aitStr.string());
|
||||
name.getRef(pNameStr);
|
||||
stringId id (pNameStr->string());
|
||||
|
||||
this->lock ();
|
||||
this->osiLock ();
|
||||
|
||||
pPVI = this->stringResTbl.lookup (id);
|
||||
if (!pPVI) {
|
||||
casPV *pPV;
|
||||
pPV = (*this)->createPV (this->ctx, aitStr.string());
|
||||
pPV = (*this)->createPV (this->ctx, pNameStr->string());
|
||||
if (pPV) {
|
||||
pPVI = (casPVI *) pPV;
|
||||
}
|
||||
@@ -1718,7 +1734,7 @@ casPVI *caServerI::createPV (gdd &name)
|
||||
// lock shouldnt be released until we finish creating and
|
||||
// installing the PV
|
||||
//
|
||||
this->unlock ();
|
||||
this->osiUnlock ();
|
||||
|
||||
return pPVI;
|
||||
}
|
||||
@@ -1736,10 +1752,10 @@ inline aitBool caServerI::roomForNewChannel() const
|
||||
//
|
||||
void casStrmClient::installChannel(casChannelI &chan)
|
||||
{
|
||||
this->lock();
|
||||
this->osiLock();
|
||||
this->getCAS().installItem(chan);
|
||||
this->chanList.add(chan);
|
||||
this->unlock();
|
||||
this->osiUnlock();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1749,10 +1765,10 @@ void casStrmClient::removeChannel(casChannelI &chan)
|
||||
{
|
||||
casRes *pRes;
|
||||
|
||||
this->lock();
|
||||
this->osiLock();
|
||||
pRes = this->getCAS().removeItem(chan);
|
||||
assert (&chan == (casChannelI *)pRes);
|
||||
this->chanList.remove(chan);
|
||||
this->unlock();
|
||||
this->osiUnlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* $Log$
|
||||
* Revision 1.5 1996/08/13 22:54:42 jhill
|
||||
* doc
|
||||
*
|
||||
* Revision 1.4 1996/07/01 19:56:15 jhill
|
||||
* one last update prior to first release
|
||||
*
|
||||
@@ -252,6 +255,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class caServerI;
|
||||
|
||||
//
|
||||
// caServer - Channel Access Server API Class
|
||||
//
|
||||
@@ -271,10 +276,6 @@ public:
|
||||
unsigned maxSimultaneousIO=1u);
|
||||
virtual ~caServer();
|
||||
|
||||
//
|
||||
// Need VF that returns pointer to derived type ?
|
||||
//
|
||||
|
||||
//caStatus enableClients ();
|
||||
//caStatus disableClients ();
|
||||
|
||||
@@ -542,5 +543,5 @@ public:
|
||||
casPV *getPV();
|
||||
};
|
||||
|
||||
#endif /* ifdef includecasdefh (this must be the last line in this file) */
|
||||
#endif // ifdef includecasdefh (this must be the last line in this file)
|
||||
|
||||
|
||||
@@ -29,6 +29,12 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.3 1996/09/04 20:27:01 jhill
|
||||
* doccasdef.h
|
||||
*
|
||||
* Revision 1.2 1996/08/13 22:53:59 jhill
|
||||
* fixed little endian problem
|
||||
*
|
||||
* Revision 1.1.1.1 1996/06/20 00:28:15 jhill
|
||||
* ca server installation
|
||||
*
|
||||
@@ -44,13 +50,12 @@
|
||||
//
|
||||
outBuf::outBuf(casMsgIO &virtualCircuit, osiMutex &mutexIn) :
|
||||
io(virtualCircuit),
|
||||
mutex(mutexIn)
|
||||
mutex(mutexIn),
|
||||
pBuf(NULL),
|
||||
bufSize(io.optimumBufferSize()),
|
||||
stack(0u)
|
||||
{
|
||||
assert(&io);
|
||||
|
||||
this->stack = 0u;
|
||||
this->bufSize = 0u;
|
||||
this->pBuf = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -58,10 +63,8 @@ outBuf::outBuf(casMsgIO &virtualCircuit, osiMutex &mutexIn) :
|
||||
//
|
||||
caStatus outBuf::init()
|
||||
{
|
||||
this->bufSize = io.optimumBufferSize();
|
||||
this->pBuf = new char [this->bufSize];
|
||||
if (!this->pBuf) {
|
||||
this->bufSize = 0u;
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
return S_cas_success;
|
||||
@@ -91,30 +94,32 @@ caHdr **ppMsg
|
||||
)
|
||||
{
|
||||
bufSizeT msgsize;
|
||||
bufSizeT stackNeeded;
|
||||
|
||||
extsize = CA_MESSAGE_ALIGN(extsize);
|
||||
|
||||
msgsize = extsize + sizeof(caHdr);
|
||||
if (msgsize>this->bufSize) {
|
||||
if (msgsize>this->bufSize || this->pBuf==NULL) {
|
||||
return S_cas_hugeRequest;
|
||||
}
|
||||
|
||||
stackNeeded = this->bufSize - msgsize;
|
||||
|
||||
this->mutex.lock();
|
||||
this->mutex.osiLock();
|
||||
|
||||
if (this->stack + msgsize > this->bufSize) {
|
||||
if (this->stack > stackNeeded) {
|
||||
|
||||
/*
|
||||
* Try to flush the output queue
|
||||
*/
|
||||
this->flush();
|
||||
this->flush(casFlushSpecified, msgsize);
|
||||
|
||||
/*
|
||||
* If this failed then the fd is nonblocking
|
||||
* and we will let select() take care of it
|
||||
*/
|
||||
if (this->stack + msgsize > this->bufSize) {
|
||||
this->mutex.unlock();
|
||||
if (this->stack > stackNeeded) {
|
||||
this->mutex.osiUnlock();
|
||||
this->sendBlockSignal();
|
||||
return S_cas_sendBlocked;
|
||||
}
|
||||
@@ -172,6 +177,7 @@ void outBuf::commitMsg ()
|
||||
*/
|
||||
mp->m_cmmd = htons (mp->m_cmmd);
|
||||
mp->m_postsize = htons (mp->m_postsize);
|
||||
mp->m_type = htons (mp->m_type);
|
||||
mp->m_count = htons (mp->m_count);
|
||||
mp->m_cid = htonl (mp->m_cid);
|
||||
mp->m_available = htonl (mp->m_available);
|
||||
@@ -179,43 +185,69 @@ void outBuf::commitMsg ()
|
||||
this->stack += sizeof(caHdr) + extSize;
|
||||
assert (this->stack <= this->bufSize);
|
||||
|
||||
this->mutex.unlock();
|
||||
this->mutex.osiUnlock();
|
||||
}
|
||||
|
||||
//
|
||||
// outBuf::flush()
|
||||
//
|
||||
casFlushCondition outBuf::flush()
|
||||
casFlushCondition outBuf::flush(casFlushRequest req,
|
||||
bufSizeT spaceRequired)
|
||||
{
|
||||
bufSizeT nBytes;
|
||||
xSendStatus stat;
|
||||
bufSizeT nBytes;
|
||||
bufSizeT stackNeeded;
|
||||
bufSizeT nBytesNeeded;
|
||||
xSendStatus stat;
|
||||
casFlushCondition cond;
|
||||
|
||||
if (this->stack<=0u) {
|
||||
return casFlushCompleted;
|
||||
}
|
||||
|
||||
stat = this->io.xSend(this->pBuf, this->stack, nBytes);
|
||||
if (stat!=xSendOK) {
|
||||
if (!this->pBuf) {
|
||||
return casFlushDisconnect;
|
||||
}
|
||||
else if (nBytes >= this->stack) {
|
||||
this->stack=0u;
|
||||
return casFlushCompleted;
|
||||
}
|
||||
else if (nBytes) {
|
||||
bufSizeT len;
|
||||
|
||||
len = this->stack-nBytes;
|
||||
//
|
||||
// memmove() is ok with overlapping buffers
|
||||
//
|
||||
memmove (this->pBuf, &this->pBuf[nBytes], len);
|
||||
this->stack = len;
|
||||
return casFlushPartial;
|
||||
this->mutex.osiLock();
|
||||
|
||||
if (req==casFlushAll) {
|
||||
nBytesNeeded = this->stack;
|
||||
}
|
||||
else {
|
||||
return casFlushNone;
|
||||
stackNeeded = this->bufSize - spaceRequired;
|
||||
if (this->stack>stackNeeded) {
|
||||
nBytesNeeded = this->stack - stackNeeded;
|
||||
}
|
||||
else {
|
||||
nBytesNeeded = 0u;
|
||||
}
|
||||
}
|
||||
|
||||
stat = this->io.xSend(this->pBuf, this->stack,
|
||||
nBytesNeeded, nBytes);
|
||||
if (nBytes) {
|
||||
bufSizeT len;
|
||||
|
||||
if (nBytes >= this->stack) {
|
||||
this->stack=0u;
|
||||
cond = casFlushCompleted;
|
||||
}
|
||||
else {
|
||||
len = this->stack-nBytes;
|
||||
//
|
||||
// memmove() is ok with overlapping buffers
|
||||
//
|
||||
memmove (this->pBuf, &this->pBuf[nBytes], len);
|
||||
this->stack = len;
|
||||
cond = casFlushPartial;
|
||||
}
|
||||
}
|
||||
else {
|
||||
cond = casFlushNone;
|
||||
}
|
||||
|
||||
if (stat!=xSendOK) {
|
||||
cond = casFlushDisconnect;
|
||||
}
|
||||
this->mutex.osiUnlock();
|
||||
return cond;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -29,6 +29,12 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.10 1996/09/04 20:27:02 jhill
|
||||
* doccasdef.h
|
||||
*
|
||||
* Revision 1.9 1996/08/13 22:56:14 jhill
|
||||
* added init for mutex class
|
||||
*
|
||||
* Revision 1.8 1996/08/05 23:22:58 jhill
|
||||
* gddScaler => gddScalar
|
||||
*
|
||||
@@ -75,21 +81,13 @@ HDRVERSIONID(serverh, "%W% %G%")
|
||||
//
|
||||
// ANSI C
|
||||
//
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
|
||||
//
|
||||
// EPICS
|
||||
//
|
||||
#define epicsAssertAuthor "Jeff Hill johill@lanl.gov"
|
||||
#include <epicsAssert.h>
|
||||
#include <db_access.h>
|
||||
|
||||
//
|
||||
// CA
|
||||
@@ -99,20 +97,13 @@ HDRVERSIONID(serverh, "%W% %G%")
|
||||
#include <casdef.h>
|
||||
#include <osiTime.h>
|
||||
|
||||
//
|
||||
// gdd
|
||||
//
|
||||
#if 0
|
||||
#include <dbMapper.h>
|
||||
#include <gddApps.h>
|
||||
#endif
|
||||
|
||||
//
|
||||
// CAS
|
||||
//
|
||||
void casVerifyFunc(const char *pFile, unsigned line, const char *pExp);
|
||||
void serverToolDebugFunc(const char *pFile, unsigned line);
|
||||
#define serverToolDebug() {serverToolDebugFunc(__FILE__, __LINE__); }
|
||||
void serverToolDebugFunc(const char *pFile, unsigned line, const char *pComment);
|
||||
#define serverToolDebug(COMMENT) \
|
||||
{serverToolDebugFunc(__FILE__, __LINE__, COMMENT); }
|
||||
#define casVerify(EXP) {if ((EXP)==0) casVerifyFunc(__FILE__, __LINE__, #EXP); }
|
||||
caStatus createDBRDD(unsigned dbrType, aitIndex dbrCount, gdd *&pDescRet);
|
||||
caStatus copyBetweenDD(gdd &dest, gdd &src);
|
||||
@@ -122,6 +113,7 @@ caStatus copyBetweenDD(gdd &dest, gdd &src);
|
||||
//
|
||||
enum xRecvStatus {xRecvOK, xRecvDisconnect};
|
||||
enum xSendStatus {xSendOK, xSendDisconnect};
|
||||
enum xBlockingStatus {xIsBlocking, xIsntBlocking};
|
||||
enum casIOState {casOnLine, casOffLine};
|
||||
typedef unsigned bufSizeT;
|
||||
class casMsgIO {
|
||||
@@ -141,8 +133,8 @@ public:
|
||||
//
|
||||
// device dependent recv
|
||||
//
|
||||
xSendStatus xSend (char *pBuf, bufSizeT nBytesToSend,
|
||||
bufSizeT &nBytesSent);
|
||||
xSendStatus xSend (char *pBuf, bufSizeT nBytesAvailableToSend,
|
||||
bufSizeT nBytesNeedToBeSent, bufSizeT &nBytesSent);
|
||||
xRecvStatus xRecv (char *pBuf, bufSizeT nBytesToRecv,
|
||||
bufSizeT &nByesRecv);
|
||||
|
||||
@@ -152,7 +144,11 @@ public:
|
||||
virtual casIOState state() const=0;
|
||||
virtual void hostNameFromAddr (char *pBuf, unsigned bufSize)=0;
|
||||
virtual int getFileDescriptor() const;
|
||||
virtual void setNonBlocking();
|
||||
void setNonBlocking()
|
||||
{
|
||||
this->xSetNonBlocking();
|
||||
this->blockingStatus = xIsntBlocking;
|
||||
}
|
||||
|
||||
//
|
||||
// only for use with DG io
|
||||
@@ -166,12 +162,14 @@ private:
|
||||
//
|
||||
osiTime elapsedAtLastSend;
|
||||
osiTime elapsedAtLastRecv;
|
||||
xBlockingStatus blockingStatus;
|
||||
|
||||
virtual xSendStatus osdSend (const char *pBuf,
|
||||
bufSizeT nBytesReq, bufSizeT &nBytesActual) =0;
|
||||
virtual xRecvStatus osdRecv (char *pBuf,
|
||||
bufSizeT nBytesReq, bufSizeT &nBytesActual) =0;
|
||||
virtual void osdShow (unsigned level) const = 0;
|
||||
virtual void xSetNonBlocking();
|
||||
};
|
||||
|
||||
#include <casOSD.h> // OS dependent
|
||||
@@ -272,9 +270,9 @@ private:
|
||||
//
|
||||
inline void casEventSys::insertEventQueue(casEvent &insert, casEvent &prevEvent)
|
||||
{
|
||||
this->mutex.lock();
|
||||
this->mutex.osiLock();
|
||||
this->eventLogQue.insertAfter(insert, prevEvent);
|
||||
this->mutex.unlock();
|
||||
this->mutex.osiUnlock();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -282,9 +280,9 @@ inline void casEventSys::insertEventQueue(casEvent &insert, casEvent &prevEvent)
|
||||
//
|
||||
inline void casEventSys::pushOnToEventQueue(casEvent &event)
|
||||
{
|
||||
this->mutex.lock();
|
||||
this->mutex.osiLock();
|
||||
this->eventLogQue.push(event);
|
||||
this->mutex.unlock();
|
||||
this->mutex.osiUnlock();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -292,9 +290,9 @@ inline void casEventSys::pushOnToEventQueue(casEvent &event)
|
||||
//
|
||||
inline void casEventSys::removeFromEventQueue(casEvent &event)
|
||||
{
|
||||
this->mutex.lock();
|
||||
this->mutex.osiLock();
|
||||
this->eventLogQue.remove(event);
|
||||
this->mutex.unlock();
|
||||
this->mutex.osiUnlock();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -481,6 +479,9 @@ enum casFlushCondition{
|
||||
casFlushPartial,
|
||||
casFlushCompleted,
|
||||
casFlushDisconnect};
|
||||
enum casFlushRequest{
|
||||
casFlushAll,
|
||||
casFlushSpecified};
|
||||
|
||||
class outBuf {
|
||||
public:
|
||||
@@ -492,13 +493,24 @@ public:
|
||||
// number of bytes in the output queue?
|
||||
//
|
||||
bufSizeT bytesPresent() const
|
||||
{ return this->stack; }
|
||||
{
|
||||
return this->stack;
|
||||
}
|
||||
|
||||
//
|
||||
// number of bytes unused in the output queue?
|
||||
//
|
||||
bufSizeT bytesFree() const
|
||||
{
|
||||
return this->bufSize - this->stack;
|
||||
}
|
||||
|
||||
//
|
||||
// flush output queue
|
||||
// (returns the number of bytes sent)
|
||||
//
|
||||
casFlushCondition flush();
|
||||
casFlushCondition flush(casFlushRequest req = casFlushAll,
|
||||
bufSizeT spaceRequired=0u);
|
||||
|
||||
//
|
||||
// allocate message buffer space
|
||||
@@ -514,18 +526,25 @@ public:
|
||||
//
|
||||
// release an allocated message (but dont send it)
|
||||
//
|
||||
void discardMsg () { this->mutex.unlock(); };
|
||||
void discardMsg ()
|
||||
{
|
||||
this->mutex.osiUnlock();
|
||||
};
|
||||
|
||||
void show(unsigned level);
|
||||
|
||||
virtual unsigned getDebugLevel()=0;
|
||||
virtual void sendBlockSignal()=0;
|
||||
|
||||
void clear()
|
||||
{
|
||||
this->stack = 0u;
|
||||
}
|
||||
private:
|
||||
casMsgIO &io;
|
||||
osiMutex &mutex;
|
||||
char *pBuf;
|
||||
bufSizeT bufSize;
|
||||
const bufSizeT bufSize;
|
||||
bufSizeT stack;
|
||||
};
|
||||
|
||||
@@ -564,16 +583,16 @@ public:
|
||||
|
||||
void installAsyncIO(casAsyncIOI &ioIn)
|
||||
{
|
||||
this->lock();
|
||||
this->osiLock();
|
||||
this->ioInProgList.add(ioIn);
|
||||
this->unlock();
|
||||
this->osiUnlock();
|
||||
}
|
||||
|
||||
void removeAsyncIO(casAsyncIOI &ioIn)
|
||||
{
|
||||
this->lock();
|
||||
this->osiLock();
|
||||
this->ioInProgList.remove(ioIn);
|
||||
this->unlock();
|
||||
this->osiUnlock();
|
||||
}
|
||||
|
||||
casRes *lookupRes(const caResId &idIn, casResType type);
|
||||
@@ -680,8 +699,8 @@ protected:
|
||||
const void *dp, const char *pFileName,
|
||||
const unsigned lineno);
|
||||
|
||||
private:
|
||||
casMsgIO &msgIO;
|
||||
private:
|
||||
|
||||
//
|
||||
// dump message to stderr
|
||||
@@ -834,7 +853,7 @@ private:
|
||||
//
|
||||
// casDGClient
|
||||
//
|
||||
class casDGClient : private casDGIO, public casClient {
|
||||
class casDGClient : private casDGIO, private casClient {
|
||||
public:
|
||||
casDGClient (caServerI &serverIn);
|
||||
|
||||
@@ -869,9 +888,24 @@ public:
|
||||
|
||||
void destroy();
|
||||
|
||||
int getFD() const
|
||||
{
|
||||
return this->casClient::getFD();
|
||||
}
|
||||
|
||||
protected:
|
||||
void process();
|
||||
|
||||
casProcCond eventSysProcess()
|
||||
{
|
||||
return this->casEventSys::process();
|
||||
}
|
||||
|
||||
casFlushCondition flush(casFlushRequest req = casFlushAll,
|
||||
bufSizeT spaceRequired=0u)
|
||||
{
|
||||
return this->outBuf::flush(req,spaceRequired);
|
||||
}
|
||||
private:
|
||||
void ioBlockedSignal(); // dummy
|
||||
|
||||
@@ -893,10 +927,8 @@ private:
|
||||
|
||||
class casClientMon;
|
||||
|
||||
//
|
||||
// caServerI
|
||||
//
|
||||
class caServerI : public caServerOS, public caServerIO,
|
||||
class caServerI :
|
||||
public caServerOS, public caServerIO,
|
||||
public osiMutex, public ioBlockedList,
|
||||
private uintResTable<casRes>,
|
||||
public casEventRegistry {
|
||||
@@ -983,7 +1015,7 @@ public:
|
||||
return &this->adapter;
|
||||
}
|
||||
|
||||
uintResTable<casRes> &getResTable() {return *this;}
|
||||
//uintResTable<casRes> &getResTable() {return *this;}
|
||||
|
||||
void installItem(casRes &res)
|
||||
{
|
||||
|
||||
@@ -176,9 +176,9 @@ void casDGIO::osdShow (unsigned level) const
|
||||
}
|
||||
|
||||
//
|
||||
// casDGIO::setNonBlocking()
|
||||
// casDGIO::xSetNonBlocking()
|
||||
//
|
||||
void casDGIO::setNonBlocking()
|
||||
void casDGIO::xSetNonBlocking()
|
||||
{
|
||||
int status;
|
||||
int yes = TRUE;
|
||||
@@ -276,7 +276,10 @@ xSendStatus casDGIO::osdSend(const char *pBuf, bufSizeT size,
|
||||
return xSendOK;
|
||||
}
|
||||
|
||||
status = sendto(this->sock, pBuf, size, 0,
|
||||
//
|
||||
// (char *) cast below is for brain dead wrs prototype
|
||||
//
|
||||
status = sendto(this->sock, (char *) pBuf, size, 0,
|
||||
&this->lastRecvAddr.sa,
|
||||
sizeof(this->lastRecvAddr.sa));
|
||||
if (status>0) {
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
// Some BSD calls have crept in here
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.4 1996/09/04 20:29:08 jhill
|
||||
// removed os depen stuff
|
||||
//
|
||||
// Revision 1.3 1996/08/13 23:00:29 jhill
|
||||
// removed include of netdb.h
|
||||
//
|
||||
// Revision 1.2 1996/07/24 22:03:36 jhill
|
||||
// fixed net proto for gnu compiler
|
||||
//
|
||||
@@ -19,43 +25,13 @@
|
||||
#define includeCASIODH
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#ifndef SUNOS4 // func proto do not have args for C++ (under sunos4)
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <bsdProto.h>
|
||||
|
||||
typedef int SOCKET;
|
||||
#define SOCKERRNO errno
|
||||
#define socket_close(S) close(S)
|
||||
#define socket_ioctl(A,B,C) ioctl(A,B,C)
|
||||
#include <osiSock.h>
|
||||
|
||||
// ca
|
||||
#include <addrList.h>
|
||||
|
||||
void hostNameFromIPAddr (const caAddr *pAddr,
|
||||
char *pBuf, unsigned bufSize);
|
||||
#if 0
|
||||
//
|
||||
// assuming al posix machines are IEEE float will be wrong
|
||||
//
|
||||
#define ntohf(A) (A)
|
||||
#define ntohd(A) (A)
|
||||
#define htonf(A) (A)
|
||||
#define htond(A) (A)
|
||||
#endif
|
||||
|
||||
class caServerIO {
|
||||
public:
|
||||
@@ -111,7 +87,7 @@ public:
|
||||
~casStreamIO();
|
||||
|
||||
int getFileDescriptor() const;
|
||||
void setNonBlocking();
|
||||
void xSetNonBlocking();
|
||||
bufSizeT optimumBufferSize ();
|
||||
|
||||
casIOState state() const;
|
||||
@@ -137,7 +113,7 @@ public:
|
||||
~casDGIO();
|
||||
|
||||
int getFileDescriptor() const;
|
||||
void setNonBlocking();
|
||||
void xSetNonBlocking();
|
||||
bufSizeT optimumBufferSize ();
|
||||
void sendBeacon(char &msg, bufSizeT length,
|
||||
aitUint32 &m_avail);
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
//
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.4 1996/07/24 22:03:36 jhill
|
||||
// fixed net proto for gnu compiler
|
||||
//
|
||||
// Revision 1.3 1996/07/09 22:55:22 jhill
|
||||
// added cast
|
||||
//
|
||||
@@ -23,8 +26,15 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#ifndef SUNOS4 // the SUNOS4 prototypes are trad C - see bsdProto.h
|
||||
//
|
||||
// the SUNOS4 and vxWorks5.2 prototypes are trad C
|
||||
//
|
||||
#if !defined(SUNOS4) && !defined(vxWorks)
|
||||
#include <arpa/inet.h>
|
||||
#else
|
||||
extern "C" {
|
||||
char * inet_ntoa(struct in_addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -32,10 +42,9 @@
|
||||
// casStreamIO::casStreamIO()
|
||||
//
|
||||
casStreamIO::casStreamIO(const SOCKET s, const caAddr &a) :
|
||||
sock(s), addr(a)
|
||||
sockState(casOffLine), sock(s), addr(a)
|
||||
{
|
||||
assert (sock>=0);
|
||||
this->sockState = casOffLine;
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +133,8 @@ caStatus casStreamIO::init()
|
||||
casStreamIO::~casStreamIO()
|
||||
{
|
||||
if (sock>=0) {
|
||||
close(sock);
|
||||
close(this->sock);
|
||||
printf("closing sock=%d\n", this->sock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +142,7 @@ casStreamIO::~casStreamIO()
|
||||
//
|
||||
// casStreamIO::osdSend()
|
||||
//
|
||||
xSendStatus casStreamIO::osdSend(const char *pBuf, bufSizeT nBytes,
|
||||
xSendStatus casStreamIO::osdSend(const char *pBuf, bufSizeT nBytesReq,
|
||||
bufSizeT &nBytesActual)
|
||||
{
|
||||
int status;
|
||||
@@ -156,31 +166,29 @@ xSendStatus casStreamIO::osdSend(const char *pBuf, bufSizeT nBytes,
|
||||
return xSendDisconnect;
|
||||
}
|
||||
|
||||
|
||||
if (nBytes<=0u) {
|
||||
if (nBytesReq<=0u) {
|
||||
nBytesActual = 0u;
|
||||
return xSendOK;
|
||||
}
|
||||
|
||||
status = send (
|
||||
this->sock,
|
||||
pBuf,
|
||||
nBytes,
|
||||
0);
|
||||
if (status == 0) {
|
||||
this->sockState = casOffLine;
|
||||
status = send (
|
||||
this->sock,
|
||||
(char *) pBuf,
|
||||
nBytesReq,
|
||||
0);
|
||||
if (status == 0) {
|
||||
this->sockState = casOffLine;
|
||||
return xSendDisconnect;
|
||||
}
|
||||
else if (status<0) {
|
||||
int anerrno = SOCKERRNO;
|
||||
}
|
||||
else if (status<0) {
|
||||
int anerrno = SOCKERRNO;
|
||||
|
||||
if (anerrno != EWOULDBLOCK) {
|
||||
this->sockState = casOffLine;
|
||||
if (anerrno != EWOULDBLOCK) {
|
||||
this->sockState = casOffLine;
|
||||
}
|
||||
nBytesActual = 0u;
|
||||
return xSendOK;
|
||||
}
|
||||
|
||||
nBytesActual = (bufSizeT) status;
|
||||
return xSendOK;
|
||||
}
|
||||
@@ -247,9 +255,9 @@ void casStreamIO::osdShow (unsigned level) const
|
||||
|
||||
|
||||
//
|
||||
// casStreamIO::setNonBlocking()
|
||||
// casStreamIO::xSsetNonBlocking()
|
||||
//
|
||||
void casStreamIO::setNonBlocking()
|
||||
void casStreamIO::xSetNonBlocking()
|
||||
{
|
||||
int status;
|
||||
int yes = TRUE;
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
*
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.2 1996/08/05 19:29:25 jhill
|
||||
* os depen code now smaller
|
||||
*
|
||||
* Revision 1.1.1.1 1996/06/20 00:28:06 jhill
|
||||
* ca server installation
|
||||
*
|
||||
@@ -52,7 +55,7 @@ void casDGEvWakeup::show(unsigned level)
|
||||
void casDGEvWakeup::expire()
|
||||
{
|
||||
casProcCond cond;
|
||||
cond = this->os.casEventSys::process();
|
||||
cond = this->os.eventSysProcess();
|
||||
if (cond != casProcOk) {
|
||||
//
|
||||
// if "this" is being used above this
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
// Some BSD calls have crept in here
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.2 1996/08/13 22:58:15 jhill
|
||||
// fdMgr.h => fdmanager.h
|
||||
//
|
||||
// Revision 1.1.1.1 1996/06/20 00:28:06 jhill
|
||||
// ca server installation
|
||||
//
|
||||
@@ -24,7 +27,14 @@ extern "C" {
|
||||
// for htons() etc
|
||||
//
|
||||
# include <netinet/in.h>
|
||||
|
||||
//
|
||||
// g++ 2.7.2 does not fix this file under sunos4 so I
|
||||
// have provided the prototype elsewhere (in osiSock.h for now)
|
||||
//
|
||||
#if !(defined(SUNOS4) && defined(__GNUC__))
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
} // extern "C"
|
||||
|
||||
#include <osiMutex.h>
|
||||
|
||||
@@ -10,8 +10,9 @@ public:
|
||||
// (since g++ does not have exceptions)
|
||||
//
|
||||
int init() {return 0;}
|
||||
void lock() {};
|
||||
void unlock() {};
|
||||
void osiLock() {}
|
||||
void osiUnlock() {}
|
||||
void show (unsigned) {}
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
WORK IN PROGRESS
|
||||
|
||||
this directory contains the vxWorks os dependent source for
|
||||
the EPICS ca server
|
||||
the EPICS ca server. This is a multi-threaded port of the
|
||||
server.
|
||||
|
||||
|
||||
|
||||
127
src/cas/os/vxWorks/caServerOS.cc
Normal file
127
src/cas/os/vxWorks/caServerOS.cc
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
*
|
||||
* caServerOS.c
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.1 1996/09/04 22:06:43 jhill
|
||||
* installed
|
||||
*
|
||||
* Revision 1.1.1.1 1996/06/20 00:28:06 jhill
|
||||
* ca server installation
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <taskLib.h>
|
||||
#include <task_params.h>
|
||||
|
||||
//
|
||||
// CA server
|
||||
//
|
||||
#include <server.h>
|
||||
|
||||
//
|
||||
// aServerOS::operator -> ()
|
||||
//
|
||||
inline caServerI * caServerOS::operator -> ()
|
||||
{
|
||||
return &this->cas;
|
||||
}
|
||||
|
||||
//
|
||||
// casBeaconTimer::expire()
|
||||
//
|
||||
void casBeaconTimer::expire()
|
||||
{
|
||||
os->sendBeacon ();
|
||||
}
|
||||
|
||||
//
|
||||
// casBeaconTimer::again()
|
||||
//
|
||||
osiBool casBeaconTimer::again()
|
||||
{
|
||||
return osiTrue;
|
||||
}
|
||||
|
||||
//
|
||||
// casBeaconTimer::delay()
|
||||
//
|
||||
const osiTime casBeaconTimer::delay()
|
||||
{
|
||||
return os->getBeaconPeriod();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// caServerOS::init()
|
||||
//
|
||||
caStatus caServerOS::init()
|
||||
{
|
||||
this->pBTmr = new casBeaconTimer((*this)->getBeaconPeriod(), *this);
|
||||
if (!this->pBTmr) {
|
||||
ca_printf("CAS: Unable to start server beacon\n");
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
|
||||
//
|
||||
// WRS still passes pointers in ints
|
||||
//
|
||||
assert (sizeof(int)==sizeof(&this->cas));
|
||||
|
||||
this->tid = taskSpawn (
|
||||
REQ_SRVR_NAME,
|
||||
REQ_SRVR_PRI,
|
||||
REQ_SRVR_OPT,
|
||||
REQ_SRVR_STACK,
|
||||
(FUNCPTR) caServerEntry, // get your act together WRS
|
||||
(int) &this->cas, // get your act together WRS
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
if (this->tid==ERROR) {
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// caServerOS::~caServerOS()
|
||||
//
|
||||
caServerOS::~caServerOS()
|
||||
{
|
||||
if (this->pBTmr) {
|
||||
delete this->pBTmr;
|
||||
}
|
||||
|
||||
if (taskIdVerify(this->tid)==OK)
|
||||
{
|
||||
taskDelete(this->tid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// caServerEntry()
|
||||
//
|
||||
void caServerEntry(caServerI *pCAS)
|
||||
{
|
||||
//
|
||||
// forever
|
||||
//
|
||||
while (TRUE) {
|
||||
pCAS->connectCB();
|
||||
printf("process timer q here?\n");
|
||||
}
|
||||
}
|
||||
|
||||
77
src/cas/os/vxWorks/casClientOS.h
Normal file
77
src/cas/os/vxWorks/casClientOS.h
Normal file
@@ -0,0 +1,77 @@
|
||||
|
||||
class casStreamEvWakeup;
|
||||
|
||||
//
|
||||
// casStreamOS
|
||||
//
|
||||
class casStreamOS : public casStrmClient {
|
||||
friend int casStrmServer (casStreamOS *);
|
||||
friend int casStrmEvent (casStreamOS *);
|
||||
public:
|
||||
casStreamOS(caServerI &, casMsgIO &);
|
||||
caStatus init();
|
||||
~casStreamOS();
|
||||
|
||||
//
|
||||
// process any incomming messages
|
||||
//
|
||||
casProcCond processInput();
|
||||
caStatus start();
|
||||
|
||||
void sendBlockSignal();
|
||||
void ioBlockedSignal();
|
||||
|
||||
void eventSignal();
|
||||
void eventFlush();
|
||||
|
||||
void show(unsigned level);
|
||||
private:
|
||||
SEM_ID eventSignalSem;
|
||||
int clientTId;
|
||||
int eventTId;
|
||||
};
|
||||
|
||||
//
|
||||
// vxWorks task entry
|
||||
//
|
||||
int casStrmServer (casStreamOS *);
|
||||
int casStrmEvent (casStreamOS *);
|
||||
|
||||
class casDGEvWakeup;
|
||||
|
||||
//
|
||||
// casDGOS
|
||||
//
|
||||
class casDGOS : public casDGClient {
|
||||
friend int casDGServer (casDGOS *);
|
||||
friend int casDGEvent (casDGOS *);
|
||||
public:
|
||||
casDGOS(caServerI &cas);
|
||||
caStatus init();
|
||||
~casDGOS();
|
||||
|
||||
//
|
||||
// process any incomming messages
|
||||
//
|
||||
casProcCond processInput();
|
||||
caStatus start();
|
||||
|
||||
void sendBlockSignal() {}
|
||||
|
||||
void eventSignal();
|
||||
void eventFlush();
|
||||
|
||||
void show(unsigned level);
|
||||
private:
|
||||
SEM_ID eventSignalSem;
|
||||
int clientTId;
|
||||
int eventTId;
|
||||
};
|
||||
|
||||
//
|
||||
// vxWorks task entry
|
||||
//
|
||||
int casDGServer (casDGOS *);
|
||||
int casDGEvent (casDGOS *);
|
||||
|
||||
|
||||
209
src/cas/os/vxWorks/casDGOS.cc
Normal file
209
src/cas/os/vxWorks/casDGOS.cc
Normal file
@@ -0,0 +1,209 @@
|
||||
|
||||
/*
|
||||
*
|
||||
* casDGOS.c
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.1 1996/09/04 22:06:45 jhill
|
||||
* installed
|
||||
*
|
||||
* Revision 1.1.1.1 1996/06/20 00:28:06 jhill
|
||||
* ca server installation
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
//
|
||||
// CA server
|
||||
//
|
||||
#include <taskLib.h> // vxWorks
|
||||
|
||||
#include <server.h>
|
||||
#include <casClientIL.h> // casClient inline func
|
||||
#include <task_params.h> // EPICS task priorities
|
||||
|
||||
//
|
||||
// casDGOS::eventSignal()
|
||||
//
|
||||
void casDGOS::eventSignal()
|
||||
{
|
||||
STATUS st;
|
||||
|
||||
st = semGive(this->eventSignalSem);
|
||||
assert (st==OK);
|
||||
}
|
||||
|
||||
//
|
||||
// casDGOS::eventFlush()
|
||||
//
|
||||
void casDGOS::eventFlush()
|
||||
{
|
||||
this->flush();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// casDGOS::casDGOS()
|
||||
//
|
||||
casDGOS::casDGOS(caServerI &cas) :
|
||||
eventSignalSem(NULL),
|
||||
casDGClient(cas),
|
||||
clientTId(ERROR),
|
||||
eventTId(ERROR)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// casDGOS::init()
|
||||
//
|
||||
caStatus casDGOS::init()
|
||||
{
|
||||
caStatus status;
|
||||
|
||||
this->eventSignalSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
|
||||
if (this->eventSignalSem == NULL) {
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
|
||||
//
|
||||
// init the base classes
|
||||
//
|
||||
status = this->casDGClient::init();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// casDGOS::~casDGOS()
|
||||
//
|
||||
casDGOS::~casDGOS()
|
||||
{
|
||||
if (taskIdVerify(this->clientTId)==OK) {
|
||||
taskDelete(this->clientTId);
|
||||
}
|
||||
if (taskIdVerify(this->eventTId)==OK) {
|
||||
taskDelete(this->eventTId);
|
||||
}
|
||||
if (this->eventSignalSem) {
|
||||
semDelete(this->eventSignalSem);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// casDGOS::show()
|
||||
//
|
||||
void casDGOS::show(unsigned level)
|
||||
{
|
||||
this->casDGClient::show(level);
|
||||
printf ("casDGOS at %x\n", (unsigned) this);
|
||||
if (taskIdVerify(this->clientTId) == OK) {
|
||||
taskShow(this->clientTId, level);
|
||||
}
|
||||
if (taskIdVerify(this->eventTId) == OK) {
|
||||
printf("casDGOS task id = %x\n", this->eventTId);
|
||||
}
|
||||
if (this->eventSignalSem) {
|
||||
semShow(this->eventSignalSem, level);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casClientStart ()
|
||||
*/
|
||||
caStatus casDGOS::start()
|
||||
{
|
||||
//
|
||||
// no (void *) vxWorks task arg
|
||||
//
|
||||
assert (sizeof(int) >= sizeof(this));
|
||||
|
||||
this->clientTId = taskSpawn(
|
||||
CAST_SRVR_NAME,
|
||||
CAST_SRVR_PRI,
|
||||
CAST_SRVR_OPT,
|
||||
CAST_SRVR_STACK,
|
||||
(FUNCPTR) casDGServer, // get your act together wrs
|
||||
(int) this, // get your act together wrs
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
if (this->clientTId==ERROR) {
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
this->eventTId = taskSpawn(
|
||||
CA_EVENT_NAME,
|
||||
CA_CLIENT_PRI,
|
||||
CA_CLIENT_OPT,
|
||||
CAST_SRVR_STACK,
|
||||
(FUNCPTR) casDGEvent, // get your act together wrs
|
||||
(int) this, // get your act together wrs
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
if (this->eventTId==ERROR) {
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casDGOS::processInput ()
|
||||
* - a noop
|
||||
*/
|
||||
casProcCond casDGOS::processInput ()
|
||||
{
|
||||
return casProcOk;
|
||||
}
|
||||
|
||||
//
|
||||
// casDGServer()
|
||||
//
|
||||
int casDGServer (casDGOS *pDGOS)
|
||||
{
|
||||
//
|
||||
// block for the next DG until the connection closes
|
||||
//
|
||||
while (TRUE) {
|
||||
pDGOS->process();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// casDGEvent()
|
||||
//
|
||||
int casDGEvent (casDGOS *pDGOS)
|
||||
{
|
||||
STATUS status;
|
||||
casProcCond cond;
|
||||
|
||||
//
|
||||
// Wait for event queue entry
|
||||
//
|
||||
while (TRUE) {
|
||||
status = semTake(pDGOS->eventSignalSem, WAIT_FOREVER);
|
||||
assert (status!=OK);
|
||||
|
||||
cond = pDGOS->eventSysProcess();
|
||||
if (cond != casProcOk) {
|
||||
printf("DG event sys process failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
95
src/cas/os/vxWorks/casOSD.h
Normal file
95
src/cas/os/vxWorks/casOSD.h
Normal file
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// casOSD.h - Channel Access Server OS Dependent for posix
|
||||
//
|
||||
//
|
||||
// Some BSD calls have crept in here
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.1 1996/09/04 22:06:46 jhill
|
||||
// installed
|
||||
//
|
||||
// Revision 1.1.1.1 1996/06/20 00:28:06 jhill
|
||||
// ca server installation
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef includeCASOSDH
|
||||
#define includeCASOSDH
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
extern "C" {
|
||||
//
|
||||
// for htons() etc
|
||||
//
|
||||
# include <netinet/in.h>
|
||||
# include <ioLib.h>
|
||||
} // extern "C"
|
||||
|
||||
#include <osiMutex.h>
|
||||
#include <osiTimer.h>
|
||||
|
||||
class caServerI;
|
||||
|
||||
class caServerOS;
|
||||
|
||||
//
|
||||
// casBeaconTimer
|
||||
//
|
||||
class casBeaconTimer : public osiTimer {
|
||||
public:
|
||||
casBeaconTimer (const osiTime &delay, caServerOS &osIn) :
|
||||
os (osIn), osiTimer(delay) {}
|
||||
void expire();
|
||||
const osiTime delay();
|
||||
osiBool again();
|
||||
const char *name()
|
||||
{
|
||||
return "casBeaconTimer";
|
||||
}
|
||||
private:
|
||||
caServerOS &os;
|
||||
int taskId;
|
||||
};
|
||||
|
||||
class casServerReg;
|
||||
|
||||
class caServerOS;
|
||||
|
||||
//
|
||||
// vxWorks task entry
|
||||
//
|
||||
void caServerEntry(caServerI *pCAS);
|
||||
|
||||
//
|
||||
// caServerOS
|
||||
//
|
||||
class caServerOS {
|
||||
friend class casServerReg;
|
||||
friend void caServerEntry(caServerI *pCAS);
|
||||
public:
|
||||
caServerOS (caServerI &casIn) :
|
||||
cas (casIn), pBTmr (NULL), tid(ERROR) {}
|
||||
caStatus init ();
|
||||
~caServerOS ();
|
||||
|
||||
//caStatus start ();
|
||||
|
||||
inline caServerI * operator -> ();
|
||||
|
||||
//int getFD();
|
||||
|
||||
private:
|
||||
caServerI &cas;
|
||||
casBeaconTimer *pBTmr;
|
||||
int tid;
|
||||
};
|
||||
|
||||
// no additions below this line
|
||||
#endif // includeCASOSDH
|
||||
|
||||
275
src/cas/os/vxWorks/casStreamOS.cc
Normal file
275
src/cas/os/vxWorks/casStreamOS.cc
Normal file
@@ -0,0 +1,275 @@
|
||||
//
|
||||
// casStreamOS.cc
|
||||
// $Id$
|
||||
//
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.1 1996/09/04 22:06:46 jhill
|
||||
// installed
|
||||
//
|
||||
// Revision 1.1.1.1 1996/06/20 00:28:06 jhill
|
||||
// ca server installation
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
// CA server
|
||||
//
|
||||
#include<server.h>
|
||||
#include <casClientIL.h> // casClient inline func
|
||||
#include <task_params.h> // EPICS task priorities
|
||||
|
||||
|
||||
//
|
||||
// casStreamOS::ioBlockedSignal()
|
||||
//
|
||||
void casStreamOS::ioBlockedSignal()
|
||||
{
|
||||
printf("in casStreamOS::ioBlockedSignal() ?\n");
|
||||
}
|
||||
|
||||
//
|
||||
// casStreamOS::eventSignal()
|
||||
//
|
||||
void casStreamOS::eventSignal()
|
||||
{
|
||||
STATUS st;
|
||||
|
||||
st = semGive(this->eventSignalSem);
|
||||
assert (st==OK);
|
||||
}
|
||||
|
||||
//
|
||||
// casStreamOS::eventFlush()
|
||||
//
|
||||
void casStreamOS::eventFlush()
|
||||
{
|
||||
this->flush();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// casStreamOS::casStreamOS()
|
||||
//
|
||||
casStreamOS::casStreamOS(caServerI &cas, casMsgIO &ioIn) :
|
||||
casStrmClient(cas, ioIn),
|
||||
eventSignalSem(NULL),
|
||||
clientTId(NULL),
|
||||
eventTId(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// casStreamOS::init()
|
||||
//
|
||||
caStatus casStreamOS::init()
|
||||
{
|
||||
caStatus status;
|
||||
|
||||
this->eventSignalSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
|
||||
if (this->eventSignalSem == NULL) {
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
|
||||
//
|
||||
// init the base classes
|
||||
//
|
||||
status = this->casStrmClient::init();
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// casStreamOS::~casStreamOS()
|
||||
//
|
||||
casStreamOS::~casStreamOS()
|
||||
{
|
||||
//
|
||||
// attempt to flush out any remaining messages
|
||||
//
|
||||
this->flush();
|
||||
|
||||
if (taskIdVerify(this->clientTId)==OK &&
|
||||
this->clientTId != taskIdSelf()) {
|
||||
taskDelete(this->clientTId);
|
||||
}
|
||||
if (taskIdVerify(this->eventTId)==OK &&
|
||||
this->eventTId != taskIdSelf()) {
|
||||
taskDelete(this->eventTId);
|
||||
}
|
||||
if (this->eventSignalSem) {
|
||||
semDelete(this->eventSignalSem);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// casStreamOS::show()
|
||||
//
|
||||
void casStreamOS::show(unsigned level)
|
||||
{
|
||||
this->casStrmClient::show(level);
|
||||
printf("casStreamOS at %x\n", (unsigned) this);
|
||||
if (taskIdVerify(this->clientTId)==OK) {
|
||||
taskShow(this->clientTId, level);
|
||||
}
|
||||
if (taskIdVerify(this->eventTId)==OK) {
|
||||
printf("casStreamOS task id %x\n", this->eventTId);
|
||||
}
|
||||
if (this->eventSignalSem) {
|
||||
semShow(this->eventSignalSem, level);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// casClientStart ()
|
||||
//
|
||||
caStatus casStreamOS::start()
|
||||
{
|
||||
//
|
||||
// no (void *) vxWorks task arg
|
||||
//
|
||||
assert (sizeof(int) >= sizeof(this));
|
||||
|
||||
this->clientTId = taskSpawn(
|
||||
CA_CLIENT_NAME,
|
||||
CA_CLIENT_PRI,
|
||||
CA_CLIENT_OPT,
|
||||
CA_CLIENT_STACK,
|
||||
(FUNCPTR) casStrmServer, // get your act together wrs
|
||||
(int) this, // get your act together wrs
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
if (this->clientTId==ERROR) {
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
this->eventTId = taskSpawn(
|
||||
CA_EVENT_NAME,
|
||||
CA_CLIENT_PRI,
|
||||
CA_CLIENT_OPT,
|
||||
CA_CLIENT_STACK,
|
||||
(FUNCPTR) casStrmEvent, // get your act together wrs
|
||||
(int) this, // get your act together wrs
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
if (this->eventTId==ERROR) {
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// casStreamOS::sendBlockSignal()
|
||||
//
|
||||
void casStreamOS::sendBlockSignal()
|
||||
{
|
||||
printf("in casStreamOS::sendBlockSignal()\n");
|
||||
}
|
||||
|
||||
//
|
||||
// casStreamOS::processInput()
|
||||
//
|
||||
casProcCond casStreamOS::processInput()
|
||||
{
|
||||
caStatus status;
|
||||
|
||||
# ifdef DEBUG
|
||||
printf(
|
||||
"Resp bytes to send=%d, Req bytes pending %d\n",
|
||||
this->outBuf::bytesPresent(),
|
||||
this->inBuf::bytesPresent());
|
||||
# endif
|
||||
|
||||
status = this->processMsg();
|
||||
switch (status) {
|
||||
case S_cas_partialMessage:
|
||||
case S_cas_ioBlocked:
|
||||
case S_cas_success:
|
||||
return casProcOk;
|
||||
default:
|
||||
errMessage (status,
|
||||
"unexpected error processing client's input");
|
||||
return casProcDisconnect;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// casStrmServer()
|
||||
//
|
||||
int casStrmServer (casStreamOS *pStrmOS)
|
||||
{
|
||||
casFillCondition fillCond;
|
||||
casProcCond procCond;
|
||||
|
||||
//
|
||||
// block for the next message until the connection closes
|
||||
//
|
||||
while (TRUE) {
|
||||
//
|
||||
// copy in new messages
|
||||
//
|
||||
fillCond = pStrmOS->fill();
|
||||
procCond = pStrmOS->processInput();
|
||||
if (fillCond == casFillDisconnect ||
|
||||
procCond == casProcDisconnect) {
|
||||
delete pStrmOS;
|
||||
//
|
||||
// NO CODE HERE
|
||||
// (see delete above)
|
||||
//
|
||||
return OK;
|
||||
}
|
||||
//
|
||||
// force the output buffer to flush prior to
|
||||
// blocking for more input (if no input bytes are
|
||||
// pending)
|
||||
//
|
||||
if (pStrmOS->bytesAvailable()<=0u) {
|
||||
pStrmOS->flush();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// casStrmEvent()
|
||||
//
|
||||
int casStrmEvent(casStreamOS *pStrmOS)
|
||||
{
|
||||
STATUS status;
|
||||
casProcCond cond;
|
||||
|
||||
//
|
||||
// Wait for event queue entry
|
||||
//
|
||||
while (TRUE) {
|
||||
status = semTake(pStrmOS->eventSignalSem, WAIT_FOREVER);
|
||||
assert (status==OK);
|
||||
|
||||
cond = pStrmOS->casEventSys::process();
|
||||
if (cond != casProcOk) {
|
||||
printf("Stream event sys process failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
113
src/cas/os/vxWorks/osiMutex.h
Normal file
113
src/cas/os/vxWorks/osiMutex.h
Normal file
@@ -0,0 +1,113 @@
|
||||
|
||||
//
|
||||
// osiMutex - OS independent mutex
|
||||
// (vxWorks version)
|
||||
//
|
||||
//
|
||||
// NOTES:
|
||||
// 1) epicsPrintf() is used in this file because we cant stand
|
||||
// the logMsg() 8 arg API amd we dont want the messages from different
|
||||
// tasks to co-mingle
|
||||
//
|
||||
|
||||
#include <semLib.h>
|
||||
#include <epicsAssert.h>
|
||||
#include <epicsPrint.h>
|
||||
|
||||
|
||||
#ifdef DEBUG_OSIMUTEX
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_OSIMUTEX
|
||||
#define osiLock() osiLockI (__FILE__, __LINE__)
|
||||
#define osiUnlock() osiUnlockI (__FILE__, __LINE__)
|
||||
#endif
|
||||
|
||||
class osiMutex {
|
||||
public:
|
||||
osiMutex()
|
||||
{
|
||||
mutex = NULL;
|
||||
}
|
||||
//
|
||||
// constructor that returns status
|
||||
// (since g++ does not have exceptions)
|
||||
//
|
||||
int init ()
|
||||
{
|
||||
this->mutex = semMCreate(SEM_Q_PRIORITY|SEM_INVERSION_SAFE);
|
||||
if (this->mutex==NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
# ifdef DEBUG_OSIMUTEX
|
||||
epicsPrintf("created mutex at %lx\n",
|
||||
(unsigned long) this->mutex);
|
||||
# endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
~osiMutex()
|
||||
{
|
||||
STATUS s;
|
||||
s = semDelete (this->mutex);
|
||||
assert (s==OK);
|
||||
# ifdef DEBUG_OSIMUTEX
|
||||
epicsPrintf("destroyed mutex at %lx\n",
|
||||
(unsigned long) this->mutex);
|
||||
# endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG_OSIMUTEX
|
||||
void osiLockI(const char *pFN, unsigned ln)
|
||||
#else
|
||||
void osiLock()
|
||||
#endif
|
||||
{
|
||||
STATUS s;
|
||||
if (!this->mutex) {
|
||||
epicsPrintf(
|
||||
"osiMutex: lock request before init was ignored\n");
|
||||
return;
|
||||
}
|
||||
assert(this->mutex);
|
||||
s = semTake (this->mutex, WAIT_FOREVER);
|
||||
assert (s==OK);
|
||||
# ifdef DEBUG_OSIMUTEX
|
||||
epicsPrintf("L%lx in %s at %u\n",
|
||||
(unsigned long) this->mutex,
|
||||
pFN, ln);
|
||||
# endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG_OSIMUTEX
|
||||
void osiUnlockI(const char *pFN, unsigned ln)
|
||||
#else
|
||||
void osiUnlock()
|
||||
#endif
|
||||
{
|
||||
STATUS s;
|
||||
|
||||
if (!this->mutex) {
|
||||
epicsPrintf(
|
||||
"osiMutex: unlock request before init was ignored\n");
|
||||
return;
|
||||
}
|
||||
s = semGive (this->mutex);
|
||||
assert (s==OK);
|
||||
# ifdef DEBUG_OSIMUTEX
|
||||
epicsPrintf("U%lx in %s at %d\n",
|
||||
(unsigned long) this->mutex,
|
||||
pFN, ln);
|
||||
# endif
|
||||
}
|
||||
|
||||
void show(unsigned level)
|
||||
{
|
||||
semShow(this->mutex, (int) level);
|
||||
}
|
||||
private:
|
||||
SEM_ID mutex;
|
||||
};
|
||||
|
||||
@@ -1,659 +0,0 @@
|
||||
|
||||
/*
|
||||
*
|
||||
* vxWorks_depen.c
|
||||
* %W% %G%
|
||||
*
|
||||
* vxWorks dependent routines for the CA server
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <server.h>
|
||||
#include <inetLib.h>
|
||||
|
||||
VERSIONID(vxWorks_depenc,"%W% %G%")
|
||||
|
||||
#define MUTEX_SEM_OPTIONS \
|
||||
(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE)
|
||||
|
||||
LOCAL int event_task(
|
||||
struct event_user *evuser,
|
||||
void (*init_func)(int arg),
|
||||
int init_func_arg
|
||||
);
|
||||
|
||||
LOCAL void osDepenTimerCB(void *pciu);
|
||||
LOCAL void osDepenSendCB(void *pClient);
|
||||
int caServerTask(struct rsrv *pRsrv);
|
||||
LOCAL int caMaxFreeBlockPoll(void);
|
||||
|
||||
size_t caMaxFreeBlock;
|
||||
|
||||
###### no event flush currently (only needed in multi thread env) ####
|
||||
status = caeqAddFlushEvent (client->evuser, XXXX, client);
|
||||
assert (status==OK);
|
||||
|
||||
|
||||
/*
|
||||
* caGetElapsedTime()
|
||||
*/
|
||||
caStatus caGetElapsedTime(caElapsedTimeVal *pElapsed)
|
||||
{
|
||||
ULONG ticks;
|
||||
ULONG rate;
|
||||
|
||||
ticks = tickGet();
|
||||
rate = sysClkRateGet();
|
||||
|
||||
pElapsed->tv_sec = ticks * rate;
|
||||
pElapsed->tv_usec = ((ticks % rate)*CAServerUSecInSec)/rate;
|
||||
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caOutOfMemory()
|
||||
*/
|
||||
int caOutOfMemory(void)
|
||||
{
|
||||
int status;
|
||||
static int pollTaskStarted;
|
||||
|
||||
if(!pollTaskStarted){
|
||||
caMaxFreeBlock = memFindMax();
|
||||
status = taskSpawn(
|
||||
MAXFREEBLOCKTASKNAME,
|
||||
MAXFREEBLOCKTASKPRI,
|
||||
MAXFREEBLOCKTASKOPT,
|
||||
MAXFREEBLOCKTASKSTACK,
|
||||
caMaxFreeBlockPoll,
|
||||
0,0,0,0,0,0,0,0,0,0);
|
||||
if(status>=0){
|
||||
pollTaskStarted = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return (caMaxFreeBlock<MAX_BLOCK_THRESHOLD);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caMaxFreeBlockPoll()
|
||||
*/
|
||||
LOCAL int caMaxFreeBlockPoll(void)
|
||||
{
|
||||
while(TRUE){
|
||||
caMaxFreeBlock = memFindMax();
|
||||
taskDelay(MAXFREEBLOCKPOLL*sysClkRateGet());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casPutCBStartTimer()
|
||||
*/
|
||||
caStatus casPutCBStartTimer(
|
||||
casChanInUse *pciu,
|
||||
unsigned timeOutSec
|
||||
)
|
||||
{
|
||||
struct client *pClient = pciu->client;
|
||||
caserver *pRsrv = pClient->cc.pRsrv;
|
||||
struct timeval tv;
|
||||
|
||||
if(pClient->cc.osSpecific.pPutCBAlarm){
|
||||
tv.tv_sec = timeOutSec;
|
||||
tv.tv_usec = 0;
|
||||
pClient->cc.osSpecific.pPutCBAlarm
|
||||
= fdmgr_add_timeout(
|
||||
pRsrv->osSpecific.pfdctx,
|
||||
&tv,
|
||||
osDepenTimerCB,
|
||||
pciu);
|
||||
if(!pClient->cc.osSpecific.pPutCBAlarm){
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
}
|
||||
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* osDepenTimerCB()
|
||||
*/
|
||||
LOCAL void osDepenTimerCB(void *pParam)
|
||||
{
|
||||
casChanInUse *pciu = (casChanInUse *)pParam;
|
||||
|
||||
pciu->client->cc.osSpecific.pPutCBAlarm = NULL;
|
||||
casPutCBTimer(pciu);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casPutCBCancelTimer()
|
||||
*/
|
||||
void casPutCBCancelTimer(struct client *pClient)
|
||||
{
|
||||
caserver *pRsrv = pClient->cc.pRsrv;
|
||||
int status;
|
||||
|
||||
if(pClient->cc.osSpecific.pPutCBAlarm){
|
||||
status = fdmgr_clear_timeout(
|
||||
pRsrv->osSpecific.pfdctx,
|
||||
pClient->cc.osSpecific.pPutCBAlarm);
|
||||
assert(status==0);
|
||||
pClient->cc.osSpecific.pPutCBAlarm = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casDisableSocketRecvIOCallback()
|
||||
*/
|
||||
caStatus casDisableSocketRecvIOCallback(struct client *pClient)
|
||||
{
|
||||
int status;
|
||||
|
||||
if(pClient->cc.osSpecific.sockRecvIOCallbackEnabled){
|
||||
status = fdmgr_clear_callback(
|
||||
pClient->cc.pRsrv->osSpecific.pfdctx,
|
||||
pClient->cc.sock,
|
||||
fdi_read);
|
||||
assert(status==0);
|
||||
pClient->cc.osSpecific.sockRecvIOCallbackEnabled = FALSE;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casEnableSocketRecvIOCallback()
|
||||
*/
|
||||
caStatus casEnableSocketRecvIOCallback(struct client *pClient)
|
||||
{
|
||||
caserver *pRsrv = pClient->cc.pRsrv;
|
||||
int status;
|
||||
|
||||
if(!pClient->cc.osSpecific.sockRecvIOCallbackEnabled){
|
||||
status = fdmgr_add_callback(
|
||||
pRsrv->osSpecific.pfdctx,
|
||||
pClient->cc.sock,
|
||||
fdi_read,
|
||||
pClient->cc.pCB,
|
||||
pClient);
|
||||
if(status){
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
pClient->cc.osSpecific.sockRecvIOCallbackEnabled = TRUE;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casWaitForIO ()
|
||||
*/
|
||||
caStatus casWaitForIO (struct rsrv *pRsrv, caTime *pDelay)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = caTime->sec;
|
||||
tv.tv_usec = caTime->nsec / NSecPerUsec;
|
||||
status = fdmgr_pend_event(pRsrv->osSpecific.pfdctx, &tv);
|
||||
if (status) {
|
||||
return S_cas_internal;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casArmSocketSendIOCallback()
|
||||
*/
|
||||
caStatus casArmSocketSendIOCallback(struct client *pClient)
|
||||
{
|
||||
caserver *pRsrv = pClient->cc.pRsrv;
|
||||
int status;
|
||||
|
||||
if(!pClient->cc.osSpecific.sockSendIOCallbackEnabled){
|
||||
status = fdmgr_add_callback(
|
||||
pRsrv->osSpecific.pfdctx,
|
||||
pClient->cc.sock,
|
||||
fdi_write,
|
||||
osDepenSendCB,
|
||||
pClient);
|
||||
if(status){
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
pClient->cc.osSpecific.sockSendIOCallbackEnabled = TRUE;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casCancelSocketSendIOCallback()
|
||||
*/
|
||||
caStatus casCancelSocketSendIOCallback(struct client *pClient)
|
||||
{
|
||||
caserver *pRsrv = pClient->cc.pRsrv;
|
||||
int status;
|
||||
|
||||
if(pClient->cc.osSpecific.sockSendIOCallbackEnabled){
|
||||
status = fdmgr_clear_callback(
|
||||
pRsrv->osSpecific.pfdctx,
|
||||
pClient->cc.sock,
|
||||
fdi_write);
|
||||
assert(status==0);
|
||||
pClient->cc.osSpecific.sockSendIOCallbackEnabled = FALSE;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* osDepenSendCB()
|
||||
*/
|
||||
LOCAL void osDepenSendCB(void *pParam)
|
||||
{
|
||||
struct client *pClient = (struct client *) pParam;
|
||||
|
||||
pClient->cc.osSpecific.sockSendIOCallbackEnabled = FALSE;
|
||||
(*pClient->sendHandler)(pClient);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casOSSpecificDelete()
|
||||
*/
|
||||
void casOSSpecificDelete(struct rsrv *pRsrv)
|
||||
{
|
||||
int status;
|
||||
|
||||
if(taskIdVerify(pRsrv->osSpecific.selectTask) == OK){
|
||||
taskwdRemove(taskDelete(pRsrv->osSpecific.selectTask));
|
||||
taskDelete(pRsrv->osSpecific.selectTask);
|
||||
}
|
||||
if(pRsrv->osSpecific.clientQLock){
|
||||
status = semDelete(pRsrv->osSpecific.clientQLock);
|
||||
assert(status==OK);
|
||||
}
|
||||
if(pRsrv->osSpecific.freeChanQLock){
|
||||
status = semDelete(pRsrv->osSpecific.freeChanQLock);
|
||||
assert(status==OK);
|
||||
}
|
||||
if(pRsrv->osSpecific.freeEventQLock){
|
||||
status = semDelete(pRsrv->osSpecific.freeEventQLock);
|
||||
assert(status==OK);
|
||||
}
|
||||
if(pRsrv->osSpecific.pvQLock){
|
||||
status = semDelete(pRsrv->osSpecific.pvQLock);
|
||||
assert(status==OK);
|
||||
}
|
||||
if(pRsrv->osSpecific.pfdctx){
|
||||
status = fdmgr_delete(pRsrv->osSpecific.pfdctx);
|
||||
assert(status==OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casOSSpecificInit()
|
||||
*/
|
||||
caStatus casOSSpecificInit(struct rsrv *pRsrv)
|
||||
{
|
||||
pRsrv->osSpecific.clientQLock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!pRsrv->osSpecific.clientQLock){
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
pRsrv->osSpecific.freeChanQLock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!pRsrv->osSpecific.freeChanQLock){
|
||||
casOSSpecificDelete(pRsrv);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
pRsrv->osSpecific.freeEventQLock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!pRsrv->osSpecific.freeEventQLock){
|
||||
casOSSpecificDelete(pRsrv);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
pRsrv->osSpecific.pvQLock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!pRsrv->osSpecific.pvQLock){
|
||||
casOSSpecificDelete(pRsrv);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
pRsrv->osSpecific.pfdctx = fdmgr_init();
|
||||
if(!pRsrv->osSpecific.pfdctx){
|
||||
casOSSpecificDelete(pRsrv);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casOSSpecificStartServer()
|
||||
*/
|
||||
caStatus casOSSpecificStartServer(caserver *pRsrv)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = fdmgr_add_callback(
|
||||
pRsrv->osSpecific.pfdctx,
|
||||
pRsrv->server_sock,
|
||||
fdi_read,
|
||||
rsrv_connect,
|
||||
pRsrv);
|
||||
if(status < 0){
|
||||
casOSSpecificDelete(pRsrv);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
|
||||
status = taskSpawn(
|
||||
REQ_SRVR_NAME,
|
||||
REQ_SRVR_PRI,
|
||||
REQ_SRVR_OPT,
|
||||
RSP_SRVR_STACK,
|
||||
caServerTask,
|
||||
(int)pRsrv,
|
||||
0,0,0,0,0,0,0,0,0);
|
||||
if(status == ERROR){
|
||||
casOSSpecificDelete(pRsrv);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
pRsrv->osSpecific.selectTask = status;
|
||||
|
||||
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caServerTask()
|
||||
*/
|
||||
int caServerTask(caserver *pRsrv)
|
||||
{
|
||||
struct timeval tv;
|
||||
caTime delay;
|
||||
struct client *pClient;
|
||||
int nchars;
|
||||
int status;
|
||||
|
||||
taskwdInsert((int)taskIdCurrent,NULL,NULL);
|
||||
|
||||
while(TRUE){
|
||||
|
||||
delay.sec = 100;
|
||||
delay.usec = 0;
|
||||
status = caServerProcess (pRsrv, &delay);
|
||||
assert (status == S_cas_success);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casSchedualBeacon()
|
||||
*/
|
||||
void casSchedualBeacon(struct rsrv *pRsrv)
|
||||
{
|
||||
fdmgrAlarm *tmp;
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = pRsrv->delayToNextBeacon.tv_sec;
|
||||
tv.tv_usec = pRsrv->delayToNextBeacon.tv_usec;
|
||||
tmp = fdmgr_add_timeout(
|
||||
pRsrv->osSpecific.pfdctx,
|
||||
&tv,
|
||||
casSendBeacon,
|
||||
pRsrv);
|
||||
if(!tmp){
|
||||
ca_printf("CAS: Unable to keep beacon going\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casOSSpecificClientInit()
|
||||
*/
|
||||
caStatus casOSSpecificClientInit(struct client *client)
|
||||
{
|
||||
client->cc.osSpecific.eventQLock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!client->cc.osSpecific.eventQLock){
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
client->cc.osSpecific.chanQLock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!client->cc.osSpecific.chanQLock){
|
||||
casOSSpecificClientDelete(client);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
client->cc.osSpecific.putNotifyLock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!client->cc.osSpecific.putNotifyLock){
|
||||
casOSSpecificClientDelete(client);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
client->cc.osSpecific.lock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!client->cc.osSpecific.lock){
|
||||
casOSSpecificClientDelete(client);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
client->cc.osSpecific.accessRightsQLock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!client->cc.osSpecific.accessRightsQLock){
|
||||
casOSSpecificClientDelete(client);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casOSSpecificClientDelete()
|
||||
*/
|
||||
void casOSSpecificClientDelete(struct client *client)
|
||||
{
|
||||
int status;
|
||||
|
||||
if(client->cc.osSpecific.eventQLock){
|
||||
status = semDelete(client->cc.osSpecific.eventQLock);
|
||||
assert(status==OK);
|
||||
}
|
||||
if(client->cc.osSpecific.chanQLock){
|
||||
status = semDelete(client->cc.osSpecific.chanQLock);
|
||||
assert(status==OK);
|
||||
}
|
||||
if(client->cc.osSpecific.putNotifyLock){
|
||||
status = semDelete(client->cc.osSpecific.putNotifyLock);
|
||||
assert(status==OK);
|
||||
}
|
||||
if(client->cc.osSpecific.lock){
|
||||
status = semDelete(client->cc.osSpecific.lock);
|
||||
assert(status==OK);
|
||||
}
|
||||
if(client->cc.osSpecific.accessRightsQLock){
|
||||
status = semDelete(client->cc.osSpecific.accessRightsQLock);
|
||||
assert(status==OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caeqOSSpecificInit()
|
||||
*/
|
||||
caStatus caeqOSSpecificInit(caEventUser *evuser)
|
||||
{
|
||||
evuser->osSpecific.lock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!evuser->osSpecific.lock){
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
|
||||
evuser->osSpecific.ppendsem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
|
||||
if(!evuser->osSpecific.ppendsem){
|
||||
semDelete(evuser->osSpecific.lock);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caeqOSSpecificDelete()
|
||||
*/
|
||||
void caeqOSSpecificDelete(caEventUser *evuser)
|
||||
{
|
||||
int status;
|
||||
|
||||
if(taskIdVerify(evuser->osSpecific.taskid)==OK){
|
||||
taskwdRemove(evuser->osSpecific.taskid);
|
||||
taskDelete(evuser->osSpecific.taskid);
|
||||
}
|
||||
status = semDelete(evuser->osSpecific.lock);
|
||||
assert(status == OK);
|
||||
status = semDelete(evuser->osSpecific.ppendsem);
|
||||
assert(status == OK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caeqOSSpecificPVInit ()
|
||||
*/
|
||||
caStatus caeqOSSpecificPVInit (casPVInUse *pPV)
|
||||
{
|
||||
pPV->osSpecific.lock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if (!pPV->osSpecific.lock) {
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caeqOSSpecificPVDelete ()
|
||||
*/
|
||||
void caeqOSSpecificPVDelete (casPVInUse *pPV)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = semDelete (pPV->osSpecific.lock);
|
||||
assert (status == OK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caeqOSSpecificEventNotify()
|
||||
*/
|
||||
void caeqOSSpecificEventNotify(caEventUser *evuser)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = semGive(evuser->osSpecific.ppendsem);
|
||||
assert(status == OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* caeqStartEvents()
|
||||
*/
|
||||
int caeqStartEvents(
|
||||
struct event_user *evuser,
|
||||
char *taskname, /* defaulted if NULL */
|
||||
void (*init_func)(),
|
||||
int init_func_arg,
|
||||
int priority_offset
|
||||
)
|
||||
{
|
||||
int status;
|
||||
int taskpri;
|
||||
|
||||
/* only one ca_pend_event thread may be started for each evuser ! */
|
||||
while(!vxTas(&evuser->osSpecific.pendlck))
|
||||
return ERROR;
|
||||
|
||||
status = taskPriorityGet(taskIdSelf(), &taskpri);
|
||||
if(status == ERROR){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
taskpri += priority_offset;
|
||||
|
||||
|
||||
if(!taskname){
|
||||
taskname = EVENT_PEND_NAME;
|
||||
}
|
||||
|
||||
status = taskSpawn(
|
||||
taskname,
|
||||
taskpri,
|
||||
EVENT_PEND_OPT,
|
||||
EVENT_PEND_STACK,
|
||||
event_task,
|
||||
(int)evuser,
|
||||
(int)init_func,
|
||||
(int)init_func_arg,
|
||||
0,0,0,0,0,0,0);
|
||||
if(status == ERROR){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
evuser->osSpecific.taskid = status;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* EVENT_TASK()
|
||||
*/
|
||||
LOCAL int event_task(
|
||||
struct event_user *evuser,
|
||||
void (*init_func)(int init_func_arg),
|
||||
int init_func_arg
|
||||
)
|
||||
{
|
||||
int status;
|
||||
|
||||
taskwdInsert((int)taskIdCurrent,NULL,NULL);
|
||||
|
||||
/* init hook */
|
||||
if(init_func){
|
||||
(*init_func)(init_func_arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* No need to lock getix as I only allow one thread to call this
|
||||
* routine at a time
|
||||
*/
|
||||
while(TRUE){
|
||||
caeqEventProcess(evuser);
|
||||
status = semTake(evuser->osSpecific.ppendsem, WAIT_FOREVER);
|
||||
assert(status == OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caeqOSSpecificClose()
|
||||
*/
|
||||
void caeqOSSpecificClose(caEventUser *pEvUser)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* asciiIPAddr
|
||||
*/
|
||||
void asciiIPAddr (struct in_addr addr, char *pBuf, unsigned bufSize)
|
||||
{
|
||||
char pName[INET_ADDR_LEN];
|
||||
|
||||
inet_ntoa_b (addr, pName);
|
||||
|
||||
strncpy (pBuf, pName, bufSize);
|
||||
pBuf[bufSize-1] = '\0';
|
||||
}
|
||||
|
||||
@@ -1,659 +0,0 @@
|
||||
|
||||
/*
|
||||
*
|
||||
* vxWorks_depen.c
|
||||
* %W% %G%
|
||||
*
|
||||
* vxWorks dependent routines for the CA server
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include<casdef.h>
|
||||
#include <inetLib.h>
|
||||
|
||||
VERSIONID(vxWorks_depenc,"%W% %G%")
|
||||
|
||||
#define MUTEX_SEM_OPTIONS \
|
||||
(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE)
|
||||
|
||||
LOCAL int event_task(
|
||||
struct event_user *evuser,
|
||||
void (*init_func)(int arg),
|
||||
int init_func_arg
|
||||
);
|
||||
|
||||
LOCAL void osDepenTimerCB(void *pciu);
|
||||
LOCAL void osDepenSendCB(void *pClient);
|
||||
int caServerTask(struct rsrv *pRsrv);
|
||||
LOCAL int caMaxFreeBlockPoll(void);
|
||||
|
||||
size_t caMaxFreeBlock;
|
||||
|
||||
###### no event flush currently (only needed in multi thread env) ####
|
||||
status = caeqAddFlushEvent (client->evuser, XXXX, client);
|
||||
assert (status==OK);
|
||||
|
||||
|
||||
/*
|
||||
* caGetElapsedTime()
|
||||
*/
|
||||
caStatus caGetElapsedTime(caElapsedTimeVal *pElapsed)
|
||||
{
|
||||
ULONG ticks;
|
||||
ULONG rate;
|
||||
|
||||
ticks = tickGet();
|
||||
rate = sysClkRateGet();
|
||||
|
||||
pElapsed->tv_sec = ticks * rate;
|
||||
pElapsed->tv_usec = ((ticks % rate)*CAServerUSecInSec)/rate;
|
||||
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caOutOfMemory()
|
||||
*/
|
||||
int caOutOfMemory(void)
|
||||
{
|
||||
int status;
|
||||
static int pollTaskStarted;
|
||||
|
||||
if(!pollTaskStarted){
|
||||
caMaxFreeBlock = memFindMax();
|
||||
status = taskSpawn(
|
||||
MAXFREEBLOCKTASKNAME,
|
||||
MAXFREEBLOCKTASKPRI,
|
||||
MAXFREEBLOCKTASKOPT,
|
||||
MAXFREEBLOCKTASKSTACK,
|
||||
caMaxFreeBlockPoll,
|
||||
0,0,0,0,0,0,0,0,0,0);
|
||||
if(status>=0){
|
||||
pollTaskStarted = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return (caMaxFreeBlock<MAX_BLOCK_THRESHOLD);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caMaxFreeBlockPoll()
|
||||
*/
|
||||
LOCAL int caMaxFreeBlockPoll(void)
|
||||
{
|
||||
while(TRUE){
|
||||
caMaxFreeBlock = memFindMax();
|
||||
taskDelay(MAXFREEBLOCKPOLL*sysClkRateGet());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casPutCBStartTimer()
|
||||
*/
|
||||
caStatus casPutCBStartTimer(
|
||||
casChanInUse *pciu,
|
||||
unsigned timeOutSec
|
||||
)
|
||||
{
|
||||
struct client *pClient = pciu->client;
|
||||
caserver *pRsrv = pClient->cc.pRsrv;
|
||||
struct timeval tv;
|
||||
|
||||
if(pClient->cc.osSpecific.pPutCBAlarm){
|
||||
tv.tv_sec = timeOutSec;
|
||||
tv.tv_usec = 0;
|
||||
pClient->cc.osSpecific.pPutCBAlarm
|
||||
= fdmgr_add_timeout(
|
||||
pRsrv->osSpecific.pfdctx,
|
||||
&tv,
|
||||
osDepenTimerCB,
|
||||
pciu);
|
||||
if(!pClient->cc.osSpecific.pPutCBAlarm){
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
}
|
||||
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* osDepenTimerCB()
|
||||
*/
|
||||
LOCAL void osDepenTimerCB(void *pParam)
|
||||
{
|
||||
casChanInUse *pciu = (casChanInUse *)pParam;
|
||||
|
||||
pciu->client->cc.osSpecific.pPutCBAlarm = NULL;
|
||||
casPutCBTimer(pciu);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casPutCBCancelTimer()
|
||||
*/
|
||||
void casPutCBCancelTimer(struct client *pClient)
|
||||
{
|
||||
caserver *pRsrv = pClient->cc.pRsrv;
|
||||
int status;
|
||||
|
||||
if(pClient->cc.osSpecific.pPutCBAlarm){
|
||||
status = fdmgr_clear_timeout(
|
||||
pRsrv->osSpecific.pfdctx,
|
||||
pClient->cc.osSpecific.pPutCBAlarm);
|
||||
assert(status==0);
|
||||
pClient->cc.osSpecific.pPutCBAlarm = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casDisableSocketRecvIOCallback()
|
||||
*/
|
||||
caStatus casDisableSocketRecvIOCallback(struct client *pClient)
|
||||
{
|
||||
int status;
|
||||
|
||||
if(pClient->cc.osSpecific.sockRecvIOCallbackEnabled){
|
||||
status = fdmgr_clear_callback(
|
||||
pClient->cc.pRsrv->osSpecific.pfdctx,
|
||||
pClient->cc.sock,
|
||||
fdi_read);
|
||||
assert(status==0);
|
||||
pClient->cc.osSpecific.sockRecvIOCallbackEnabled = FALSE;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casEnableSocketRecvIOCallback()
|
||||
*/
|
||||
caStatus casEnableSocketRecvIOCallback(struct client *pClient)
|
||||
{
|
||||
caserver *pRsrv = pClient->cc.pRsrv;
|
||||
int status;
|
||||
|
||||
if(!pClient->cc.osSpecific.sockRecvIOCallbackEnabled){
|
||||
status = fdmgr_add_callback(
|
||||
pRsrv->osSpecific.pfdctx,
|
||||
pClient->cc.sock,
|
||||
fdi_read,
|
||||
pClient->cc.pCB,
|
||||
pClient);
|
||||
if(status){
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
pClient->cc.osSpecific.sockRecvIOCallbackEnabled = TRUE;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casWaitForIO ()
|
||||
*/
|
||||
caStatus casWaitForIO (struct rsrv *pRsrv, caTime *pDelay)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = caTime->sec;
|
||||
tv.tv_usec = caTime->nsec / NSecPerUsec;
|
||||
status = fdmgr_pend_event(pRsrv->osSpecific.pfdctx, &tv);
|
||||
if (status) {
|
||||
return S_cas_internal;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casArmSocketSendIOCallback()
|
||||
*/
|
||||
caStatus casArmSocketSendIOCallback(struct client *pClient)
|
||||
{
|
||||
caserver *pRsrv = pClient->cc.pRsrv;
|
||||
int status;
|
||||
|
||||
if(!pClient->cc.osSpecific.sockSendIOCallbackEnabled){
|
||||
status = fdmgr_add_callback(
|
||||
pRsrv->osSpecific.pfdctx,
|
||||
pClient->cc.sock,
|
||||
fdi_write,
|
||||
osDepenSendCB,
|
||||
pClient);
|
||||
if(status){
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
pClient->cc.osSpecific.sockSendIOCallbackEnabled = TRUE;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casCancelSocketSendIOCallback()
|
||||
*/
|
||||
caStatus casCancelSocketSendIOCallback(struct client *pClient)
|
||||
{
|
||||
caserver *pRsrv = pClient->cc.pRsrv;
|
||||
int status;
|
||||
|
||||
if(pClient->cc.osSpecific.sockSendIOCallbackEnabled){
|
||||
status = fdmgr_clear_callback(
|
||||
pRsrv->osSpecific.pfdctx,
|
||||
pClient->cc.sock,
|
||||
fdi_write);
|
||||
assert(status==0);
|
||||
pClient->cc.osSpecific.sockSendIOCallbackEnabled = FALSE;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* osDepenSendCB()
|
||||
*/
|
||||
LOCAL void osDepenSendCB(void *pParam)
|
||||
{
|
||||
struct client *pClient = (struct client *) pParam;
|
||||
|
||||
pClient->cc.osSpecific.sockSendIOCallbackEnabled = FALSE;
|
||||
(*pClient->sendHandler)(pClient);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casOSSpecificDelete()
|
||||
*/
|
||||
void casOSSpecificDelete(struct rsrv *pRsrv)
|
||||
{
|
||||
int status;
|
||||
|
||||
if(taskIdVerify(pRsrv->osSpecific.selectTask) == OK){
|
||||
taskwdRemove(taskDelete(pRsrv->osSpecific.selectTask));
|
||||
taskDelete(pRsrv->osSpecific.selectTask);
|
||||
}
|
||||
if(pRsrv->osSpecific.clientQLock){
|
||||
status = semDelete(pRsrv->osSpecific.clientQLock);
|
||||
assert(status==OK);
|
||||
}
|
||||
if(pRsrv->osSpecific.freeChanQLock){
|
||||
status = semDelete(pRsrv->osSpecific.freeChanQLock);
|
||||
assert(status==OK);
|
||||
}
|
||||
if(pRsrv->osSpecific.freeEventQLock){
|
||||
status = semDelete(pRsrv->osSpecific.freeEventQLock);
|
||||
assert(status==OK);
|
||||
}
|
||||
if(pRsrv->osSpecific.pvQLock){
|
||||
status = semDelete(pRsrv->osSpecific.pvQLock);
|
||||
assert(status==OK);
|
||||
}
|
||||
if(pRsrv->osSpecific.pfdctx){
|
||||
status = fdmgr_delete(pRsrv->osSpecific.pfdctx);
|
||||
assert(status==OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casOSSpecificInit()
|
||||
*/
|
||||
caStatus casOSSpecificInit(struct rsrv *pRsrv)
|
||||
{
|
||||
pRsrv->osSpecific.clientQLock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!pRsrv->osSpecific.clientQLock){
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
pRsrv->osSpecific.freeChanQLock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!pRsrv->osSpecific.freeChanQLock){
|
||||
casOSSpecificDelete(pRsrv);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
pRsrv->osSpecific.freeEventQLock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!pRsrv->osSpecific.freeEventQLock){
|
||||
casOSSpecificDelete(pRsrv);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
pRsrv->osSpecific.pvQLock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!pRsrv->osSpecific.pvQLock){
|
||||
casOSSpecificDelete(pRsrv);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
pRsrv->osSpecific.pfdctx = fdmgr_init();
|
||||
if(!pRsrv->osSpecific.pfdctx){
|
||||
casOSSpecificDelete(pRsrv);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casOSSpecificStartServer()
|
||||
*/
|
||||
caStatus casOSSpecificStartServer(caserver *pRsrv)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = fdmgr_add_callback(
|
||||
pRsrv->osSpecific.pfdctx,
|
||||
pRsrv->server_sock,
|
||||
fdi_read,
|
||||
rsrv_connect,
|
||||
pRsrv);
|
||||
if(status < 0){
|
||||
casOSSpecificDelete(pRsrv);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
|
||||
status = taskSpawn(
|
||||
REQ_SRVR_NAME,
|
||||
REQ_SRVR_PRI,
|
||||
REQ_SRVR_OPT,
|
||||
RSP_SRVR_STACK,
|
||||
caServerTask,
|
||||
(int)pRsrv,
|
||||
0,0,0,0,0,0,0,0,0);
|
||||
if(status == ERROR){
|
||||
casOSSpecificDelete(pRsrv);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
pRsrv->osSpecific.selectTask = status;
|
||||
|
||||
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caServerTask()
|
||||
*/
|
||||
int caServerTask(caserver *pRsrv)
|
||||
{
|
||||
struct timeval tv;
|
||||
caTime delay;
|
||||
struct client *pClient;
|
||||
int nchars;
|
||||
int status;
|
||||
|
||||
taskwdInsert((int)taskIdCurrent,NULL,NULL);
|
||||
|
||||
while(TRUE){
|
||||
|
||||
delay.sec = 100;
|
||||
delay.usec = 0;
|
||||
status = caServerProcess (pRsrv, &delay);
|
||||
assert (status == S_cas_success);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casSchedualBeacon()
|
||||
*/
|
||||
void casSchedualBeacon(struct rsrv *pRsrv)
|
||||
{
|
||||
fdmgrAlarm *tmp;
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = pRsrv->delayToNextBeacon.tv_sec;
|
||||
tv.tv_usec = pRsrv->delayToNextBeacon.tv_usec;
|
||||
tmp = fdmgr_add_timeout(
|
||||
pRsrv->osSpecific.pfdctx,
|
||||
&tv,
|
||||
casSendBeacon,
|
||||
pRsrv);
|
||||
if(!tmp){
|
||||
ca_printf("CAS: Unable to keep beacon going\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casOSSpecificClientInit()
|
||||
*/
|
||||
caStatus casOSSpecificClientInit(struct client *client)
|
||||
{
|
||||
client->cc.osSpecific.eventQLock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!client->cc.osSpecific.eventQLock){
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
client->cc.osSpecific.chanQLock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!client->cc.osSpecific.chanQLock){
|
||||
casOSSpecificClientDelete(client);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
client->cc.osSpecific.putNotifyLock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!client->cc.osSpecific.putNotifyLock){
|
||||
casOSSpecificClientDelete(client);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
client->cc.osSpecific.lock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!client->cc.osSpecific.lock){
|
||||
casOSSpecificClientDelete(client);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
client->cc.osSpecific.accessRightsQLock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!client->cc.osSpecific.accessRightsQLock){
|
||||
casOSSpecificClientDelete(client);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* casOSSpecificClientDelete()
|
||||
*/
|
||||
void casOSSpecificClientDelete(struct client *client)
|
||||
{
|
||||
int status;
|
||||
|
||||
if(client->cc.osSpecific.eventQLock){
|
||||
status = semDelete(client->cc.osSpecific.eventQLock);
|
||||
assert(status==OK);
|
||||
}
|
||||
if(client->cc.osSpecific.chanQLock){
|
||||
status = semDelete(client->cc.osSpecific.chanQLock);
|
||||
assert(status==OK);
|
||||
}
|
||||
if(client->cc.osSpecific.putNotifyLock){
|
||||
status = semDelete(client->cc.osSpecific.putNotifyLock);
|
||||
assert(status==OK);
|
||||
}
|
||||
if(client->cc.osSpecific.lock){
|
||||
status = semDelete(client->cc.osSpecific.lock);
|
||||
assert(status==OK);
|
||||
}
|
||||
if(client->cc.osSpecific.accessRightsQLock){
|
||||
status = semDelete(client->cc.osSpecific.accessRightsQLock);
|
||||
assert(status==OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caeqOSSpecificInit()
|
||||
*/
|
||||
caStatus caeqOSSpecificInit(caEventUser *evuser)
|
||||
{
|
||||
evuser->osSpecific.lock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if(!evuser->osSpecific.lock){
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
|
||||
evuser->osSpecific.ppendsem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
|
||||
if(!evuser->osSpecific.ppendsem){
|
||||
semDelete(evuser->osSpecific.lock);
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caeqOSSpecificDelete()
|
||||
*/
|
||||
void caeqOSSpecificDelete(caEventUser *evuser)
|
||||
{
|
||||
int status;
|
||||
|
||||
if(taskIdVerify(evuser->osSpecific.taskid)==OK){
|
||||
taskwdRemove(evuser->osSpecific.taskid);
|
||||
taskDelete(evuser->osSpecific.taskid);
|
||||
}
|
||||
status = semDelete(evuser->osSpecific.lock);
|
||||
assert(status == OK);
|
||||
status = semDelete(evuser->osSpecific.ppendsem);
|
||||
assert(status == OK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caeqOSSpecificPVInit ()
|
||||
*/
|
||||
caStatus caeqOSSpecificPVInit (casPVInUse *pPV)
|
||||
{
|
||||
pPV->osSpecific.lock = semMCreate(MUTEX_SEM_OPTIONS);
|
||||
if (!pPV->osSpecific.lock) {
|
||||
return S_cas_noMemory;
|
||||
}
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caeqOSSpecificPVDelete ()
|
||||
*/
|
||||
void caeqOSSpecificPVDelete (casPVInUse *pPV)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = semDelete (pPV->osSpecific.lock);
|
||||
assert (status == OK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caeqOSSpecificEventNotify()
|
||||
*/
|
||||
void caeqOSSpecificEventNotify(caEventUser *evuser)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = semGive(evuser->osSpecific.ppendsem);
|
||||
assert(status == OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* caeqStartEvents()
|
||||
*/
|
||||
int caeqStartEvents(
|
||||
struct event_user *evuser,
|
||||
char *taskname, /* defaulted if NULL */
|
||||
void (*init_func)(),
|
||||
int init_func_arg,
|
||||
int priority_offset
|
||||
)
|
||||
{
|
||||
int status;
|
||||
int taskpri;
|
||||
|
||||
/* only one ca_pend_event thread may be started for each evuser ! */
|
||||
while(!vxTas(&evuser->osSpecific.pendlck))
|
||||
return ERROR;
|
||||
|
||||
status = taskPriorityGet(taskIdSelf(), &taskpri);
|
||||
if(status == ERROR){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
taskpri += priority_offset;
|
||||
|
||||
|
||||
if(!taskname){
|
||||
taskname = EVENT_PEND_NAME;
|
||||
}
|
||||
|
||||
status = taskSpawn(
|
||||
taskname,
|
||||
taskpri,
|
||||
EVENT_PEND_OPT,
|
||||
EVENT_PEND_STACK,
|
||||
event_task,
|
||||
(int)evuser,
|
||||
(int)init_func,
|
||||
(int)init_func_arg,
|
||||
0,0,0,0,0,0,0);
|
||||
if(status == ERROR){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
evuser->osSpecific.taskid = status;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* EVENT_TASK()
|
||||
*/
|
||||
LOCAL int event_task(
|
||||
struct event_user *evuser,
|
||||
void (*init_func)(int init_func_arg),
|
||||
int init_func_arg
|
||||
)
|
||||
{
|
||||
int status;
|
||||
|
||||
taskwdInsert((int)taskIdCurrent,NULL,NULL);
|
||||
|
||||
/* init hook */
|
||||
if(init_func){
|
||||
(*init_func)(init_func_arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* No need to lock getix as I only allow one thread to call this
|
||||
* routine at a time
|
||||
*/
|
||||
while(TRUE){
|
||||
caeqEventProcess(evuser);
|
||||
status = semTake(evuser->osSpecific.ppendsem, WAIT_FOREVER);
|
||||
assert(status == OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caeqOSSpecificClose()
|
||||
*/
|
||||
void caeqOSSpecificClose(caEventUser *pEvUser)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* asciiIPAddr
|
||||
*/
|
||||
void asciiIPAddr (struct in_addr addr, char *pBuf, unsigned bufSize)
|
||||
{
|
||||
char pName[INET_ADDR_LEN];
|
||||
|
||||
inet_ntoa_b (addr, pName);
|
||||
|
||||
strncpy (pBuf, pName, bufSize);
|
||||
pBuf[bufSize-1] = '\0';
|
||||
}
|
||||
|
||||
@@ -1,256 +0,0 @@
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <taskLib.h>
|
||||
#include <errnoLib.h>
|
||||
#include <logLib.h>
|
||||
#include <tickLib.h>
|
||||
#include <sysLib.h>
|
||||
#include <vxLib.h>
|
||||
#include <ioLib.h>
|
||||
#include <usrLib.h>
|
||||
#include <semLib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sockLib.h> /* for sendto() setsockopt() etc */
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
/*
|
||||
* EPICS on vxWorks
|
||||
*/
|
||||
#include <task_params.h>
|
||||
#include <taskwd.h>
|
||||
#include <fdmgr.h>
|
||||
|
||||
extern size_t caMaxFreeBlock;
|
||||
#define MAXFREEBLOCKPOLL 5 /* sec */
|
||||
#define MAXFREEBLOCKTASKNAME "caMemPoll"
|
||||
#define MAXFREEBLOCKTASKPRI 255
|
||||
#define MAXFREEBLOCKTASKOPT (VX_FP_TASK)
|
||||
#define MAXFREEBLOCKTASKSTACK 4095
|
||||
|
||||
/*
|
||||
* per server locks
|
||||
* ================
|
||||
*/
|
||||
#define LOCK_CLIENTQ(PRSRV) \
|
||||
{ \
|
||||
int status; \
|
||||
status = semTake((PRSRV)->osSpecific.clientQLock, WAIT_FOREVER); \
|
||||
assert(status==OK); \
|
||||
}
|
||||
|
||||
#define UNLOCK_CLIENTQ(PRSRV) \
|
||||
{ \
|
||||
int status; \
|
||||
status = semGive((PRSRV)->osSpecific.clientQLock); \
|
||||
assert(status==OK); \
|
||||
}
|
||||
|
||||
#define LOCK_FREE_CHAN_Q(PRSRV) \
|
||||
{\
|
||||
int status;\
|
||||
status = semTake((PRSRV)->osSpecific.freeChanQLock, WAIT_FOREVER);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
#define UNLOCK_FREE_CHAN_Q(PRSRV) \
|
||||
{ \
|
||||
int status;\
|
||||
status = semGive((PRSRV)->osSpecific.freeChanQLock);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
#define LOCK_FREE_EVENT_Q(PRSRV) \
|
||||
{\
|
||||
int status;\
|
||||
status = semTake((PRSRV)->osSpecific.freeEventQLock, WAIT_FOREVER);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
#define UNLOCK_FREE_EVENT_Q(PRSRV) \
|
||||
{ \
|
||||
int status;\
|
||||
status = semGive((PRSRV)->osSpecific.freeEventQLock);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
#define LOCK_PVQ(PRSRV) \
|
||||
{ \
|
||||
int status; \
|
||||
status = semTake((PRSRV)->osSpecific.pvQLock, WAIT_FOREVER); \
|
||||
assert(status==OK); \
|
||||
}
|
||||
|
||||
#define UNLOCK_PVQ(PRSRV) \
|
||||
{ \
|
||||
int status;\
|
||||
status = semGive((PRSRV)->osSpecific.pvQLock);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
/*
|
||||
* per client locks
|
||||
* ================
|
||||
*/
|
||||
#define SEND_LOCK(CLIENT) \
|
||||
{\
|
||||
int status;\
|
||||
status = semTake((CLIENT)->cc.osSpecific.lock, WAIT_FOREVER);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
#define SEND_UNLOCK(CLIENT) \
|
||||
{ \
|
||||
int status;\
|
||||
status = semGive((CLIENT)->cc.osSpecific.lock);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
#define LOCK_CHAN_Q(PCLIENT) \
|
||||
{\
|
||||
int status;\
|
||||
status = semTake((PCLIENT)->cc.osSpecific.chanQLock, WAIT_FOREVER);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
#define UNLOCK_CHAN_Q(PCLIENT) \
|
||||
{ \
|
||||
int status;\
|
||||
status = semGive((PCLIENT)->cc.osSpecific.chanQLock);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
#define LOCK_EVENT_Q(PCLIENT) \
|
||||
{\
|
||||
int status;\
|
||||
status = semTake((PCLIENT)->cc.osSpecific.eventQLock, WAIT_FOREVER);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
#define UNLOCK_EVENT_Q(PCLIENT) \
|
||||
{ \
|
||||
int status;\
|
||||
status = semGive((PCLIENT)->cc.osSpecific.eventQLock);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
#define LOCK_PUT_NOTIFY(PCLIENT) \
|
||||
{\
|
||||
int status;\
|
||||
status = semTake((PCLIENT)->cc.osSpecific.putNotifyLock, WAIT_FOREVER);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
#define UNLOCK_PUT_NOTIFY(PCLIENT) \
|
||||
{ \
|
||||
int status;\
|
||||
status = semGive((PCLIENT)->cc.osSpecific.putNotifyLock);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
#define LOCK_ACCESS_RIGHTS_Q(PCLIENT) \
|
||||
{\
|
||||
int status;\
|
||||
status = semTake((PCLIENT)->cc.osSpecific.accessRightsQLock, \
|
||||
WAIT_FOREVER);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
#define UNLOCK_ACCESS_RIGHTS_Q(PCLIENT) \
|
||||
{ \
|
||||
int status;\
|
||||
status = semGive((PCLIENT)->cc.osSpecific.accessRightsQLock);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* event system locks
|
||||
* ==================
|
||||
*/
|
||||
#define CA_EVENT_LOCK(PEVUSER) \
|
||||
{ \
|
||||
int status;\
|
||||
status = semTake((PEVUSER)->osSpecific.lock, WAIT_FOREVER);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
#define CA_EVENT_UNLOCK(PEVUSER) \
|
||||
{ \
|
||||
int status;\
|
||||
status = semGive((PEVUSER)->osSpecific.lock);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
#define LOCK_PV(PPV) \
|
||||
{ \
|
||||
int status;\
|
||||
status = semTake((PPV)->osSpecific.lock, WAIT_FOREVER);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
#define UNLOCK_PV(PPV) \
|
||||
{ \
|
||||
int status;\
|
||||
status = semGive((PPV)->osSpecific.lock);\
|
||||
assert(status==OK);\
|
||||
}
|
||||
|
||||
/*
|
||||
* vxWorks specific addition to event_user struct
|
||||
*/
|
||||
typedef struct {
|
||||
SEM_ID lock;
|
||||
SEM_ID ppendsem;
|
||||
int taskid;
|
||||
char pendlck;
|
||||
}caeqOsSpecific;
|
||||
|
||||
typedef struct {
|
||||
SEM_ID lock;
|
||||
}caPVOsSpecific;
|
||||
|
||||
|
||||
/*
|
||||
* vxWorks specific addition to rsrv struct
|
||||
*/
|
||||
typedef struct {
|
||||
fdctx *pfdctx;
|
||||
SEM_ID clientQLock;
|
||||
SEM_ID pvQLock;
|
||||
SEM_ID freeChanQLock;
|
||||
SEM_ID freeEventQLock;
|
||||
int selectTask;
|
||||
}rsrvOsSpecific;
|
||||
|
||||
/*
|
||||
* vxWorks specific addition to client struct
|
||||
*/
|
||||
typedef struct {
|
||||
SEM_ID lock;
|
||||
SEM_ID putNotifyLock;
|
||||
SEM_ID chanQLock;
|
||||
SEM_ID eventQLock;
|
||||
SEM_ID accessRightsQLock;
|
||||
fdmgrAlarm *pPutCBAlarm;
|
||||
unsigned sockSendIOCallbackEnabled:1;
|
||||
unsigned sockRecvIOCallbackEnabled:1;
|
||||
}clientOsSpecific;
|
||||
|
||||
typedef int SOCKET;
|
||||
|
||||
#define SOCKERRNO errno
|
||||
|
||||
#define socket_close(S) close(S)
|
||||
/* vxWorks still has brain dead func proto for ioctl() */
|
||||
#define socket_ioctl(A,B,C) ioctl(A,B,(int)C)
|
||||
|
||||
/* leave task around for debugging if we fail */
|
||||
#define abort(A) taskSuspend(0)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -49,5 +49,5 @@ sf2db: sf2dbYacc.o
|
||||
sf2dbYacc.o: sf2dbLex.c
|
||||
|
||||
clean::
|
||||
/bin/rm -f sf2dbYacc.c sf2dbLex.c
|
||||
$(RM) -f sf2dbYacc.c sf2dbLex.c
|
||||
|
||||
|
||||
@@ -65,7 +65,8 @@ static char *ptypename[DBF_NTYPES] = {
|
||||
"DBF_NOACCESS"
|
||||
};
|
||||
|
||||
static char *pguigroup[] = {
|
||||
#define NGUIDEFS 26
|
||||
static char *pguigroup[NGUIDEFS] = {
|
||||
"",
|
||||
"GUI_COMMON",
|
||||
"GUI_ALARMS",
|
||||
@@ -259,6 +260,7 @@ gen_rectype:
|
||||
if(pfldDes->field_type==DBF_NOACCESS) {
|
||||
char *prtn;
|
||||
char fldname[5];
|
||||
char *ptemp;
|
||||
|
||||
strcpy(fldname,pfldDes->fldname);
|
||||
pstr = fldname;
|
||||
@@ -277,8 +279,21 @@ gen_rectype:
|
||||
pfldDes->fldname,recordtypeInclude);
|
||||
break;
|
||||
}
|
||||
if(!(pstr = strstr(includeLine,fldname))) continue;
|
||||
if(isalnum(*(pstr + strlen(fldname)))) continue;
|
||||
ptemp = &includeLine[0];
|
||||
while(TRUE) {
|
||||
if(!ptemp) break;
|
||||
if(!(pstr = strstr(ptemp,fldname))) {
|
||||
ptemp = NULL;
|
||||
break;
|
||||
}
|
||||
if(isalnum(*(pstr-1))
|
||||
|| isalnum(*(pstr + strlen(fldname)))) {
|
||||
ptemp = pstr + 1;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(!ptemp) continue;
|
||||
break;
|
||||
}
|
||||
if(!prtn) continue;
|
||||
@@ -294,7 +309,10 @@ gen_rectype:
|
||||
fprintf(fp,"\t\tprompt(\"%s\")\n",pfldDes->prompt);
|
||||
}
|
||||
if(pfldDes->promptflag) {
|
||||
fprintf(fp,"\t\tpromptgroup(%s)\n",pguigroup[pfldDes->promptflag]);
|
||||
if(pfldDes->promptflag<0 || pfldDes->promptflag>=NGUIDEFS)
|
||||
fprintf(fp,"\t\tpromptgroup(%s)\n",pguigroup[9]);/*GUI_DISPLAY*/
|
||||
else
|
||||
fprintf(fp,"\t\tpromptgroup(%s)\n",pguigroup[pfldDes->promptflag]);
|
||||
}
|
||||
if(pfldDes->as_level == 0) fprintf(fp,"\t\tasl(ASL0)\n");
|
||||
if(pfldDes->special) {
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.4 1996/08/05 19:31:59 jhill
|
||||
* fixed removes use of iter.cur()
|
||||
*
|
||||
* Revision 1.3 1996/07/25 17:58:16 jhill
|
||||
* fixed missing ref in list decl
|
||||
*
|
||||
@@ -58,6 +61,9 @@ typedef unsigned resTableIndex;
|
||||
|
||||
const unsigned resTableIndexBitWidth = (sizeof(resTableIndex)*CHAR_BIT);
|
||||
|
||||
//
|
||||
// class T must derive class ID
|
||||
//
|
||||
template <class T, class ID>
|
||||
class resTable {
|
||||
public:
|
||||
@@ -106,7 +112,6 @@ public:
|
||||
while (pList<&this->pTable[this->hashIdMask+1]) {
|
||||
tsSLIter<T> iter(*pList);
|
||||
T *pItem;
|
||||
|
||||
while ( (pItem = iter()) ) {
|
||||
iter.remove();
|
||||
delete pItem;
|
||||
@@ -248,7 +253,7 @@ private:
|
||||
//
|
||||
class uintId {
|
||||
public:
|
||||
uintId(unsigned idIn=~0u) : id(idIn) {}
|
||||
uintId(unsigned idIn=UINT_MAX) : id(idIn) {}
|
||||
|
||||
resTableIndex resourceHash(unsigned nBitsId) const
|
||||
{
|
||||
@@ -267,7 +272,7 @@ public:
|
||||
//
|
||||
return hashid;
|
||||
}
|
||||
|
||||
|
||||
int operator == (const uintId &idIn)
|
||||
{
|
||||
return this->id == idIn.id;
|
||||
@@ -287,11 +292,15 @@ protected:
|
||||
template <class ITEM>
|
||||
class uintRes : public uintId, public tsSLNode<ITEM> {
|
||||
friend class uintResTable<ITEM>;
|
||||
public:
|
||||
uintRes(unsigned idIn=UINT_MAX) : uintId(idIn) {}
|
||||
};
|
||||
|
||||
//
|
||||
// special resource table which uses
|
||||
// unsigned integer keys allocated in chronological sequence
|
||||
//
|
||||
// NOTE: ITEM must public inherit from uintRes<ITEM>
|
||||
//
|
||||
template <class ITEM>
|
||||
class uintResTable : public resTable<ITEM, uintId> {
|
||||
@@ -360,17 +369,33 @@ private:
|
||||
//
|
||||
class stringId {
|
||||
public:
|
||||
stringId (char const * const idIn) : id(idIn) {}
|
||||
stringId (char const * const idIn) :
|
||||
pStr(new char [strlen(idIn)+1u])
|
||||
{
|
||||
if (this->pStr!=NULL) {
|
||||
strcpy(this->pStr, idIn);
|
||||
}
|
||||
}
|
||||
|
||||
~ stringId()
|
||||
{
|
||||
if (this->pStr!=NULL) {
|
||||
delete [] this->pStr;
|
||||
}
|
||||
}
|
||||
|
||||
resTableIndex resourceHash(unsigned nBitsId) const
|
||||
{
|
||||
const char *pStr = this->id;
|
||||
resTableIndex hashid;
|
||||
unsigned i;
|
||||
|
||||
if (this->pStr==NULL) {
|
||||
return 0u;
|
||||
}
|
||||
|
||||
hashid = 0u;
|
||||
for (i=0u; pStr[i]; i++) {
|
||||
hashid += pStr[i] * (i+1u);
|
||||
for (i=0u; this->pStr[i]; i++) {
|
||||
hashid += this->pStr[i] * (i+1u);
|
||||
}
|
||||
|
||||
hashid = hashid % (1u<<nBitsId);
|
||||
@@ -380,20 +405,25 @@ public:
|
||||
|
||||
int operator == (const stringId &idIn)
|
||||
{
|
||||
return strcmp(this->id,idIn.id)==0;
|
||||
if (this->pStr!=NULL && idIn.pStr!=NULL) {
|
||||
return strcmp(this->pStr,idIn.pStr)==0;
|
||||
}
|
||||
else {
|
||||
return 0u; // not equal
|
||||
}
|
||||
}
|
||||
|
||||
const char * resourceName()
|
||||
{
|
||||
return id;
|
||||
return this->pStr;
|
||||
}
|
||||
|
||||
void show (unsigned)
|
||||
{
|
||||
printf ("resource id = %s\n", id);
|
||||
printf ("resource id = %s\n", this->pStr);
|
||||
}
|
||||
private:
|
||||
char const * const id;
|
||||
char * const pStr;
|
||||
};
|
||||
|
||||
#endif // INCresourceLibh
|
||||
|
||||
@@ -23,68 +23,127 @@ private:
|
||||
const char * const pName;
|
||||
};
|
||||
|
||||
class jane : public stringId, tsSLNode<jane> {
|
||||
public:
|
||||
jane (const char *pNameIn) : stringId(pNameIn) {}
|
||||
};
|
||||
|
||||
main()
|
||||
{
|
||||
unsigned i;
|
||||
clock_t start, finish;
|
||||
double duration;
|
||||
const int LOOPS = 500000;
|
||||
resTable<fred,uintId> tbl;
|
||||
const int LOOPS = 50000;
|
||||
resTable<fred,uintId> intTbl;
|
||||
resTable<jane,stringId> strTbl;
|
||||
fred fred1("fred1",0x1000a432);
|
||||
fred fred2("fred2",0x0000a432);
|
||||
jane jane1("jane1");
|
||||
jane jane2("jane2");
|
||||
fred *pFred;
|
||||
uintId id1(0x1000a432);
|
||||
uintId id2(0x0000a432);
|
||||
jane *pJane;
|
||||
uintId uintId1(0x1000a432);
|
||||
uintId uintId2(0x0000a432);
|
||||
stringId strId1("jane1");
|
||||
stringId strId2("jane2");
|
||||
int status;
|
||||
|
||||
status = tbl.init(8);
|
||||
status = intTbl.init(8);
|
||||
if (status) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = tbl.add(fred1);
|
||||
status = intTbl.add(fred1);
|
||||
assert (!status);
|
||||
status = tbl.add(fred2);
|
||||
status = intTbl.add(fred2);
|
||||
assert (!status);
|
||||
|
||||
start = clock();
|
||||
for(i=0; i<LOOPS; i++){
|
||||
pFred = tbl.lookup(id1);
|
||||
pFred = intTbl.lookup(uintId1);
|
||||
assert(pFred==&fred1);
|
||||
pFred = tbl.lookup(id1);
|
||||
pFred = intTbl.lookup(uintId1);
|
||||
assert(pFred==&fred1);
|
||||
pFred = tbl.lookup(id1);
|
||||
pFred = intTbl.lookup(uintId1);
|
||||
assert(pFred==&fred1);
|
||||
pFred = tbl.lookup(id1);
|
||||
pFred = intTbl.lookup(uintId1);
|
||||
assert(pFred==&fred1);
|
||||
pFred = tbl.lookup(id1);
|
||||
pFred = intTbl.lookup(uintId1);
|
||||
assert(pFred==&fred1);
|
||||
pFred = tbl.lookup(id1);
|
||||
pFred = intTbl.lookup(uintId1);
|
||||
assert(pFred==&fred1);
|
||||
pFred = tbl.lookup(id1);
|
||||
pFred = intTbl.lookup(uintId1);
|
||||
assert(pFred==&fred1);
|
||||
pFred = tbl.lookup(id1);
|
||||
pFred = intTbl.lookup(uintId1);
|
||||
assert(pFred==&fred1);
|
||||
pFred = tbl.lookup(id1);
|
||||
pFred = intTbl.lookup(uintId1);
|
||||
assert(pFred==&fred1);
|
||||
pFred = tbl.lookup(id2);
|
||||
pFred = intTbl.lookup(uintId2);
|
||||
assert(pFred==&fred2);
|
||||
}
|
||||
finish = clock();
|
||||
|
||||
duration = finish-start;
|
||||
duration /= CLOCKS_PER_SEC;
|
||||
printf("It took %15.10f total sec\n", duration);
|
||||
printf("It took %15.10f total sec for integer hash lookups\n", duration);
|
||||
duration /= LOOPS;
|
||||
duration /= 10;
|
||||
duration *= 1e6;
|
||||
printf("It took %15.10f u sec per hash lookup\n", duration);
|
||||
printf("It took %15.10f u sec per integer hash lookup\n", duration);
|
||||
|
||||
tbl.show(10u);
|
||||
intTbl.show(10u);
|
||||
|
||||
tbl.remove(id1);
|
||||
tbl.remove(id2);
|
||||
intTbl.remove(uintId1);
|
||||
intTbl.remove(uintId2);
|
||||
|
||||
status = strTbl.init(8);
|
||||
if (status) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = strTbl.add(jane1);
|
||||
assert (!status);
|
||||
status = strTbl.add(jane2);
|
||||
assert (!status);
|
||||
|
||||
start = clock();
|
||||
for(i=0; i<LOOPS; i++){
|
||||
pJane = strTbl.lookup(strId1);
|
||||
assert(pJane==&jane1);
|
||||
pJane = strTbl.lookup(strId1);
|
||||
assert(pJane==&jane1);
|
||||
pJane = strTbl.lookup(strId1);
|
||||
assert(pJane==&jane1);
|
||||
pJane = strTbl.lookup(strId1);
|
||||
assert(pJane==&jane1);
|
||||
pJane = strTbl.lookup(strId1);
|
||||
assert(pJane==&jane1);
|
||||
pJane = strTbl.lookup(strId1);
|
||||
assert(pJane==&jane1);
|
||||
pJane = strTbl.lookup(strId1);
|
||||
assert(pJane==&jane1);
|
||||
pJane = strTbl.lookup(strId1);
|
||||
assert(pJane==&jane1);
|
||||
pJane = strTbl.lookup(strId1);
|
||||
assert(pJane==&jane1);
|
||||
pJane = strTbl.lookup(strId2);
|
||||
assert(pJane==&jane2);
|
||||
}
|
||||
finish = clock();
|
||||
|
||||
duration = finish-start;
|
||||
duration /= CLOCKS_PER_SEC;
|
||||
printf("It took %15.10f total sec for string hash lookups\n", duration);
|
||||
duration /= LOOPS;
|
||||
duration /= 10;
|
||||
duration *= 1e6;
|
||||
printf("It took %15.10f u sec per string hash lookup\n", duration);
|
||||
|
||||
strTbl.show(10u);
|
||||
|
||||
strTbl.remove(strId1);
|
||||
strTbl.remove(strId2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.3 1996/07/25 18:01:42 jhill
|
||||
* use pointer (not ref) for list in iter class
|
||||
*
|
||||
* Revision 1.2 1996/07/24 22:12:04 jhill
|
||||
* added remove() to iter class + made node's prev/next private
|
||||
*
|
||||
@@ -125,7 +128,7 @@ template <class T>
|
||||
class tsSLIter {
|
||||
public:
|
||||
tsSLIter(tsSLList<T> &listIn) :
|
||||
pList(&listIn), pCurrent(0), pPrevious(0) {}
|
||||
pCurrent(0), pPrevious(0), pList(&listIn) {}
|
||||
|
||||
void reset()
|
||||
{
|
||||
|
||||
@@ -57,6 +57,7 @@ device(ai,CONSTANT,devAiSoft,"Soft Channel")
|
||||
#device(ai,AB_IO,devAiAb1771Ife0to5V,"AB-1771IFE-0to5Volt")
|
||||
#device(ai,AB_IO,devAiAb1771IrPlatinum,"AB-1771RTD-Platinum")
|
||||
#device(ai,AB_IO,devAiAb1771IrCopper,"AB-1771RTD-Copper")
|
||||
#device(ai,AB_IO,devAiAbSclDcm,"AB-SCL500DCM")
|
||||
#device(ai,CAMAC_IO,devAiCamac,"Camac")
|
||||
#device(ai,VME_IO,devAiAt5Vxi,"VXI-AT5-AI")
|
||||
#device(ai,GPIB_IO,devAiK486Gpib,"Keithley-486")
|
||||
@@ -69,6 +70,7 @@ device(ao,CONSTANT,devAoSoft,"Soft Channel")
|
||||
#device(ao,CONSTANT,devAoTestAsyn,"Test Asyn")
|
||||
#device(ao,CONSTANT,devAoSymb,"vxWorks Variable")
|
||||
#device(ao,AB_IO,devAoAb1771Ofe,"AB-1771OFE")
|
||||
#device(ao,AB_IO,devAoAbSclDcm,"AB-SCL500DCM")
|
||||
#device(ao,CAMAC_IO,devAoCamac,"Camac")
|
||||
#device(ao,VME_IO,devAoAt5Vxi,"VXI-AT5-AO")
|
||||
device(bi,CONSTANT,devBiSoft,"Soft Channel")
|
||||
@@ -113,9 +115,11 @@ device(event,CONSTANT,devEventSoft,"Soft Channel")
|
||||
device(longin,CONSTANT,devLiSoft,"Soft Channel")
|
||||
device(longin,CONSTANT,devLiSymb,"vxWorks Variable")
|
||||
#device(longin,CAMAC_IO,devLiCamac,"Camac")
|
||||
#device(longin,AB_IO,devLiAbSclDcm,"AB-SCL500DCM")
|
||||
device(longout,CONSTANT,devLoSoft,"Soft Channel")
|
||||
device(longout,CONSTANT,devLoSymb,"vxWorks Variable")
|
||||
#device(longout,CAMAC_IO,devLoCamac,"Camac")
|
||||
#device(longout,AB_IO,devLoAbSclDcm,"AB-SCL500DCM")
|
||||
device(mbbi,CONSTANT,devMbbiSoft,"Soft Channel")
|
||||
#device(mbbi,CONSTANT,devMbbiSoftRaw,"Raw Soft Channel")
|
||||
#device(mbbi,VME_IO,devMbbiMpv910,"MPV-910")
|
||||
|
||||
@@ -143,6 +143,7 @@ LIBOBJS += $(EPICS_BASE_BIN)/devWfTestAsyn.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAB1771IR.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAB1771IXE.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devAB1771OFE.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devABSLCDCM.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devABBINARY.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devABStatus.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devMpc.o
|
||||
@@ -202,3 +203,8 @@ LIBOBJS += $(EPICS_BASE_BIN)/drvHp1404a.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvXy240.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvXy566.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/drvVmic2534.o
|
||||
#
|
||||
#from src/devOpt
|
||||
#
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devBBInteract.o
|
||||
#LIBOBJS += $(EPICS_BASE_BIN)/devGpibInteract.o
|
||||
|
||||
@@ -670,7 +670,7 @@ long dbGetLinkValue(struct link *plink, short dbrType, void *pbuffer,
|
||||
precord->pact = pact;
|
||||
if(status) return(status);
|
||||
}
|
||||
if(ppv_link->pvlMask&pvlOptMS)
|
||||
if(ppv_link->pvlMask&pvlOptMS && precord!= paddr->precord)
|
||||
recGblSetSevr(precord,LINK_ALARM,paddr->precord->sevr);
|
||||
|
||||
if(ppv_link->getCvt && ppv_link->lastGetdbrType==dbrType) {
|
||||
@@ -780,6 +780,7 @@ long dbGetField( DBADDR *paddr,short dbrType,void *pbuffer,
|
||||
}
|
||||
if(options && (*options))
|
||||
getOptions(paddr,(void **)&pbuf,options,pflin);
|
||||
if(nRequest && *nRequest==0) goto done;
|
||||
dbInitEntry(pdbbase,&dbEntry);
|
||||
if(status = dbFindRecord(&dbEntry,precord->name)) goto done;
|
||||
if(status = dbFindField(&dbEntry,pfldDes->name)) goto done;
|
||||
@@ -951,6 +952,10 @@ long dbPutField(DBADDR *paddr,short dbrType,void *pbuffer,long nRequest)
|
||||
if(status) return(status);
|
||||
}
|
||||
if(status=dbPutString(&dbEntry,buffer)) goto done;
|
||||
if(special) {
|
||||
status = putSpecial(paddr,1);
|
||||
if(status) return(status);
|
||||
}
|
||||
if(plink->type == PV_LINK) {
|
||||
DBADDR dbaddr;
|
||||
|
||||
@@ -982,10 +987,6 @@ long dbPutField(DBADDR *paddr,short dbrType,void *pbuffer,long nRequest)
|
||||
}
|
||||
}
|
||||
}
|
||||
if(special) {
|
||||
status = putSpecial(paddr,1);
|
||||
if(status) return(status);
|
||||
}
|
||||
db_post_events(precord,plink,DBE_VALUE);
|
||||
dbFinishEntry(&dbEntry);
|
||||
done:
|
||||
|
||||
@@ -298,6 +298,17 @@ void dbCaRemoveLink(struct link *plink);
|
||||
long dbCaGetLink(struct link *plink,short dbrType,void *pbuffer,
|
||||
unsigned short *psevr,long *nRequest);
|
||||
long dbCaPutLink(struct link *plink,short dbrType,void *pbuffer,long nRequest);
|
||||
long dbCaGetAttributes(struct link *plink,
|
||||
void (*callback)(void *usrPvt),void *usrPvt);
|
||||
long dbCaGetControlLimits(struct link *plink,double *low, double *high);
|
||||
long dbCaGetGraphicLimits(struct link *plink,double *low, double *high);
|
||||
long dbCaGetAlarmLimits(struct link *plink,
|
||||
double *lolo, double *low, double *high, double *hihi);
|
||||
long dbCaGetNelements(struct link *plink,long *nelements);
|
||||
long dbCaGetPrecision(struct link *plink,short *precision);
|
||||
long dbCaGetSevr(struct link *plink,short *severity);
|
||||
long dbCaGetUnits(struct link *plink,char *units,int unitsSize);
|
||||
int dbCaIsLinkConnected(struct link *plink);
|
||||
|
||||
#else
|
||||
struct rset *dbGetRset();
|
||||
|
||||
192
src/db/dbCa.c
192
src/db/dbCa.c
@@ -43,6 +43,7 @@ of this distribution.
|
||||
#include "dbCa.h"
|
||||
/*Following is because dbScan.h causes include for dbAccess.h*/
|
||||
void scanOnce(void *precord);
|
||||
extern volatile int interruptAccept;
|
||||
|
||||
static ELLLIST caList; /* Work list for dbCaTask */
|
||||
static SEM_ID caListSem; /*Mutual exclusions semaphores for caList*/
|
||||
@@ -138,7 +139,7 @@ long dbCaGetLink(struct link *plink,short dbrType, char *pdest,
|
||||
epicsPrintf("dbCaGetLink: semStatus!OK\n");
|
||||
return(-1);
|
||||
}
|
||||
if(ca_state(pca->chid) != cs_conn) {
|
||||
if(!pca->chid || ca_state(pca->chid) != cs_conn) {
|
||||
pca->sevr = INVALID_ALARM;
|
||||
goto done;
|
||||
}
|
||||
@@ -214,7 +215,7 @@ long dbCaPutLink(struct link *plink,short dbrType,
|
||||
epicsPrintf("dbCaGetLink: semStatus!OK\n");
|
||||
return(-1);
|
||||
}
|
||||
if(ca_state(pca->chid) != cs_conn) {
|
||||
if(!pca->chid || ca_state(pca->chid) != cs_conn) {
|
||||
semGive(pca->lock);
|
||||
return(-1);
|
||||
}
|
||||
@@ -260,6 +261,149 @@ long dbCaPutLink(struct link *plink,short dbrType,
|
||||
return(status);
|
||||
}
|
||||
|
||||
long dbCaGetAttributes(struct link *plink,
|
||||
void (*callback)(void *usrPvt),void *usrPvt)
|
||||
{
|
||||
caLink *pca;
|
||||
long status = 0;
|
||||
STATUS semStatus;
|
||||
short link_action = 0;
|
||||
caAttributes *pcaAttributes;
|
||||
|
||||
if(!plink || (plink->type!=CA_LINK)) {
|
||||
epicsPrintf("dbCaGetAttributes: called for non CA_LINK\n");
|
||||
return(-1);
|
||||
}
|
||||
pca = (caLink *)plink->value.pv_link.pvt;
|
||||
if(!pca) {
|
||||
epicsPrintf("dbCaGetAttributes: record %s pv_link.pvt is NULL\n",
|
||||
plink->value.pv_link.precord);
|
||||
return(-1);
|
||||
}
|
||||
if(pca->pcaAttributes) {
|
||||
epicsPrintf("dbCaGetAttributes: record %s duplicate call\n",
|
||||
plink->value.pv_link.precord);
|
||||
return(-1);
|
||||
}
|
||||
pcaAttributes = dbCalloc(1,sizeof(caAttributes));
|
||||
pcaAttributes->callback = callback;
|
||||
pcaAttributes->usrPvt = usrPvt;
|
||||
semStatus = semTake(pca->lock,WAIT_FOREVER);
|
||||
if(semStatus!=OK) {
|
||||
epicsPrintf("dbCaGetLink: semStatus!OK\n");
|
||||
return(-1);
|
||||
}
|
||||
pca->pcaAttributes = pcaAttributes;
|
||||
link_action |= CA_GET_ATTRIBUTES;
|
||||
semGive(pca->lock);
|
||||
addAction(pca,link_action);
|
||||
return(status);
|
||||
}
|
||||
|
||||
caAttributes *getpcaAttributes(struct link *plink)
|
||||
{
|
||||
caLink *pca;
|
||||
|
||||
if(!plink || (plink->type!=CA_LINK)) return(NULL);
|
||||
pca = (caLink *)plink->value.pv_link.pvt;
|
||||
if(!pca->chid || ca_state(pca->chid)!=cs_conn) return(NULL);
|
||||
return(pca->pcaAttributes);
|
||||
}
|
||||
|
||||
long dbCaGetControlLimits(struct link *plink,double *low, double *high)
|
||||
{
|
||||
caAttributes *pcaAttributes;
|
||||
|
||||
pcaAttributes = getpcaAttributes(plink);
|
||||
if(!pcaAttributes) return(-1);
|
||||
*low = pcaAttributes->data.lower_ctrl_limit;
|
||||
*high = pcaAttributes->data.upper_ctrl_limit;
|
||||
return(0);
|
||||
}
|
||||
|
||||
long dbCaGetGraphicLimits(struct link *plink,double *low, double *high)
|
||||
{
|
||||
caAttributes *pcaAttributes;
|
||||
|
||||
pcaAttributes = getpcaAttributes(plink);
|
||||
if(!pcaAttributes) return(-1);
|
||||
*low = pcaAttributes->data.lower_disp_limit;
|
||||
*high = pcaAttributes->data.upper_disp_limit;
|
||||
return(0);
|
||||
}
|
||||
|
||||
long dbCaGetAlarmLimits(struct link *plink,
|
||||
double *lolo, double *low, double *high, double *hihi)
|
||||
{
|
||||
caAttributes *pcaAttributes;
|
||||
|
||||
pcaAttributes = getpcaAttributes(plink);
|
||||
if(!pcaAttributes) return(-1);
|
||||
*lolo = pcaAttributes->data.lower_alarm_limit;
|
||||
*low = pcaAttributes->data.lower_warning_limit;
|
||||
*high = pcaAttributes->data.upper_warning_limit;
|
||||
*hihi = pcaAttributes->data.upper_alarm_limit;
|
||||
return(0);
|
||||
}
|
||||
|
||||
long dbCaGetPrecision(struct link *plink,short *precision)
|
||||
{
|
||||
caAttributes *pcaAttributes;
|
||||
|
||||
pcaAttributes = getpcaAttributes(plink);
|
||||
if(!pcaAttributes) return(-1);
|
||||
*precision = pcaAttributes->data.precision;
|
||||
return(0);
|
||||
}
|
||||
|
||||
long dbCaGetUnits(struct link *plink,char *units,int unitsSize)
|
||||
{
|
||||
caAttributes *pcaAttributes;
|
||||
|
||||
pcaAttributes = getpcaAttributes(plink);
|
||||
if(!pcaAttributes) return(-1);
|
||||
strncpy(units,pcaAttributes->data.units,unitsSize);
|
||||
units[unitsSize-1] = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
long dbCaGetNelements(struct link *plink,long *nelements)
|
||||
{
|
||||
caLink *pca;
|
||||
|
||||
if(!plink) return(-1);
|
||||
if(plink->type != CA_LINK) return(-1);
|
||||
pca = (caLink *)plink->value.pv_link.pvt;
|
||||
if(!pca->chid || ca_state(pca->chid)!=cs_conn) return(-1);
|
||||
*nelements = pca->nelements;
|
||||
return(0);
|
||||
}
|
||||
|
||||
long dbCaGetSevr(struct link *plink,short *severity)
|
||||
{
|
||||
caLink *pca;
|
||||
|
||||
if(!plink) return(-1);
|
||||
if(plink->type != CA_LINK) return(-1);
|
||||
pca = (caLink *)plink->value.pv_link.pvt;
|
||||
if(!pca->chid || ca_state(pca->chid)!=cs_conn) return(-1);
|
||||
*severity = pca->sevr;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int dbCaIsLinkConnected(struct link *plink)
|
||||
{
|
||||
caLink *pca;
|
||||
|
||||
if(!plink) return(FALSE);
|
||||
if(plink->type != CA_LINK) return(FALSE);
|
||||
pca = (caLink *)plink->value.pv_link.pvt;
|
||||
if(!pca) return(FALSE);
|
||||
if(!pca->chid) return(FALSE);
|
||||
if(ca_state(pca->chid)==cs_conn) return(TRUE);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
static void eventCallback(struct event_handler_args arg)
|
||||
{
|
||||
caLink *pca = (caLink *)arg.usr;
|
||||
@@ -326,6 +470,39 @@ done:
|
||||
semGive(pca->lock);
|
||||
}
|
||||
|
||||
static void getAttribEventCallback(struct event_handler_args arg)
|
||||
{
|
||||
caLink *pca = (caLink *)arg.usr;
|
||||
struct link *plink;
|
||||
STATUS semStatus;
|
||||
struct dbr_ctrl_double *dbr;
|
||||
caAttributes *pcaAttributes = NULL;
|
||||
|
||||
if(!pca) {
|
||||
epicsPrintf("getAttribEventCallback why was arg.usr NULL\n");
|
||||
return;
|
||||
}
|
||||
semStatus = semTake(pca->lock,WAIT_FOREVER);
|
||||
if(semStatus!=OK) {
|
||||
epicsPrintf("getAttribEventCallback: semStatus!OK\n");
|
||||
return;
|
||||
}
|
||||
plink = pca->plink;
|
||||
if(!plink) goto done;
|
||||
if(!arg.dbr) {
|
||||
epicsPrintf("getAttribEventCallback why was arg.dbr NULL\n");
|
||||
goto done;
|
||||
}
|
||||
dbr = arg.dbr;
|
||||
pcaAttributes = pca->pcaAttributes;
|
||||
if(!pcaAttributes) goto done;
|
||||
pcaAttributes->data = *dbr; /*copy entire structure*/
|
||||
pcaAttributes->gotData = TRUE;
|
||||
(pcaAttributes->callback)(pcaAttributes->usrPvt);
|
||||
done:
|
||||
semGive(pca->lock);
|
||||
}
|
||||
|
||||
static void accessRightsCallback(struct access_rights_handler_args arg)
|
||||
{
|
||||
caLink *pca = (caLink *)ca_puser(arg.chid);
|
||||
@@ -414,6 +591,7 @@ static void connectionCallback(struct connection_handler_args arg)
|
||||
if((plink->value.pv_link.pvlMask & pvlOptOutString) && (pca->gotOutString)){
|
||||
link_action |= CA_WRITE_STRING;
|
||||
}
|
||||
if(pca->pcaAttributes) link_action |= CA_GET_ATTRIBUTES;
|
||||
done:
|
||||
semGive(pca->lock);
|
||||
if(link_action) addAction(pca,link_action);
|
||||
@@ -426,6 +604,8 @@ void dbCaTask()
|
||||
int status;
|
||||
|
||||
SEVCHK(ca_task_initialize(),NULL);
|
||||
/*Dont do anything until iocInit initializes database*/
|
||||
while(!interruptAccept) taskDelay(10);
|
||||
/* channel access event loop */
|
||||
while (TRUE){
|
||||
semTake(caWakeupSem,WAIT_FOREVER);
|
||||
@@ -442,6 +622,7 @@ void dbCaTask()
|
||||
free(pca->pputNative);
|
||||
free(pca->pgetString);
|
||||
free(pca->pputString);
|
||||
free(pca->pcaAttributes);
|
||||
semDelete(pca->lock);
|
||||
free(pca);
|
||||
continue; /*No other link_action makes sense*/
|
||||
@@ -499,6 +680,13 @@ void dbCaTask()
|
||||
epicsPrintf("dbCaTask ca_add_array_event %s\n",
|
||||
ca_message(status));
|
||||
}
|
||||
if(link_action&CA_GET_ATTRIBUTES) {
|
||||
status = ca_get_callback(DBR_CTRL_DOUBLE,
|
||||
pca->chid,getAttribEventCallback,pca);
|
||||
if(status!=ECA_NORMAL)
|
||||
epicsPrintf("dbCaTask ca_add_array_event %s\n",
|
||||
ca_message(status));
|
||||
}
|
||||
} else { /* caList was empty */
|
||||
semGive(caListSem);
|
||||
break; /*caList is empty*/
|
||||
|
||||
@@ -30,6 +30,16 @@ of this distribution.
|
||||
#define CA_WRITE_STRING 0x8
|
||||
#define CA_MONITOR_NATIVE 0x10
|
||||
#define CA_MONITOR_STRING 0x20
|
||||
#define CA_GET_ATTRIBUTES 0x40
|
||||
|
||||
typedef struct caAttributes
|
||||
{
|
||||
void (*callback)(void *usrPvt);
|
||||
struct dbr_ctrl_double data;
|
||||
void *usrPvt;
|
||||
int gotData;
|
||||
}caAttributes;
|
||||
|
||||
typedef struct caLink
|
||||
{
|
||||
ELLNODE node;
|
||||
@@ -39,6 +49,7 @@ typedef struct caLink
|
||||
void *pputNative;
|
||||
char *pgetString;
|
||||
char *pputString;
|
||||
caAttributes *pcaAttributes;
|
||||
long nelements;
|
||||
SEM_ID lock;
|
||||
unsigned long nDisconnect;
|
||||
|
||||
@@ -155,7 +155,7 @@ int db_event_list(char *name)
|
||||
printf(" ev que %x\n",pevent->ev_que);
|
||||
printf(" ev user %x\n",pevent->ev_que->evuser);
|
||||
#endif
|
||||
printf( "task %x select %x pfield %x behind by %d\n",
|
||||
printf( "task %x select %x pfield %x behind by %ld\n",
|
||||
pevent->ev_que->evuser->taskid,
|
||||
pevent->select,
|
||||
(unsigned int) pevent->paddr->pfield,
|
||||
|
||||
@@ -207,10 +207,15 @@ void dbLockSetRecordLock(dbCommon *precord)
|
||||
|
||||
void dbScanLock(dbCommon *precord)
|
||||
{
|
||||
lockRecord *plockRecord = (lockRecord *)precord->lset;
|
||||
lockRecord *plockRecord;
|
||||
lockSet *plockSet;
|
||||
STATUS status;
|
||||
|
||||
if(!(plockRecord= (lockRecord *)precord->lset)) {
|
||||
epicsPrintf("dbScanLock plockRecord is NULL record %s\n",
|
||||
precord->name);
|
||||
exit(1);
|
||||
}
|
||||
while(TRUE) {
|
||||
if(changingLockSets) {
|
||||
semTake(globalWaitSemid,WAIT_FOREVER);
|
||||
@@ -319,6 +324,7 @@ void dbLockSetMerge(dbCommon *pfirst,dbCommon *psecond)
|
||||
lockSet *p1lockSet;
|
||||
lockSet *p2lockSet;
|
||||
|
||||
if(pfirst==psecond) return;
|
||||
p1lockSet = p1lockRecord->plockSet;
|
||||
p2lockSet = p2lockRecord->plockSet;
|
||||
if(!p1lockSet) {
|
||||
|
||||
@@ -586,15 +586,16 @@ static void scanList(scan_list *psl)
|
||||
/*In reading this code remember that the call to dbProcess can result*/
|
||||
/*in the SCAN field being changed in an arbitrary number of records */
|
||||
|
||||
scan_element *pse,*prev,*next;
|
||||
scan_element *pse,*prev;
|
||||
scan_element *next=0;
|
||||
|
||||
FASTLOCK(&psl->lock);
|
||||
psl->modified = FALSE;
|
||||
pse = (scan_element *)ellFirst(&psl->list);
|
||||
prev = NULL;
|
||||
next = (scan_element *)ellNext((void *)pse);
|
||||
if(pse) next = (scan_element *)ellNext((void *)pse);
|
||||
FASTUNLOCK(&psl->lock);
|
||||
while(pse!=NULL) {
|
||||
while(pse) {
|
||||
struct dbCommon *precord = pse->precord;
|
||||
|
||||
dbScanLock(precord);
|
||||
@@ -604,22 +605,22 @@ static void scanList(scan_list *psl)
|
||||
if(!psl->modified) {
|
||||
prev = pse;
|
||||
pse = (scan_element *)ellNext((void *)pse);
|
||||
if(pse!=NULL)next = (scan_element *)ellNext((void *)pse);
|
||||
if(pse)next = (scan_element *)ellNext((void *)pse);
|
||||
} else if (pse->pscan_list==psl) {
|
||||
/*This scan element is still in same scan list*/
|
||||
prev = pse;
|
||||
pse = (scan_element *)ellNext((void *)pse);
|
||||
if(pse!=NULL)next = (scan_element *)ellNext((void *)pse);
|
||||
if(pse)next = (scan_element *)ellNext((void *)pse);
|
||||
psl->modified = FALSE;
|
||||
} else if (prev!=NULL && prev->pscan_list==psl) {
|
||||
} else if (prev && prev->pscan_list==psl) {
|
||||
/*Previous scan element is still in same scan list*/
|
||||
pse = (scan_element *)ellNext((void *)prev);
|
||||
if(pse!=NULL) {
|
||||
if(pse) {
|
||||
prev = (scan_element *)ellPrevious((void *)pse);
|
||||
next = (scan_element *)ellNext((void *)pse);
|
||||
}
|
||||
psl->modified = FALSE;
|
||||
} else if (next!=NULL && next->pscan_list==psl) {
|
||||
} else if (next && next->pscan_list==psl) {
|
||||
/*Next scan element is still in same scan list*/
|
||||
pse = next;
|
||||
prev = (scan_element *)ellPrevious((void *)pse);
|
||||
@@ -667,7 +668,7 @@ static void addToList(struct dbCommon *precord,scan_list *psl)
|
||||
}
|
||||
pse ->pscan_list = psl;
|
||||
ptemp = (scan_element *)ellFirst(&psl->list);
|
||||
while(ptemp!=NULL) {
|
||||
while(ptemp) {
|
||||
if(ptemp->precord->phas>precord->phas) {
|
||||
ellInsert(&psl->list,
|
||||
ellPrevious((void *)ptemp),(void *)pse);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name [a-zA-Z0-9_\-:\.\[\]<>;]
|
||||
string [a-zA-Z0-9_\,\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$\t]
|
||||
string [a-zA-Z0-9_\,\^~\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$\t]
|
||||
|
||||
%{
|
||||
#undef YY_INPUT
|
||||
|
||||
@@ -536,7 +536,7 @@ static void dbRecordtypeFieldItem(char *name,char *value)
|
||||
free((void *)value);
|
||||
return;
|
||||
}
|
||||
yyerror("Illegal promptgroup. See guigroup.h for legal values");
|
||||
yyerror("Illegal special value.");
|
||||
return;
|
||||
}
|
||||
if(strcmp(name,"pp")==0) {
|
||||
|
||||
@@ -53,6 +53,7 @@ of this distribution.
|
||||
int dbStaticDebug = 0;
|
||||
#define messagesize 100
|
||||
#define RPCL_LEN 184
|
||||
#define MAX_FIELD_NAME_LENGTH 20
|
||||
long postfix(char *pinfix, char *ppostfix,short *perror);
|
||||
|
||||
static char *ppstring[5]={"NPP","PP","CA","CP","CPP"};
|
||||
@@ -88,7 +89,8 @@ static char *promptOUTLINK[] = {
|
||||
"NPP PP CA:",
|
||||
"NMS or MS:"};
|
||||
static char *promptFWDLINK[] = {
|
||||
" PV Name:"};
|
||||
" PV Name:",
|
||||
"<null> CA:"};
|
||||
static char *promptVME_IO[] = {
|
||||
" card:",
|
||||
"signal:",
|
||||
@@ -217,6 +219,8 @@ long dbNextFielddes(DBENTRY *pdbentry,int dctonly)
|
||||
{return dbNextField(pdbentry,dctonly);}
|
||||
char **dbGetChoices(DBENTRY *pdbentry)
|
||||
{return dbGetMenuChoices(pdbentry);}
|
||||
void dbDumpRecDes(DBBASE *pdbbase,char *recordTypeName)
|
||||
{dbDumpRecordType(pdbbase,recordTypeName);}
|
||||
|
||||
/* internal routines*/
|
||||
void copyEntry(DBENTRY *pfrom,DBENTRY *pto)
|
||||
@@ -279,7 +283,6 @@ static long putParmString(char **pparm,char *pstring)
|
||||
pstring++;
|
||||
size = strlen(pstring) + 1;
|
||||
if(size==1) return(0);
|
||||
if(size>=MAX_STRING_SIZE) return(S_dbLib_strLen);
|
||||
*pparm = dbCalloc(size, sizeof(char *));
|
||||
strcpy(*pparm,pstring);
|
||||
return(0);
|
||||
@@ -1451,9 +1454,9 @@ long dbCopyRecord(DBENTRY *pdbentry,char *newRecordName,int overWriteOK)
|
||||
return(0);
|
||||
}
|
||||
|
||||
long dbFindField(DBENTRY *pdbentry,char *pfieldName)
|
||||
long dbFindField(DBENTRY *pdbentry,char *pname)
|
||||
{
|
||||
dbRecordType *precordType = pdbentry->precordType;
|
||||
dbRecordType *precordType = pdbentry->precordType;
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
char *precord;
|
||||
dbFldDes *pflddes;
|
||||
@@ -1462,14 +1465,25 @@ long dbFindField(DBENTRY *pdbentry,char *pfieldName)
|
||||
short *sortFldInd;
|
||||
long status;
|
||||
int compare;
|
||||
char fieldName[MAX_FIELD_NAME_LENGTH];
|
||||
char *pfieldName;
|
||||
int ind;
|
||||
|
||||
if(!precordType) return(S_dbLib_recordTypeNotFound);
|
||||
if(!precnode) return(S_dbLib_recNotFound);
|
||||
precord = precnode->precord;
|
||||
papsortFldName = precordType->papsortFldName;
|
||||
sortFldInd = precordType->sortFldInd;
|
||||
/*copy field name. Stop at null or blank or tab*/
|
||||
pfieldName = &fieldName[0];
|
||||
for(ind=0; ind<MAX_FIELD_NAME_LENGTH; ind++) {
|
||||
if(*pname=='\0' || *pname==' ' || *pname=='\t') break;
|
||||
*pfieldName++ = *pname++;
|
||||
}
|
||||
*pfieldName = '\0';
|
||||
pfieldName = &fieldName[0];
|
||||
/* check for default field name or VAL to be supplied */
|
||||
if((*pfieldName==0) || (strcmp(pfieldName,"VAL")==0)) {
|
||||
if((*pfieldName==0) || (strcmp(pfieldName,"VAL")==0) ) {
|
||||
if(!(pflddes=precordType->pvalFldDes))
|
||||
return(S_dbLib_recordTypeNotFound);
|
||||
pdbentry->pflddes = pflddes;
|
||||
@@ -1572,7 +1586,7 @@ char *dbGetString(DBENTRY *pdbentry)
|
||||
if(plink->value.constantStr) {
|
||||
strcpy(message,plink->value.constantStr);
|
||||
} else {
|
||||
strcpy(message,"0");
|
||||
strcpy(message,"");
|
||||
}
|
||||
break;
|
||||
case PV_LINK:
|
||||
@@ -1665,12 +1679,23 @@ char *dbGetString(DBENTRY *pdbentry)
|
||||
break;
|
||||
case PV_LINK:
|
||||
case CA_LINK:
|
||||
case DB_LINK:
|
||||
case DB_LINK: {
|
||||
int ppind;
|
||||
short pvlMask;
|
||||
|
||||
pvlMask = plink->value.pv_link.pvlMask;
|
||||
if(pvlMask&pvlOptCA) ppind=2;
|
||||
else ppind=0;
|
||||
if(plink->value.pv_link.pvname)
|
||||
strcpy(message,plink->value.pv_link.pvname);
|
||||
else
|
||||
strcpy(message,"");
|
||||
if(ppind) {
|
||||
strcat(message," ");
|
||||
strcat(message,ppstring[ppind]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default :
|
||||
return(NULL);
|
||||
}
|
||||
@@ -1778,6 +1803,8 @@ long dbPutString(DBENTRY *pdbentry,char *pstring)
|
||||
if(!pstr || (int)strlen(pstr)<=0 ) {
|
||||
if(plink->type==PV_LINK) dbCvtLinkToConstant(pdbentry);
|
||||
if(plink->type!=CONSTANT) return(S_dbLib_badField);
|
||||
free((void *)plink->value.constantStr);
|
||||
plink->value.constantStr = NULL;
|
||||
return(0);
|
||||
}
|
||||
switch(plink->type) {
|
||||
@@ -1807,16 +1834,42 @@ long dbPutString(DBENTRY *pdbentry,char *pstring)
|
||||
if(plink->type==CONSTANT) dbCvtLinkToPvlink(pdbentry);
|
||||
end = strchr(pstr,' ');
|
||||
if(end) {
|
||||
if(strstr(end,"NPP")) ppOpt = 0;
|
||||
else if(strstr(end,"PP")) ppOpt = pvlOptPP;
|
||||
else if(strstr(end,"CA")) ppOpt = pvlOptCA;
|
||||
else if(strstr(end,"CP")) ppOpt = pvlOptCP;
|
||||
else if(strstr(end,"CPP")) ppOpt = pvlOptCPP;
|
||||
else ppOpt = 0;
|
||||
if(strstr(end,"NMS")) msOpt = 0;
|
||||
else if(strstr(end,"MS")) msOpt = pvlOptMS;
|
||||
else msOpt = 0;
|
||||
*end = 0;
|
||||
switch (pflddes->field_type) {
|
||||
case DBF_INLINK: {
|
||||
if(strstr(end,"NPP")) ppOpt = 0;
|
||||
else if(strstr(end,"CPP")) ppOpt = pvlOptCPP;
|
||||
else if(strstr(end,"PP")) ppOpt = pvlOptPP;
|
||||
else if(strstr(end,"CA")) ppOpt = pvlOptCA;
|
||||
else if(strstr(end,"CP")) ppOpt = pvlOptCP;
|
||||
else ppOpt = 0;
|
||||
if(strstr(end,"NMS")) msOpt = 0;
|
||||
else if(strstr(end,"MS")) msOpt = pvlOptMS;
|
||||
else msOpt = 0;
|
||||
*end = 0;
|
||||
}
|
||||
break;
|
||||
case DBF_OUTLINK: {
|
||||
if(strstr(end,"NPP")) ppOpt = 0;
|
||||
else if(strstr(end,"PP")) ppOpt = pvlOptPP;
|
||||
else if(strstr(end,"CA")) ppOpt = pvlOptCA;
|
||||
else ppOpt = 0;
|
||||
if(strstr(end,"NMS")) msOpt = 0;
|
||||
else if(strstr(end,"MS")) msOpt = pvlOptMS;
|
||||
else msOpt = 0;
|
||||
*end = 0;
|
||||
}
|
||||
break;
|
||||
case DBF_FWDLINK: {
|
||||
if(strstr(end,"NPP")) ppOpt = 0;
|
||||
else if(strstr(end,"CA")) ppOpt = pvlOptCA;
|
||||
else ppOpt = 0;
|
||||
msOpt = 0;
|
||||
*end = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
epicsPrintf("dbPutString: Logic Error\n");
|
||||
}
|
||||
}
|
||||
status = putPvLink(pdbentry,ppOpt|msOpt,pstr);
|
||||
return(0);
|
||||
@@ -2347,7 +2400,8 @@ int dbAllocForm(DBENTRY *psave)
|
||||
status = mapLINKTtoFORMT(plink,plinkflddes,&linkType);
|
||||
if(status) goto done;
|
||||
nlines = formlines[linkType];
|
||||
nbytes = sizeof(struct form) + 2*nlines*(sizeof(char *) + MAX_STRING_SIZE);
|
||||
/*Dont know how to handle string size. Just use messagesize*/
|
||||
nbytes = sizeof(struct form) + 2*nlines*(sizeof(char *) + messagesize);
|
||||
pform = dbCalloc(1,nbytes);
|
||||
pform->linkType = linkType;
|
||||
psave->formpvt = pform;
|
||||
@@ -2358,11 +2412,11 @@ int dbAllocForm(DBENTRY *psave)
|
||||
pstr = (char *)(pform->verify) + nlines*sizeof(char *);
|
||||
for(i=0; i<nlines; i++) {
|
||||
pform->value[i] = pstr;
|
||||
pstr += MAX_STRING_SIZE;
|
||||
pstr += messagesize;
|
||||
}
|
||||
for(i=0; i<nlines; i++) {
|
||||
pform->verify[i] = pstr;
|
||||
pstr += MAX_STRING_SIZE;
|
||||
pstr += messagesize;
|
||||
}
|
||||
done:
|
||||
dbFinishEntry(pdbentry);
|
||||
@@ -2410,7 +2464,7 @@ char **dbGetFormValue(DBENTRY *pdbentry)
|
||||
if(plink->value.pv_link.pvname)
|
||||
strcpy(*value,plink->value.pv_link.pvname);
|
||||
else
|
||||
strcpy(*value,"\0");
|
||||
strcpy(*value,"");
|
||||
value++;
|
||||
if(pvlMask&pvlOptPP) strcpy(*value,"PP");
|
||||
else if(pvlMask&pvlOptCA) strcpy(*value,"CA");
|
||||
@@ -2429,7 +2483,7 @@ char **dbGetFormValue(DBENTRY *pdbentry)
|
||||
if(plink->value.pv_link.pvname)
|
||||
strcpy(*value,plink->value.pv_link.pvname);
|
||||
else
|
||||
strcpy(*value,"\0");
|
||||
strcpy(*value,"");
|
||||
value++;
|
||||
if(pvlMask&pvlOptPP) strcpy(*value,"PP");
|
||||
else if(pvlMask&pvlOptCA) strcpy(*value,"CA");
|
||||
@@ -2441,11 +2495,15 @@ char **dbGetFormValue(DBENTRY *pdbentry)
|
||||
}
|
||||
break;
|
||||
case FORM_FWDLINK: {
|
||||
short pvlMask = plink->value.pv_link.pvlMask;
|
||||
|
||||
if(plink->value.pv_link.pvname)
|
||||
strcpy(*value,plink->value.pv_link.pvname);
|
||||
else
|
||||
strcpy(*value,"\0");
|
||||
strcpy(*value,"");
|
||||
value++;
|
||||
if(pvlMask&pvlOptCA) strcpy(*value,"CA");
|
||||
else strcpy(*value,"");
|
||||
}
|
||||
break;
|
||||
case FORM_VME_IO:
|
||||
@@ -2595,7 +2653,7 @@ long dbPutForm(DBENTRY *pdbentry,char **value)
|
||||
**verify = 0;
|
||||
value++; verify++;
|
||||
**verify = 0; /*Initialize verify to NULL*/
|
||||
if(!(*value)) ppOpt = 0;
|
||||
if((*value==NULL) || (strcmp(*value,"")==0)) ppOpt = 0;
|
||||
else if(strstr(*value,"NPP")) ppOpt = 0;
|
||||
else if(strstr(*value,"PP")) ppOpt = pvlOptPP;
|
||||
else if(strstr(*value,"CA")) ppOpt = pvlOptCA;
|
||||
@@ -2604,7 +2662,7 @@ long dbPutForm(DBENTRY *pdbentry,char **value)
|
||||
else strcpy(*verify,"Illegal. Chose a value");
|
||||
value++; verify++;
|
||||
**verify = 0; /*Initialize verify to NULL*/
|
||||
if(!(*value)) msOpt = 0;
|
||||
if((*value==NULL) || (strcmp(*value,"")==0)) msOpt = 0;
|
||||
else if(strstr(*value,"NMS")) msOpt = 0;
|
||||
else if(strstr(*value,"MS")) msOpt = pvlOptMS;
|
||||
else strcpy(*verify,"Illegal. Chose a value");
|
||||
@@ -2631,14 +2689,14 @@ long dbPutForm(DBENTRY *pdbentry,char **value)
|
||||
**verify = 0;
|
||||
value++; verify++;
|
||||
**verify = 0; /*Initialize verify to NULL*/
|
||||
if(!(*value)) ppOpt = 0;
|
||||
if((*value==NULL) || (strcmp(*value,"")==0)) ppOpt = 0;
|
||||
else if(strstr(*value,"NPP")) ppOpt = 0;
|
||||
else if(strstr(*value,"PP")) ppOpt = pvlOptPP;
|
||||
else if(strstr(*value,"CA")) ppOpt = pvlOptCA;
|
||||
else strcpy(*verify,"Illegal. Chose a value");
|
||||
value++; verify++;
|
||||
**verify = 0; /*Initialize verify to NULL*/
|
||||
if(!(*value)) msOpt = 0;
|
||||
if((*value==NULL) || (strcmp(*value,"")==0)) msOpt = 0;
|
||||
else if(strstr(*value,"NMS")) msOpt = 0;
|
||||
else if(strstr(*value,"MS")) msOpt = pvlOptMS;
|
||||
else strcpy(*verify,"Illegal. Chose a value");
|
||||
@@ -2661,6 +2719,11 @@ long dbPutForm(DBENTRY *pdbentry,char **value)
|
||||
|
||||
pstr = *value;
|
||||
**verify = 0;
|
||||
value++; verify++;
|
||||
**verify = 0; /*Initialize verify to NULL*/
|
||||
if((*value==NULL) || (strcmp(*value,"")==0)) ppOpt = 0;
|
||||
else if(strstr(*value,"CA")) ppOpt = pvlOptCA;
|
||||
else strcpy(*verify,"Illegal. Chose a value");
|
||||
putPvLink(pdbentry,ppOpt|msOpt,pstr);
|
||||
}
|
||||
break;
|
||||
@@ -3016,6 +3079,8 @@ long dbCvtLinkToConstant(DBENTRY *pdbentry)
|
||||
plink->value.constantStr =
|
||||
dbCalloc(strlen(pflddes->initial)+1,sizeof(char));
|
||||
strcpy(plink->value.constantStr,pflddes->initial);
|
||||
} else {
|
||||
plink->value.constantStr = NULL;
|
||||
}
|
||||
return(0);
|
||||
default:
|
||||
|
||||
@@ -34,12 +34,7 @@
|
||||
#define INCdbStaticLibh 1
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <ellLib.h>
|
||||
#include <dbDefs.h>
|
||||
#include <dbFldTypes.h>
|
||||
#include <dbBase.h>
|
||||
#include <link.h>
|
||||
@@ -118,6 +113,7 @@ int dbGetNRecdes(DBENTRY *pdbentry);
|
||||
long dbFirstFielddes(DBENTRY *pdbentry,int dctonly);
|
||||
long dbNextFielddes(DBENTRY *pdbentry,int dctonly);
|
||||
char **dbGetChoices(DBENTRY *pdbentry);
|
||||
void dbDumpRecDes(DBBASE *pdbbase,char *recordTypeName);
|
||||
/*End obsolete routines*/
|
||||
|
||||
long dbFindRecordType(DBENTRY *pdbentry,char *recordTypename);
|
||||
@@ -207,6 +203,6 @@ extern int dbStaticDebug;
|
||||
#define S_dbLib_nameLength (M_dbLib|17) /*Record Name is too long*/
|
||||
#define S_dbLib_noRecSup (M_dbLib|19) /*Record support not found*/
|
||||
#define S_dbLib_strLen (M_dbLib|21) /*String is too long*/
|
||||
#define S_dbLib_noSizeOffset (M_dbLib|23) /*Missing SizeOffset Routine*/
|
||||
#define S_dbLib_noSizeOffset (M_dbLib|23) /*Missing SizeOffset Routine - No record support?*/
|
||||
#define S_dbLib_noForm (M_dbLib|25) /*dbAllocForm was not called*/
|
||||
#endif /*INCdbStaticLibh*/
|
||||
|
||||
@@ -164,6 +164,7 @@ int dbIsDefaultValue(DBENTRY *pdbentry)
|
||||
{
|
||||
dbFldDes *pflddes = pdbentry->pflddes;
|
||||
void *pfield = pdbentry->pfield;
|
||||
char *endp;
|
||||
|
||||
if(!pflddes) return(FALSE);
|
||||
switch (pflddes->field_type) {
|
||||
@@ -182,13 +183,19 @@ int dbIsDefaultValue(DBENTRY *pdbentry)
|
||||
case DBF_DOUBLE:
|
||||
case DBF_ENUM:
|
||||
if(!pfield) return(TRUE);
|
||||
if(!pflddes->initial) return(FALSE);
|
||||
if(!pflddes->initial) {
|
||||
if((strtod((char *)pfield,&endp)==0.0) && (*endp=='\0'))
|
||||
return(TRUE);
|
||||
return(FALSE);
|
||||
}
|
||||
return(strcmp((char *)pfield,(char *)pflddes->initial)==0);
|
||||
case DBF_MENU: {
|
||||
unsigned short val,ival;
|
||||
unsigned short val=0;
|
||||
unsigned short ival;
|
||||
|
||||
if(!pfield) return(FALSE);
|
||||
val = *(unsigned short *)pfield;
|
||||
if(pfield) val = *(unsigned short *)pfield;
|
||||
if(!pfield || pflddes->initial == 0)
|
||||
return((val==0)?TRUE:FALSE);
|
||||
if(pflddes->initial == 0) return((val==0)?TRUE:FALSE);
|
||||
sscanf(pflddes->initial,"%hu",&ival);
|
||||
return((val==ival)?TRUE:FALSE);
|
||||
@@ -212,8 +219,12 @@ int dbIsDefaultValue(DBENTRY *pdbentry)
|
||||
|
||||
if(!plink) return(FALSE);
|
||||
if(plink->type!=CONSTANT) return(FALSE);
|
||||
if(plink->value.constantStr == 0) return(TRUE);
|
||||
if(!pflddes->initial) return(FALSE);
|
||||
if(!plink->value.constantStr) return(TRUE);
|
||||
if(!pflddes->initial) {
|
||||
if((strtod((char *)plink->value.constantStr,&endp)==0.0)
|
||||
&& (*endp=='\0')) return(TRUE);
|
||||
return(FALSE);
|
||||
}
|
||||
if(strcmp(plink->value.constantStr,pflddes->initial)==0)
|
||||
return(TRUE);
|
||||
return(FALSE);
|
||||
|
||||
@@ -602,7 +602,7 @@ void dbGetRecordtypeSizeOffset(dbRecordType *pdbRecordType)
|
||||
if (vxstatus != OK) {
|
||||
status = S_dbLib_noSizeOffset;
|
||||
errPrintf(status,__FILE__,__LINE__,"%s",name);
|
||||
taskSuspend(0);
|
||||
return;
|
||||
}
|
||||
sizeOffset(pdbRecordType);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user