- \anchor exceptionHandling_b_2_3_3 2.3.3 The return value of write() indicates whether data was lost in the transfer. If the write has to be delayed due to an exception, the return value will be true (= data lost) if a previously delayed and not-yet written value is discarded in the process, false (= no data lost) otherwise. [\ref testExceptionHandling_b_2_3_3 "T"]
- \anchor b_2_3_4 2.3.4 When the delayed value is finally written to the device during the recovery procedure, the return value of the write() is ignored. \ref comment_b_2_3_4 "(*)" [not testable]
- \anchor exceptionHandling_b_2_3_5 2.3.5 It is guaranteed that the write takes place before the device is considered fully recovered again and other transfers are allowed (cf. \ref b_3_1 "3.1"). [\ref testExceptionHandling_b_2_3_5 "T"]
- \anchor exceptionHandling_b_2_3_6 2.3.6 Write operations to registers of the type ChimeraTK::Void are not delayed. \ref comment_b_2_3_6 "(*)" [tested by \ref exceptionHandling_b_3_1_2 "3.1.2"]
- \anchor b_2_4 2.4 In case of exceptions, there is no guaranteed realtime behaviour, not even for "non-blocking" transfers. \ref comment_b_2_4 "(*)" [not testable]
- \anchor exceptionHandling_b_2_5 2.5 TransferElement::isReadable(), TransferElement::isWriteable() and TransferElement::isReadonly() return with values as if reading and writing would be allowed. \ref exceptionHandling_comment_b_2_5 "(*)" [\ref testExceptionHandling_b_2_5 "T"]
...
...
@@ -70,7 +71,7 @@ namespace ChimeraTK {
- 3. The framework tries to resolve an exception state by periodically re-opening the faulty device.
- \anchor b_3_1 3.1 After successfully re-opening the device, a recovery procedure is executed before allowing any read/write operations from the ApplicationModules and FanOuts again. This recovery procedure involves:
- \anchor exceptionHandling_b_3_1_1 3.1.1 the execution of so-called initialisation handlers (see \ref exceptionHandling_b_3_2 "3.2") [\ref testExceptionHandling_b_3_1_1 "T"], and
- \anchor exceptionHandling_b_3_1_2 3.1.2 restoring all registers that have been written since the start of the application with their latest values. The register values are restored in the same order they were written. \ref comment_b_3_1_2 "(*)" [\ref testExceptionHandling_b_3_1_2 "T"]
- \anchor exceptionHandling_b_3_1_2 3.1.2 restoring all registers that have been written since the start of the application with their latest values. The register values are restored in the same order they were written. Registers of the type ChimeraTK::Void are not written. \ref comment_b_3_1_2 "(*)" [\ref testExceptionHandling_b_3_1_2 "T"]
- \anchor exceptionHandling_b_3_1_3 3.1.3 The asynchronous read transfers of the device are (re-)activated by calling Device::activateAsyncReads(). [\ref testExceptionHandling_b_3_1_3 "T"]
- \anchor exceptionHandling_b_3_1_4 3.1.4 Finally, \c Devices/\<alias\>/deviceBecameFunctional is written to inform any module subscribing to this variable about the finished recovery. \ref comment_b_3_1_4 "(*)" [\ref testExceptionHandling_b_3_1_4 "T"]
- \anchor exceptionHandling_b_3_2 3.2 Any number of initialisation handlers can be added to the DeviceModule in the user code. Initialisation handlers are callback functions which will be executed when a device is opened for the first time and after a device recovers from an exception, before any application-initiated transfers are executed (including delayed write transfers). See DeviceModule::addInitialisationHandler(). [\ref testExceptionHandling_b_3_2 "T"]
...
...
@@ -93,6 +94,8 @@ namespace ChimeraTK {
- \anchor comment_b_2_3_4 \ref b_2_3_4 "2.3.4" The TransferElement specification B.7.2 guarantees that only old data may be lost in a write transfer, hence the latest data is guaranteed to be written to the device during recovery.
- \anchor comment_b_2_3_6 \ref exceptionHandling_b_2_3_6 "2.3.6" Void-typed registers trigger actions and do not carry data. Hence no value can be restored, but instead an action would be triggered which is usually unwanted at the time of recovery (e.g. board reset). If the action is explicitly wanted during recovery, it can be triggered in the recovery handler instead.
- \anchor comment_b_2_4 \ref b_2_4 "2.4" Even read without wait_for_new_data and write operations are not truely non-blocking, since they are still synchronous. The "non-blocking" guarantee only means that the operation does not block until new data has arrived, and that it is not frozen until the device is recovered. For the duration of the recovery procedure and of course for timeout periods these operations may still block. readNonBlocking() and readLatest() with wait_for_new_data could in theory be truely lock-free and wait-free, but the synchronisation mechanism in case of exceptions are not implemented as such. In case of exceptions, the application usually anway does not behave normally any more. If needed, this limitation could be lifted with a more complicated implementation in the future.
- \anchor exceptionHandling_comment_b_2_5 \ref exceptionHandling_b_2_5 "2.5" These functions can throw runtime errors if the behaviour has to be determined from the running device. In this case readability and writeability can change on the device (cf. <a href="https://chimeratk.github.io/DeviceAccess/master/spec__transfer_element.html">TransferElement specification</a> C.5.3). Suppressing the exception and allowing the operation does not pose the risk of getting a ChimeraTK::logic_error in the preXxx() phase of the