Öffnet in neuem Fenster Opens in a new window Öffnet externe Seite Opens an external site Öffnet externe Seite in neuem Fenster Opens an external site in a new window

Changelog

Changelog of CA Lab

V1.8.0.2 (Released: January 2026)

### CALab – Ultra‑Short Changelog (User‑Focused)

* Faster EPICS connections and updates (tuned CA timeouts, 
  background polling). 
* More robust, thread‑safe operation in LabVIEW; fewer hangs
  on abort/stop and during heavy parallel use. 
* Richer per‑PV results: values, status/severity, timestamps, 
  record fields, and per‑PV error information. 
* Clearer diagnostics via the `info` API and a global PV error counter
  for quick health checks.
* Improved Linux support with runtime loading of EPICS libraries,
  avoiding hard build‑time dependencies.
* Improved numeric string parsing for comma/dot locales

### CALab – Full Changelog
----------------------------------------------------------------------
# Major architectural rewrite and threading model
* The core CALab implementation (`calab.cpp`, `globals.cpp`, 
  `PVItem.cpp` and supporting headers) has been extensively refactored
  for thread-safety and maintainability while keeping the LabVIEW API 
  and data structures stable.
* Introduced a central `Globals` singleton responsible for EPICS CA
  context management, the PV registry, per‑VI instance tracking,
  background worker registration, and coordinated shutdown.
* Added generic `TimeoutUniqueLock` and `TimeoutSharedLock` RAII
  wrappers for `std::mutex` / `std::shared_timed_mutex` that enforce
  acquisition timeouts and log detailed diagnostics when locks
  cannot be obtained in time, making deadlocks and long holds
  visible in the debug log.
* Clarified and enforced a lock hierarchy, consistently using
  shared/exclusive access on the PV registry to reduce contention
  between CA callbacks, LabVIEW calls, and background workers.

---

# EPICS interaction and Linux support

* On Linux, EPICS CA and libCom are now loaded dynamically via
  `epics_dynamic_linux.cpp` and the new compatibility shim
  `epics_compat.h`. This allows building and distributing CALab
  without EPICS headers on the build host and improves robustness
  when different EPICS versions are present at runtime.
* Added fall‑back text tables and optional environment accessors so
  CALab continues to work even when certain symbols (such as
  `dbr_text` or `envGetConfigParamPtr`) are not exported by the EPICS
  libraries.
* Unified EPICS context attach/detach logic through a new RAII helper
  `CaContextGuard`, ensuring that worker threads, callbacks, and all
  public entry points operate on a valid CA context.

---

# PV registry, instance management and teardown

* Introduced a more robust per‑VI instance model (`MyInstanceData`)
  with explicit lifecycle hooks (`reserved`, `unreserved`, `aborted`).
  Each instance tracks its bound LabVIEW handles, the first function
  that used it, an `activeCalls` counter, and an `isUnreserving` flag,
  enabling controlled teardown.
* Implemented a generic array‑to‑instance map in `Globals` to resolve
  which VI instance owns a given LabVIEW array handle. `getValue`,
  `putValue` and `addEvent` now reliably bind arrays to their owning
  instance even in multi‑VI and reentrant setups.
* Added a per‑instance call guard that increments `activeCalls` on
  entry and decrements it on exit. The guard blocks new calls while
  an instance is unreserving and wakes waiters on every exit,
  allowing `unreserved` to wait for all in‑flight EPICS operations
  to finish without risking deadlocks.
* The `unreserved` callback now performs a careful two‑phase
  teardown of the `PvIndexArray`. It atomically claims `PvIndexEntry`
  objects, waits (with timeout) until all readers drop their
  references, and then deletes entries either immediately or via a
  deferred deletion worker. This eliminates use‑after‑free scenarios
  that could previously occur during shutdown.
* `Globals::unregisterArraysForInstance` now removes all
  array‑to‑instance associations under a timed write lock,
  preventing stale mappings when an instance disappears.

---

# PvIndexArray and change tracking

* Reworked `PvIndexArray` entries: each slot now points to a 
  `PvIndexEntry` object holding a `PVItem*`, a `PVMetaInfo` block, an
  internal atomic reference counter and a deletion flag. Readers use
  `try_acquire()` / `release()` to safely share entries; deleters set
  `deleting=true` and reclaim entries once `refs` drops to zero.
