diff --git a/.appveyor.yml b/.appveyor.yml index 71e7d0b..5e9cb5b 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -3,6 +3,12 @@ # This is YAML - indentation levels are crucial +#---------------------------------# +# build cache # +#---------------------------------# +# The AppVeyor cache allowance is way too small (1GB per account across all +# projects, branches and jobs) to be used for the dependency builds. + cache: - C:\Users\appveyor\.tools @@ -12,17 +18,13 @@ cache: init: # Set autocrlf to make batch files work - - git config --global core.autocrlf true + - cmd: git config --global core.autocrlf true clone_depth: 5 -# Skipping commits affecting only specific files -skip_commits: - files: - - 'documentation/*' - - '.github/*' - - '**/*.md' - - '.readthedocs.yml' +#---------------------------------# +# build matrix configuration # +#---------------------------------# # Build Configurations: dll/static, regular/debug configuration: @@ -35,26 +37,25 @@ configuration: environment: # common / default variables for all jobs SETUP_PATH: .ci-local + EPICS_TEST_IMPRECISE_TIMING: YES BASE: 7.0 matrix: - CMP: vs2019 + BASE: 3.15 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - CMP: vs2019 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - BASE: 3.15 - CMP: vs2017 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - CMP: vs2015 - - CMP: vs2013 - CMP: gcc APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 # TODO: static linking w/ readline isn't working. Bypass auto-detect COMMANDLINE_LIBRARY: EPICS # Platform: processor architecture -platform: - - x64 +platform: x64 # Matrix configuration: exclude sets of jobs matrix: @@ -92,9 +93,9 @@ on_failure: # debugging # #---------------------------------# -## if you want to connect by remote desktop to a failed build, uncomment these lines -## note that you will need to connect within the usual build timeout limit (60 minutes) -## so you may want to adjust the build matrix above to just build the one of interest +## To connect by remote desktop to a failed build, uncomment the lines below. +## You must connect within the usual build timeout limit (60 minutes), +## so adjust the build matrix above to just build the config of interest. #on_failure: # - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) @@ -105,4 +106,8 @@ on_failure: #---------------------------------# notifications: + - provider: Email + to: + - core-talk@aps.anl.gov + on_build_success: false - provider: GitHubPullRequest diff --git a/.github/workflows/ci-scripts-build.yml b/.github/workflows/ci-scripts-build.yml index 08fa6ee..90e3573 100644 --- a/.github/workflows/ci-scripts-build.yml +++ b/.github/workflows/ci-scripts-build.yml @@ -11,27 +11,13 @@ name: pvData on: push: paths-ignore: - - 'documentation/*' - - 'startup/*' - - '.appveyor/*' - - '.tools/*' - - '.gitattributes' - - '**/*.html' - - '**/*.md' + - .appveyor.yml pull_request: - paths-ignore: - - 'documentation/*' - - 'startup/*' - - '.appveyor/*' - - '.tools/*' - - '.gitattributes' - - '**/*.html' - - '**/*.md' env: SETUP_PATH: .ci-local:.ci EPICS_TEST_IMPRECISE_TIMING: YES - EPICS_TEST_TIMEOUT: 300 # 5 min (RTEMS epicsMessageQueue is slowest) + EPICS_TEST_TIMEOUT: 300 # 5 min jobs: native: @@ -39,7 +25,8 @@ jobs: runs-on: ${{ matrix.os }} # Set environment variables from matrix parameters env: - BASE: "7.0" + # NB: PVA modules build against both BASE 7.0 and 3.15 + BASE: ${{ matrix.base }} CMP: ${{ matrix.cmp }} BCFG: ${{ matrix.configuration }} CI_CROSS_TARGETS: ${{ matrix.cross }} @@ -50,9 +37,11 @@ jobs: matrix: # Job names also name artifacts, character limitations apply include: - - os: ubuntu-22.04 - cmp: gcc-12 - name: "Ub-22 gcc-12 c++20 Werror" + - name: "7.0 Ub gcc c++20 Werror" + base: "7.0" + os: ubuntu-latest + cmp: gcc + configuration: default # Turn all warnings into errors, # except for those we could not fix (yet). # Remove respective -Wno-error=... flag once it is fixed. @@ -73,127 +62,139 @@ jobs: -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3' CMD_LDFLAGS=-Wl,-z,relro" - - os: ubuntu-20.04 - cmp: gcc - configuration: default - cross: "windows-x64-mingw" - name: "Ub-20 gcc + MinGW" - - - os: ubuntu-20.04 - cmp: gcc - configuration: static - cross: "windows-x64-mingw" - name: "Ub-20 gcc + MinGW, static" - - - os: ubuntu-20.04 + - name: "7.0 Ub gcc C++11, static" + base: "7.0" + os: ubuntu-latest cmp: gcc configuration: static extra: "CMD_CXXFLAGS=-std=c++11" - name: "Ub-20 gcc C++11, static" - - os: ubuntu-20.04 + - name: "7.0 Ub gcc u-char" + base: "7.0" + os: ubuntu-latest cmp: gcc configuration: static extra: "CMD_CFLAGS=-funsigned-char CMD_CXXFLAGS=-funsigned-char" - name: "Ub-20 gcc unsigned char" - - os: ubuntu-20.04 + - name: "7.0 Ub clang" + base: "7.0" + os: ubuntu-latest cmp: clang configuration: default - name: "Ub-20 clang" - - os: ubuntu-20.04 + - name: "7.0 Ub clang C++11" + base: "7.0" + os: ubuntu-latest cmp: clang configuration: default extra: "CMD_CXXFLAGS=-std=c++11" - name: "Ub-20 clang C++11" - - os: ubuntu-20.04 + - name: "7.0 MacOS clang" + base: "7.0" + os: macos-latest + cmp: clang + configuration: default + + # Cross builds + + - name: "3.15 Ub-22 gcc + MinGW" + base: "3.15" + os: ubuntu-22.04 cmp: gcc configuration: default - cross: "RTEMS-pc686-qemu@5" - name: "Ub-20 gcc + RT-5.1 pc686" + cross: "windows-x64-mingw" - - os: ubuntu-20.04 + - name: "7.0 Ub gcc + linux-aarch64" + base: "7.0" + os: ubuntu-latest cmp: gcc configuration: default - cross: "RTEMS-beatnik@5" - test: NO - name: "Ub-20 gcc + RT-5.1 beatnik" + cross: "linux-aarch64" - - os: ubuntu-20.04 + - name: "7.0 Ub gcc + linux-arm gnueabi" + base: "7.0" + os: ubuntu-latest cmp: gcc configuration: default - cross: "RTEMS-xilinx_zynq_a9_qemu@5" - test: NO - name: "Ub-20 gcc + RT-5.1 xilinx_zynq_a9_qemu" + cross: "linux-arm@arm-linux-gnueabi" - - os: ubuntu-20.04 + - name: "7.0 Ub gcc + linux-arm gnueabihf" + base: "7.0" + os: ubuntu-latest cmp: gcc configuration: default - cross: "RTEMS-uC5282@5" - test: NO - name: "Ub-20 gcc + RT-5.1 uC5282" + cross: "linux-arm@arm-linux-gnueabihf" - - os: ubuntu-20.04 + - name: "7.0 Ub gcc + MinGW" + base: "7.0" + os: ubuntu-latest + cmp: gcc + configuration: default + cross: "windows-x64-mingw" + + - name: "7.0 Ub gcc + MinGW, static" + base: "7.0" + os: ubuntu-latest + cmp: gcc + configuration: static + cross: "windows-x64-mingw" + + - name: "7.0 Ub-22 gcc + RT-4.9 pc386" + base: "7.0" + os: ubuntu-22.04 + cmp: gcc + configuration: default + cross: "RTEMS-pc386-qemu@4.9" + + - name: "7.0 Ub-22 gcc + RT-4.10 pc386" + base: "7.0" + os: ubuntu-22.04 cmp: gcc configuration: default - name: "Ub-20 gcc + RT-4.10" cross: "RTEMS-pc386-qemu@4.10" test: NO - - os: ubuntu-20.04 + - name: "7.0 Ub-22 gcc + RT-5.1 pc686" + base: "7.0" + os: ubuntu-22.04 cmp: gcc configuration: default - name: "Ub-20 gcc + RT-4.9" - cross: "RTEMS-pc386-qemu@4.9" + cross: "RTEMS-pc686-qemu@5" - - os: macos-latest - cmp: clang + - name: "7.0 Ub-22 gcc + RT-5.1 beatnik,zynq_a9,uC5282" + base: "7.0" + os: ubuntu-22.04 + cmp: gcc configuration: default - name: "MacOS clang" + cross: "RTEMS-beatnik@5:RTEMS-xilinx_zynq_a9_qemu@5:RTEMS-uC5282@5" + test: NO - - os: windows-2019 - cmp: vs2019 + # Windows builds + + - name: "7.0 Win-22 MSC-22" + base: "7.0" + os: windows-2022 + cmp: vs2022 + configuration: default + + - name: "7.0 Win-22 MSC-22 static" + base: "7.0" + os: windows-2022 + cmp: vs2022 + configuration: static + + - name: "7.0 Win-22 MSC-22 debug" + base: "7.0" + os: windows-2022 + cmp: vs2022 configuration: debug - name: "Win2019 MSC-19" - extra: "CMD_CXXFLAGS=-analysis" + extra: "CMD_CXXFLAGS=-analyze" - - os: windows-2019 - cmp: vs2019 - configuration: static-debug - name: "Win2019 MSC-19, static" - extra: "CMD_CXXFLAGS=-analysis" - - - os: windows-2019 - cmp: vs2019 - configuration: debug - name: "Win2019 MSC-19, debug" - - - os: windows-2019 + - name: "7.0 Win-22 MinGW" + base: "7.0" + os: windows-2022 cmp: gcc configuration: default - name: "Win2019 mingw" - - # Linux cross builds - - - os: ubuntu-latest - cmp: gcc - configuration: default - name: "Cross linux-aarch64" - cross: linux-aarch64 - - - os: ubuntu-latest - cmp: gcc - configuration: default - name: "Cross linux-arm gnueabi" - cross: linux-arm@arm-linux-gnueabi - - - os: ubuntu-latest - cmp: gcc - configuration: default - name: "Cross linux-arm gnueabihf" - cross: linux-arm@arm-linux-gnueabihf steps: - uses: actions/checkout@v4 @@ -230,7 +231,7 @@ jobs: image: ${{ matrix.image }} # Set environment variables from matrix parameters env: - BASE: "7.0" + BASE: ${{ matrix.base }} CMP: ${{ matrix.cmp }} BCFG: ${{ matrix.configuration }} EXTRA: ${{ matrix.extra }} @@ -240,63 +241,54 @@ jobs: matrix: # Job names also name artifacts, character limitations apply include: - #- name: "CentOS-7" - # image: centos:7 - # cmp: gcc - # configuration: default + - name: "7.0 CentOS-8 gcc" + base: "7.0" + image: centos:8 + cmp: gcc + configuration: default - - name: "Fedora-33" + - name: "7.0 Rocky-9 gcc" + base: "7.0" + image: rockylinux:9 + cmp: gcc + configuration: default + + - name: "7.0 Fedora-33 gcc" + base: "7.0" image: fedora:33 cmp: gcc configuration: default - - name: "Fedora-latest" + - name: "7.0 Fedora gcc" + base: "7.0" image: fedora:latest cmp: gcc configuration: default steps: - - name: "Build newer Git" - # actions/checkout@v2 wants git >=2.18 - # centos:7 has 1.8 - if: matrix.image=='centos:7' + - name: "Fix repo URLs on CentOS-8" + # centos:8 is frozen, repos are in the vault + if: matrix.image=='centos:8' run: | - yum -y install curl make gcc curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-MakeMaker - curl https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.29.0.tar.gz | tar -xz - cd git-* - make -j2 prefix=/usr/local all - make prefix=/usr/local install - cd .. - rm -rf git-* - type -a git - git --version + sed -i -e "s|mirrorlist=|#mirrorlist=|" \ + -e "s|#baseurl=http://mirror|baseurl=http://vault|" \ + /etc/yum.repos.d/CentOS-Linux-{BaseOS,AppStream,Extras,Plus}.repo - name: "Redhat setup" run: | - dnfyum() { - dnf -y "$@" || yum -y "$@" - return $? - } - dnfyum install python3 gdb make perl gcc-c++ glibc-devel readline-devel ncurses-devel perl-devel perl-Test-Simple - git --version || dnfyum install git - # rather than just bite the bullet and link python3 -> python, - # people would rather just break all existing scripts... - [ -e /usr/bin/python ] || ln -sf python3 /usr/bin/python - python --version + dnf -y install python3 gdb make perl gcc-c++ glibc-devel readline-devel ncurses-devel perl-devel perl-Test-Simple + git --version || dnf -y install git + python3 --version - uses: actions/checkout@v4 with: submodules: true - name: Automatic core dumper analysis uses: mdavidsaver/ci-core-dumper@master - if: matrix.image!='centos:7' - - name: Automatic core dumper analysis - uses: mdavidsaver/ci-core-dumper@node16 - if: matrix.image=='centos:7' - name: Prepare and compile dependencies - run: python .ci/cue.py prepare + run: python3 .ci/cue.py prepare - name: Build main module - run: python .ci/cue.py build + run: python3 .ci/cue.py build - name: Run main module tests - run: python .ci/cue.py -T 20M test + run: python3 .ci/cue.py -T 20M test - name: Upload tapfiles Artifact if: ${{ always() }} uses: actions/upload-artifact@v4 @@ -306,4 +298,4 @@ jobs: if-no-files-found: ignore - name: Collect and show test results if: ${{ always() }} - run: python .ci/cue.py -T 5M test-results + run: python3 .ci/cue.py -T 5M test-results diff --git a/Doxyfile b/Doxyfile index 058e148..6358c5d 100644 --- a/Doxyfile +++ b/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "PVData C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 8.0.7-dev +PROJECT_NUMBER = 8.0.8-dev # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/configure/CONFIG_PVDATA_VERSION b/configure/CONFIG_PVDATA_VERSION index c23c6e0..69bc6c3 100644 --- a/configure/CONFIG_PVDATA_VERSION +++ b/configure/CONFIG_PVDATA_VERSION @@ -2,7 +2,7 @@ EPICS_PVD_MAJOR_VERSION = 8 EPICS_PVD_MINOR_VERSION = 0 -EPICS_PVD_MAINTENANCE_VERSION = 7 +EPICS_PVD_MAINTENANCE_VERSION = 8 # Development flag, set to zero for release versions diff --git a/documentation/Doxyfile b/documentation/Doxyfile index 92eeff4..6536ad1 100644 --- a/documentation/Doxyfile +++ b/documentation/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "PVData C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 8.0.7-dev +PROJECT_NUMBER = 8.0.8-dev # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/documentation/release_notes.dox b/documentation/release_notes.dox index 25d30a9..06bf896 100644 --- a/documentation/release_notes.dox +++ b/documentation/release_notes.dox @@ -2,6 +2,14 @@ @page release_notes Release Notes +Release 8.0.7 (Dec 2025) +======================== + +- Compatible changes + - Allow epics::pvData::Timer to be cancelled during callback execution. + - Clang compiler warnings cleaned up. + - Limit periodic timers to one catch-up after missing many events. + Release 8.0.6 (Dec 2023) ======================== diff --git a/src/factory/FieldCreateFactory.cpp b/src/factory/FieldCreateFactory.cpp index db5595e..6d08835 100644 --- a/src/factory/FieldCreateFactory.cpp +++ b/src/factory/FieldCreateFactory.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -378,7 +379,8 @@ BoundedScalarArray::BoundedScalarArray(ScalarType elementType, size_t size) string BoundedScalarArray::getID() const { char buffer[32]; - sprintf(buffer, "%s<%zu>", ScalarTypeFunc::name(getElementType()), size); + epicsSnprintf(buffer, sizeof(buffer), "%s<%lu>", + ScalarTypeFunc::name(getElementType()), (unsigned long) size); return string(buffer); } @@ -403,7 +405,8 @@ FixedScalarArray::FixedScalarArray(ScalarType elementType, size_t size) string FixedScalarArray::getID() const { char buffer[32]; - sprintf(buffer, "%s[%zu]", ScalarTypeFunc::name(getElementType()), size); + epicsSnprintf(buffer, sizeof(buffer), "%s[%lu]", + ScalarTypeFunc::name(getElementType()), (unsigned long) size); return string(buffer); } diff --git a/src/misc/pv/timer.h b/src/misc/pv/timer.h index 83146d5..18c6e84 100644 --- a/src/misc/pv/timer.h +++ b/src/misc/pv/timer.h @@ -60,6 +60,8 @@ private: epicsTime timeToRun; double period; bool onList; + bool cancelled; + bool processing; friend class Timer; struct IncreasingTime; }; diff --git a/src/misc/timer.cpp b/src/misc/timer.cpp index 14a207b..4990051 100644 --- a/src/misc/timer.cpp +++ b/src/misc/timer.cpp @@ -23,7 +23,9 @@ namespace epics { namespace pvData { TimerCallback::TimerCallback() : period(0.0), - onList(false) + onList(false), + cancelled(false), + processing(false) { } @@ -50,6 +52,7 @@ void Timer::addElement(TimerCallbackPtr const & timerCallback) temp.push_back(timerCallback); timerCallback->onList = true; + timerCallback->cancelled = false; // merge sorted lists. // for us effectively insertion sort. @@ -60,6 +63,11 @@ void Timer::addElement(TimerCallbackPtr const & timerCallback) bool Timer::cancel(TimerCallbackPtr const &timerCallback) { Lock xx(mutex); + /* If we're processing, just set the cancel flag */ + if (timerCallback->processing) { + timerCallback->cancelled = true; + return true; + } if(!timerCallback->onList) return false; if(!alive) { timerCallback->onList = false; @@ -107,6 +115,7 @@ void Timer::run() TimerCallbackPtr work; work.swap(queue.front()); work->onList = false; + work->processing = true; queue.pop_front(); { @@ -115,7 +124,15 @@ void Timer::run() work->callback(); } - if(work->period > 0.0 && alive) { + work->processing = false; + + if(work->period > 0.0 && alive && !work->cancelled) { + if(waitfor <= -work->period) { + // Periodic timer phase has fallen behind by at least one full period. + // Could be due to previous slow jobs, or a system time jump forward. + // Reset the phase. + work->timeToRun = now = epicsTime::getCurrent(); + } work->timeToRun += work->period; addElement(work); } diff --git a/testApp/misc/testByteBuffer.cpp b/testApp/misc/testByteBuffer.cpp index ff26f06..dca0ac2 100644 --- a/testApp/misc/testByteBuffer.cpp +++ b/testApp/misc/testByteBuffer.cpp @@ -14,6 +14,11 @@ #include #include +// allow to test deprecated functions without causing compiler warnings +#include +#undef EPICS_DEPRECATED +#define EPICS_DEPRECATED + #include #include diff --git a/testApp/pv/performstruct.cpp b/testApp/pv/performstruct.cpp index 7abf1a8..0b78ac0 100644 --- a/testApp/pv/performstruct.cpp +++ b/testApp/pv/performstruct.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -54,7 +55,7 @@ void buildMiss() for(size_t i=0; i<1000; i++) { // unique name each time to (partially) defeat caching char buf[10]; - sprintf(buf, "field%zu", i); + epicsSnprintf(buf, sizeof(buf), "field%lu", (unsigned long) i); record.start();