* `PVMetaInfo` caches the last change‑hash of its `PVItem` and exposes
  `hasChanged()` / `update()` helpers. `getValue` uses this to detect
  unchanged PVs without copying payloads, which makes large PV arrays
  much cheaper to poll.
* New helpers around `PvIndexArray` update the stored change‑hash
  either globally or only for changed indices, keeping tracking
  consistent even when only a subset of PVs is refreshed.

---

# Background worker for value changes

* CALab now decouples EPICS value‑change callbacks from PV updates by
  queuing change events into a dedicated background worker 
  (a `ValueChangeTask` deque). The worker thread looks up the
  corresponding `PVItem`, updates its cached DBR buffer, time
  metadata, status and severity, and then notifies subscribers.
* The worker uses `TimeoutSharedLock` for PV registry lookups and
  `TimeoutUniqueLock` on the per‑PV mutex; failures to acquire locks
  within bounded time produce clear debug messages instead of blocking
  indefinitely.
* When `.RTYP` PVs update, the worker automatically propagates the
  record type to the parent base PV. For other field PVs 
  (`BASE.FIELD`), the latest field value is cached as a string on the
  parent `PVItem`, with careful numeric‑to‑string conversion when the
  field is numeric.
* After processing each task, the worker notifies interested LabVIEW
  subscribers via `postEventForPv`, which snapshots subscribers,
  fills their `sResult` clusters from the current `PVItem` state,
  and posts user events outside of internal locks.

---

# LabVIEW user event handling

* Introduced an explicit `EventRegistry` that maps PV names to 
  `(LVUserEventRef, sResult*)` pairs. `addEvent` ensures that the
  target `PVItem` exists in the PV registry, registers the event, and
  optionally posts an event immediately if the PV already has a value.
* `destroyEvent` now walks the entire event registry and removes every
  occurrence of the given `LVUserEventRef`, deleting empty PV entries.
  This avoids dangling references and keeps the registry compact.
* `postEventForPv` snapshots subscribers while holding the registry’s
  event mutex and posts LabVIEW events without that lock held,
  preventing reentrancy problems and potential deadlocks with user code.

---

# Numeric formatting and PREC handling

* The `PVItem::FormatUnit` numeric formatting logic has been
  completely rewritten. It now fully respects the `PREC` field for all
  numeric record types, switching to scientific notation when a value
  is too small to be represented reasonably in fixed notation at the
  requested precision.
* Formatting is locale‑aware: decimal and thousands separators are
  chosen based on the current C++ locale of the calling thread. For
  integer‑like values with `PREC=0`, thousands separators are inserted
  while preserving the sign.
* When no `PREC` is available, CALab uses heuristics to avoid
  floating‑point artefacts: it finds a small number of decimal places
  that round the value cleanly within a tolerance, trims trailing
  zeros, removes a trailing decimal point if necessary, and switches
  to scientific notation for very large or very small values.

---

# getValue / putValue behaviour and error reporting

* `getValue` has been restructured into clear phases: instance
  resolution and binding, call‑guard activation, PV registry/field
  initialization, subscription and connection handling, 
  change detection, and output population. This makes the control flow
  more predictable and ensures concurrent calls coordinate correctly
  via per‑instance `activeCalls`.
* When only a subset of PVs has changed, CALab now incrementally
  cleans and repopulates only the affected entries in `ResultArray`,
  `FirstStringValue`, `FirstDoubleValue`, and `DoubleValueArray`.
  This significantly reduces LabVIEW heap churn for large PV arrays.
* Memory cleanup has been centralised in `CleanupResult` and
  `cleanupMemory`, which now support both full teardown and selective
  cleanup based on a list of changed indices. Any errors from the
  LabVIEW memory manager are logged with timestamps and error codes.
* `fillResultFromPv` always pulls the current error state from `PVItem`
  into the `ErrorIO` cluster and skips updating the error string when
  the code and string are unchanged, avoiding unnecessary allocations
  during steady‑state operation.
* `putValue` has been refactored around a `PutValueCtx` helper that
  handles string, double and 64‑bit integer sources
  (`StringValueArray2D`, `DoubleValueArray2D`, `LongValueArray2D`).
  It performs robust type checking, clamps values to EPICS native
  ranges where needed, and records per‑PV error messages on conversion
  failures.
* When `wait4readback` is true, CALab uses `ca_put_callback` and a
  small `PutCtx` object to track callback completions, waiting up to
  the specified timeout while interleaving `ca_pend_event()` calls
  with internal notifications. If any callbacks time out, the
  communication status is set accordingly.

---

# disconnectPVs and communication status

* `disconnectPVs` has been rewritten to minimise the time spent
  holding the PV registry lock. It first collects the `PVItem` objects
  to disconnect (either all PVs or a deduplicated, parent‑aware subset
  of the requested names) under a shared lock, then releases the lock
  and performs channel clear / connection teardown work outside the
  critical section.
* When called with `All=true`, `disconnectPVs` now first checks
  whether more than one VI instance currently has active CALab arrays
  and refuses to disconnect in that case, preventing one VI from
  inadvertently disconnecting PVs used by others.
* The global PV error counter and per‑PV error codes now feed into
  `CommunicationStatus`: a non‑zero status is reported only when
  at least one addressed PV is currently in an error state, rather
  than treating any historic error as a permanent global failure.

---

# info() and diagnostic visibility

* `info()` has been expanded to report CALab version (including build
  type and word size), the compiled‑against EPICS base version, 
  the CA protocol version, all EPICS environment variables known via
  `env_param_list`, and CALab‑specific environment variables
  (`CALAB_POLLING`, `CALAB_NODBG`).
* New helper `populateInfoStringArray` writes this data into a 2D
  LabVIEW string array of (key, value) rows, correctly disposing and
  reallocating internal string handles when dimensions change and
  avoiding stale data when shrinking.
* `populateAllResultArray` builds a snapshot of all base PVs currently
  in the registry, sorted by PV name, and fills an `sResultArrayHdl`
  using the same logic as `fillResultFromPv`, giving `CaLabInfo.vi`
  a consistent view of all PVs, including status, severity, timestamp,
  fields and error information.

---

# Record field validation and metadata

* New methods in `Globals` (`recordFieldIsCommonField` and
  `recordFieldExists`) validate whether a field name is valid for a
  given EPICS record type, using a comprehensive hard‑coded field list
  plus a small cache. This prevents CALab from trying to connect to
  obviously non‑existent field PVs and improves behaviour when users
  request invalid fields.
* Field PV updates now populate a per‑PV field map on the parent
  `PVItem` with human‑readable string values. `getValue` uses this
  cache to fill `FieldNameArray` and `FieldValueArray` without extra
  EPICS lookups, so applications can access record fields efficiently.

---

# Miscellaneous improvements

* All public and internal headers (`calab.h`, `globals.h`, `PVItem.h`,
  `TimeoutUniqueLock.h`, `epics_compat.h`) have been thoroughly
  documented with clearer comments on ownership, threading rules and
  semantics. This documentation work does not change the binary
  interface but makes the codebase significantly easier to understand
  and maintain.
* Debug output is now centralised through `CaLabDbgPrintf` /
  `CaLabDbgPrintfD` and enriched with timestamps and contextual tags
  (function names, lock names, PV names), making diagnostics for
  timing issues and deadlocks much more straightforward.
* Many internal error paths have been hardened: all LabVIEW memory
  allocations are checked, exceptions in DLL entry points are caught
  and logged, and defensive checks prevent further work once the
  global `stopped` flag indicates that CALab is shutting down.

----------------------------------------------------------------------

V1.7.5.1
  # Updated EPICS Base to Version 7.0.9
  # Filter fixed
  # CaLabGet returns bad status if some PV don't connect now
  # PV initialisation with ECA_CHIDNOTFND before first value
  # Code optimisations and many more code comments
  # Updated lib VIs and example VIs

----------------------------------------------------------------------
V1.7.4.1 (Released: December 2024)
  # Resolved Windows Setup Issues
    - Added "Install for all users"
    - Fixed issues with the custom installation location
    - Automated PATH variable configuration
    - Enhanced the post-installation page
  # Improved path search for EPICS components in certain VIs
  # Updated VC Redist to Version 14.42.34433.0
  # Updated EPICS Base to Version 7.0.8.2
  Fixed crash when enabling field values without field names enabled

----------------------------------------------------------------------
V1.7.3.3  (Released: June 2024)
  + When the PREC field is queried, the string output of the values is
    formatted accordingly in CaLabGet.vi. This enhancement applies
    only to EPICS records that support the PREC field.
  + The EPICS record type and the native EPICS data type are now also
    displayed in the PVList in CaLabInfo.vi.
  + Added utilities-VIs to add/remove CA Lab to/from palette set (LV)
  ! To avoid confusion with the programming terminology,
    in the caLabPut.vi the label of the input "synchronous"
    has been changed to "wait". (The VI is 100% backward compatible.)
  # Resolved the 39-character string bug.
  # Fixed issues with 64-bit record handling for large numbers.
  # Fixed data type conversationFixed problems with inactive Epics
    variables at the time of programme start.
  # Minor improvements of the SoftIOC Demo.vi
  # The setup no longer requires admin rights.
  # The CA Lab libraries and VIs are now saved under %APPDATA%\calab.

----------------------------------------------------------------------
V1.7.3.2
  # Fixed problems with inactive Epics variables
    at the time of programme start.

----------------------------------------------------------------------
V1.7.3.1
  # Support of different number or order of fields in CaLabGet/Event
  # CaLabInfo.vi: PV list now has alphabetically sorted PVs names

----------------------------------------------------------------------
V1.7.3.0
  # Fixed some output filter issues
  # Improved "SoftIOC Demo.vi"
  - Support discontinued for LabVIEW versions older than 2019
  - Support discontinued for the 32-bit version of CA Lab on Linux

----------------------------------------------------------------------
Last version with 32-bit support of CA Lab on Linux
(LabVIEW Community Edition (32-bit) on Windows is still supported)
Last version with backward compatibility up to LabVIEW 8.5

V1.7.2.2 (Released: February 2023)
  # Fixed misleading warning "Missing values to write"
  # Memory leak on write fixed (mode: "variable PV names" = TRUE)
  # Support for EPICS base 7.0.7 is back

----------------------------------------------------------------------
V1.7.2.1 (Released: December 2022)
  # fall back to EPICS base 7.0.4.1
    (working on fix for 7.0.7)

----------------------------------------------------------------------
V1.7.2.0 (Released: November 2022)
  + Compatible with NI Linux Real-Time x86
  + CaLabSoftIoc is now native LabVIEW code (calabioc.dll is no longer needed)
  + CaLabSoftIoc now also works under Linux
  + CaLabInit and CaLabGet has an optional output filter now
    (this can save ressources and increase performance)
    Following values can be combined with OR:
        PV indicators:
            firstValueAsString = 1
            firstValueAsNumber = 2
            valueArrayAsNumber = 4
            errorOut = 8
        PV Info cluster:
            pviElements = 16
            pviValuesAsString = 32
            pviValuesAsNumber = 64
            pviStatusAsString = 128
            pviStatusAsNumber = 256
            pviSeverityAsString = 512
            pviSeverityAsNumber = 1024
            pviTimestampAsString = 2048
            pviTimestampAsNumber = 4096
            pviFieldNames = 8192
            pviFieldValues = 16384
            pviError = 32768
  # Fixed multiple instances of PVs in "myItems" map
  # Fixed crash of negative enums
  # Added mutex for writing PVs
  # EPICS base 7.0.7
  # Some clean up in VIs

----------------------------------------------------------------------
V1.7.1.1 (Released: August 2022)
  # restoring some insignificant VI input defaults
    from previous versions v1.7.0.1 to v1.7.0.6
  # adaptations of the examples

----------------------------------------------------------------------
V1.7.1.0 (Released: August 2022)
  # EPICS base 7.0.6.1
  # solved the conflict when unloading libraries
    (this was the reason for the withdrawal of versions V1.7.0.x)
  # User Events revised
  # Internal search algorithm reworked
  # Improved performance for large number of variables (>1.000)
  # Added Parallel Event Demo.vi (LabVIEW 2019 and later)
  # Updated instructions for Linux users
  # Published Code at GitHub https://github.com/epics-extensions/CALab
  # Additional software developer Brian Powell - A warm welcome!

----------------------------------------------------------------------
December 2020
  versions V1.7.0.x were withdrawn because they did not run
  sufficiently stable
  fall back to stable version V1.6.0.11

----------------------------------------------------------------------
V1.7.0.6 (Released: September 2020)
  # EPICS base 7.0.4.1
  # BUGFIX caLabPut.vi: fixed memory leak in mode "variable PV names"
  # BUGFIX: CaLabGet "Value array (number)" (2D arrays only)
  # BUGFIX: Put_DBL-1D_PV.vi and Put_I64-1D_PV-1D.vi
            input "Synchronous (F)" is recommend
  # BUGFIX: CaLabEvent_PV.vi and CaLabPut_Main_Initialized.vi
            input "PV name(s)" is required
  + Improved performance for caLabPut and caLabGet (large byte arrays)

----------------------------------------------------------------------
V1.7.0.3 (Released: August 2020)
  # BUGFIX caLabGet.vi: sometimes 0 elements in result when Timeout=1s

----------------------------------------------------------------------
V1.7.0.2 (Released: July 2020)
  + Added warning for duplicate PV names

----------------------------------------------------------------------
V1.7.0.1 (Released: June 2020)
  # EPICS base 7.0.4
  ! CA Lab is now running as a service and will only be terminated
    when LabVIEW is fully terminated.
  ! CHANGED default value of the input connector "variable PV names"
    to TRUE (the previous default value was confusing)
    More info: https://hz-b.de/calab => caLabGet.vi / caLabPut.vi
  ! CHANGED data type of the input connector "Timeout" to integer
  # BUGFIX in CaLabSoftIoc.vi: input field "Data Type" had a blank
    space for "bo" (Thanks to Lee)
  # BUGFIX in CaLabSoftIOC.vi @64bit: detecting of the softIoc.exe
  + ADDED value range (1-255) for the input connector "Timeout"

----------------------------------------------------------------------
V1.6.0.11 (Released: March 2020)
# BUGFIX 60 characters support for CaLabSoftIOC.vi
# EPICS base 3.14.12.8
# Debug window shows more details

----------------------------------------------------------------------
V1.6.0.10 (Released: June 2018)
  # PV names can use 60 characters now
  # constantly changing PV names can be used again (input connector
    'variable PV names' must be set true)
    Remark: You will get better performance without this option

----------------------------------------------------------------------
V1.6.0.9 (Released: March 2018)
  # fixed multithreaded write values
  # fixed default input type for name in "CaLabPut.vi"
  # corrected "Event Demo.vi"

----------------------------------------------------------------------
V1.6.0.8 (Released: March 2018)
  + "CaLabDisconnect.vi": Now you can disconnect several or all
     EPICS variables from network without closing all CaLab-VIs
  + "CaLabInit.vi": Now you can initialize Channel Access Variables
     before using in "CaLabGet.vi" and "CaLabPut.vi"
  + Field values with enums are displayed with correct enum string now
  # EPICS base 3.14.12.7
  # Update of online documentation
  # Online documentation moved to http://hz-b.de/calab
  - Input "ValueSetsInColums" removed
  ! Please, replace old CA Lab VIs! The new VIs fit into old structures.

----------------------------------------------------------------------
V1.5.1.0 (Released: January 2016)
  + CaLabGet.vi: added optional parameter NoMDEL
                 NoMEL=true -> ignore monitor dead-band
                            -> deactivated caching of values
  - CaLabGet.vi: connector "Initialize" removed
  # CaLabEvent.vi: restart issues fixed
  # EPICS base 3.14.12.5
  # VI versioning started
  # Update of examples
  # Update of online documentation

----------------------------------------------------------------------
V1.5.0.5 (Released: August 2014)
  + Environment variable for redirecting debug window output to a file
        CALAB_NODBG = PATH_NAME_OF_LOG_FILE
  + Environment variable for switching off monitoring EPICS variables
    This is useful to avoid permanent open network ports. (CompactRIO)
        CALAB_POLLING = TRUE
   (CA Lab looks only if CALAB_POLLING is defined. The value does not matter.
    Events and synchronisation are disabled if you use this polling mode.)
  + Added CALAB_NODBG and CALAB_POLLING to CaLabInfo
  # Non-blocking mutexes to avoid freezing
  # Improved CaLabPut to run more smoothly
  # Detection of empty PV name in CaLabPut
  # Good news for all Linux users: CaLabEvent.vi is working again
    Please link the CA Lab library without the option "-llv"

----------------------------------------------------------------------
V1.5.0.1 (Released: February 2014)
  +++ New server component! +++
  + Configure and start an external "soft IOC shell" instance directly
    out of LabVIEW (for Windows only, Linux users really doesn't need it)
  + New VI "CaLabInfo" to show:
                 current (used) EPICS environment variables
                 internal EPICS PV cache of CA Lab
  # Error code for success is 0 now instead of 1
  # Error codes are in user error code range now (7008-7496)
    Ca Lab error {7008-7472} - 7000 = Channel Access error code
  # Shows more error messages
  # Solves problems with restarted VIs
  # caLabGet: Solves problems with empty PV name array
  # Removes delayed termination of VIs
    (found a better way for safe termination)
  # PV cache and subcriptions are running until all CA Lab VIs are closed
    (stopped VIs have ongoing PV monitors for quick restart)
  # Improved Linux compatibility
  # EPICS base 3.14.12.4

  Known problems
  Linux + current LabVIEW version: The event function is broken. (NI
  confirmed the problem and looks for a solution.) The problem is in the
  development enviroment only. If you build an executible, all is fine.
(NI 2014-02-24: "The problem is expected to be fixed with the version LV 2014.")

----------------------------------------------------------------------
V1.4.1.0 (Released: February 2013)
  + New memory management
  + Gaps in string arrays are possible now; e.g. ['a', 'b', '', 'd']
    (EPICS data type must be a string array!)
  + New LabVIEW control "PV Info" (output cluster),
    project "CaLabs.lvproj" and aliases "CaLabs.aliases"
    (Thanks to Robert M. Everly)
  + Global Channel Access warnings and errors are displayed
    via "Debugging window" of LabVIEW
  # Just one call of caLab.dll in caLabGet.vi instead of two
  # Parallel running instances of CA Lab don't freeze anymore
  # Events: Initially disconnected variables receive values
    after connection is established (fix)
  # Improved LabVIEW convention of VIs
    (Thanks to Robert M. Everly)
  # Update of ReadMeFirst.txt
  # Delayed termination of VIs if they run a very short time (<10sec.)
    This guarantees a safe termination of EPICS environment.
  # Write values (without synchronous) is up to 10 times faster now
  # Read values is up to 5 times faster now
  - Removed buffer size (since version 1.3 without function)
  - Removed dead lock detecting and auto unfreezing
    (No workaround needed anymore)

*** Note ***
If you upgrade existing VIs with CA Lab please exchange:
    caLabGetxx.vi -> caLabGet.vi
    caLabPutxx.vi -> caLabPut.vi
and click right on greyed out CA Lab VIs and use "Relink to SubVI"
to update type of Polymorphic VI.
Watch out! LabVIEW may result in a misalignment of connectors!!

----------------------------------------------------------------------
V1.3.2.1 (Released: August 2012)
  # caLabEvent: Solves problems with subscriptions to
    multi-element (DBR_TIME_CHAR) variables and NULL values
    (Thanks to Phillip J. Wyss -Purdue University-)

----------------------------------------------------------------------
Change-log of CA Lab
V1.3.2.0 (Released: July 2012)
  # Synchronized puts wait for callbacks now (ca_array_put_callback)
  # Less IO delay
  # Solved problems with caLabEvent and uninitialized arrays
  # Recompiled EPICS base 3.14.12.2 with
    rules-db.patch, str-to-enum.patch, fix-907761.patch, comment-nop.patch,
    rsrv2.patch, nfsMount.patch and dbReportDev.patch
  + Multi threaded get and put = faster io
  + Dead lock detecting and auto unfreezing
  + Optional warning window

----------------------------------------------------------------------
V1.3.1.3 (Released: March 2012)
  # Solved 1D-pv-array to 1D-value-array problem
  # caLabGet.vi: optimized memory allocation
  # caLabPut.vi: documentation updated
  # Examples revised and documented better
  # Recompiled EPICS base 3.14.12.2 with
    rules-db.patch, fix-907761.patch and str-to-enum.patch

----------------------------------------------------------------------
V1.3.1.2 (Released: February 2012)
  + caLabPut: New option valueSetsInColumns to hold value sets in columns
     instead of rows (value sets in rows for 2d arrays is default now)
  # caLabPut optimized for speed (large arrays)
  # BUG: caLabGet and caLabGet had transposed arrays in some cases
  # Fixes problems with PV names that contain white spaces
  # Better handling of oversized value arrays in caLabPut
    (Ca Lab uses max. valid array size [NELM field] instead of size=1 now)

----------------------------------------------------------------------
V1.3.1.0 (Released: January 2012)
  + caLabPut: New option "synchronous"
             (old connector name was "fire and forget")
             true = writes value(s) after waiting for the end
                      of record processing
             false  = writes value(s) without waiting for the end
                      of record processing (DEFAULT)
Note: Old projects that use the "fire and forget" feature in caLabPut,
      are no longer compatible!

----------------------------------------------------------------------
V1.3.0.4 (Released: December 2011)
  # Fixes problems with PV names that contain a point
  # Better enum string handling for string value output
  # Uninstaller detects and terminates running caRepeater.exe now

---------------------------------------------------------------------
V1.3.0.3 (Released: December 2011)
  + Completely rewritten
  + EPICS base 3.14.12.2
  + 64-bit support
  + !!! caLabGet and caLabPut accepts PV arrays now !!!
  + Much faster if you use name arrays
  + Optional fields are no longer static values
    (monitoring of optional fields)

  # No white spaces in results anymore
  # Fixes problem with long PV names
  # Memory leak for caLabPut Fixes
  # Works with LabVIEW 2011
  # Improved polymorphic vi handling (boolean input)
  # Fixes caLabPut2x.vi (1D-name-array with 1D-value-array)
  # Keeps last valid value in error case

  - Fire and forget not longer available
   (dummy connectors for compatibility)

---------------------------------------------------------------------
V1.2.1.3 (Released: May 2011)
  # Fixes multi instances bug
  # Fixes for EPICS Base
  # Fixes lost values of reconnected channels
  # Fixes problems with multiple ioc-server-sources

---------------------------------------------------------------------
V1.2.0.0 (Released: February 2011)
  + Added "user event" (software trigger) to CA Lab

  # Minor changes in startDemo.bat (11 FEB 2011)
  # Fixes LabVIEW crash in case of immediately closing VI after
    stopping it
  # Faster termination of CA Lab VIs

---------------------------------------------------------------------
V1.1.1.1 (Released: January 2011)
  # Holds last valid value of PV after channel disconnection with
    current state info
  # Fixes for EPICS Base "escape-paths.patch", "errlog-atExit.patch"
    and "rsrv.patch"

---------------------------------------------------------------------
V1.1.1.0 (Released: January 2011)
  + WORKS WITH LINUX NOW!!!
  + Works with LabVIEW 7.0 up to LabVIEW 2010
  + Improved performance (much more faster Channel Access IO,
    faster reconnect)
  + Internal PV cache to improve read and write access and reduce
    network traffic
  + User defined fields of EPICS PV such as "EGU", "DESCRIPTION" etc.
  + New additional fire-and-forget-bit for speeding up write
    If you use the fire and forget mode you'll get no success info
  + User defined timeout for Channel Access communication (optional)
  + User defined buffer for reconnect and put task (optional)
  + More PV information bundled in output cluster
  + Status bit of PV for easy health check

  - In LabVIEW 8.5 and higher "initPV.vi" and "disconnectPV.vi"
    are no longer needed.
  - Reduced user-VIs to "caLabGet.vi" and "caLabPut.vi"

  # Fixes memory leak
  # Holds last valid value of PV after channel disconnection with
    current state info
  # Better error handling (no frozen LabVIEW anymore)
  # Built with EPICS Base 3.14.12

---------------------------------------------------------------------
V1.0.0.3 (Released: June 2010)
  - First Release