cafe-1.12.5 release

This commit is contained in:
2021-03-16 09:30:56 +01:00
parent 7504b0a539
commit 7ba4128448
106 changed files with 185064 additions and 183247 deletions
+156393 -173875
View File
File diff suppressed because it is too large Load Diff
+167
View File
@@ -0,0 +1,167 @@
/*
* Bitshuffle - Filter for improving compression of typed binary data.
*
* Author: Kiyoshi Masui <kiyo@physics.ubc.ca>
* Website: http://www.github.com/kiyo-masui/bitshuffle
* Created: 2014
*
* See LICENSE file for details about copyright and rights to use.
*
*/
#include "bitshuffle.h"
#include "bitshuffle_core.h"
#include "bitshuffle_internals.h"
#include "lz4.h"
#include <stdio.h>
#include <string.h>
// Constants.
// Use fast decompression instead of safe decompression for LZ4.
#define BSHUF_LZ4_DECOMPRESS_FAST
// Macros.
#define CHECK_ERR_FREE_LZ(count, buf) if (count < 0) { \
free(buf); return count - 1000; }
/* Bitshuffle and compress a single block. */
int64_t bshuf_compress_lz4_block(ioc_chain *C_ptr, \
const size_t size, const size_t elem_size) {
int64_t nbytes, count;
void *tmp_buf_bshuf;
void *tmp_buf_lz4;
size_t this_iter;
const void *in;
void *out;
tmp_buf_bshuf = malloc(size * elem_size);
if (tmp_buf_bshuf == NULL) return -1;
tmp_buf_lz4 = malloc(LZ4_compressBound(size * elem_size));
if (tmp_buf_lz4 == NULL){
free(tmp_buf_bshuf);
return -1;
}
in = ioc_get_in(C_ptr, &this_iter);
ioc_set_next_in(C_ptr, &this_iter, (void*) ((char*) in + size * elem_size));
count = bshuf_trans_bit_elem(in, tmp_buf_bshuf, size, elem_size);
if (count < 0) {
free(tmp_buf_lz4);
free(tmp_buf_bshuf);
return count;
}
nbytes = LZ4_compress((const char*) tmp_buf_bshuf, (char*) tmp_buf_lz4, size * elem_size);
free(tmp_buf_bshuf);
CHECK_ERR_FREE_LZ(nbytes, tmp_buf_lz4);
out = ioc_get_out(C_ptr, &this_iter);
ioc_set_next_out(C_ptr, &this_iter, (void *) ((char *) out + nbytes + 4));
bshuf_write_uint32_BE(out, nbytes);
memcpy((char *) out + 4, tmp_buf_lz4, nbytes);
free(tmp_buf_lz4);
return nbytes + 4;
}
/* Decompress and bitunshuffle a single block. */
int64_t bshuf_decompress_lz4_block(ioc_chain *C_ptr,
const size_t size, const size_t elem_size) {
int64_t nbytes, count;
void *out, *tmp_buf;
const void *in;
size_t this_iter;
int32_t nbytes_from_header;
in = ioc_get_in(C_ptr, &this_iter);
nbytes_from_header = bshuf_read_uint32_BE(in);
ioc_set_next_in(C_ptr, &this_iter,
(void*) ((char*) in + nbytes_from_header + 4));
out = ioc_get_out(C_ptr, &this_iter);
ioc_set_next_out(C_ptr, &this_iter,
(void *) ((char *) out + size * elem_size));
tmp_buf = malloc(size * elem_size);
if (tmp_buf == NULL) return -1;
#ifdef BSHUF_LZ4_DECOMPRESS_FAST
nbytes = LZ4_decompress_fast((const char*) in + 4, (char*) tmp_buf, size * elem_size);
CHECK_ERR_FREE_LZ(nbytes, tmp_buf);
if (nbytes != nbytes_from_header) {
free(tmp_buf);
return -91;
}
#else
nbytes = LZ4_decompress_safe((const char*) in + 4, (char *) tmp_buf, nbytes_from_header,
size * elem_size);
CHECK_ERR_FREE_LZ(nbytes, tmp_buf);
if (nbytes != size * elem_size) {
free(tmp_buf);
return -91;
}
nbytes = nbytes_from_header;
#endif
count = bshuf_untrans_bit_elem(tmp_buf, out, size, elem_size);
CHECK_ERR_FREE(count, tmp_buf);
nbytes += 4;
free(tmp_buf);
return nbytes;
}
/* ---- Public functions ----
*
* See header file for description and usage.
*
*/
size_t bshuf_compress_lz4_bound(const size_t size,
const size_t elem_size, size_t block_size) {
size_t bound, leftover;
if (block_size == 0) {
block_size = bshuf_default_block_size(elem_size);
}
if (block_size % BSHUF_BLOCKED_MULT) return -81;
// Note that each block gets a 4 byte header.
// Size of full blocks.
bound = (LZ4_compressBound(block_size * elem_size) + 4) * (size / block_size);
// Size of partial blocks, if any.
leftover = ((size % block_size) / BSHUF_BLOCKED_MULT) * BSHUF_BLOCKED_MULT;
if (leftover) bound += LZ4_compressBound(leftover * elem_size) + 4;
// Size of uncompressed data not fitting into any blocks.
bound += (size % BSHUF_BLOCKED_MULT) * elem_size;
return bound;
}
int64_t bshuf_compress_lz4(const void* in, void* out, const size_t size,
const size_t elem_size, size_t block_size) {
return bshuf_blocked_wrap_fun(&bshuf_compress_lz4_block, in, out, size,
elem_size, block_size);
}
int64_t bshuf_decompress_lz4(const void* in, void* out, const size_t size,
const size_t elem_size, size_t block_size) {
//printf("bshuf_decompress_lz4 called from within zbsread.h\n");
//return 0;
return bshuf_blocked_wrap_fun(&bshuf_decompress_lz4_block, in, out, size,
elem_size, block_size);
}
+123
View File
@@ -0,0 +1,123 @@
/*
* Bitshuffle - Filter for improving compression of typed binary data.
*
* This file is part of Bitshuffle
* Author: Kiyoshi Masui <kiyo@physics.ubc.ca>
* Website: http://www.github.com/kiyo-masui/bitshuffle
* Created: 2014
*
* See LICENSE file for details about copyright and rights to use.
*
*
* Header File
*
* Worker routines return an int64_t which is the number of bytes processed
* if positive or an error code if negative.
*
* Error codes:
* -1 : Failed to allocate memory.
* -11 : Missing SSE.
* -12 : Missing AVX.
* -80 : Input size not a multiple of 8.
* -81 : block_size not multiple of 8.
* -91 : Decompression error, wrong number of bytes processed.
* -1YYY : Error internal to compression routine with error code -YYY.
*/
#ifndef BITSHUFFLE_H
#define BITSHUFFLE_H
#include <stdlib.h>
#include "bitshuffle_core.h"
#ifdef __cplusplus
extern "C" {
#endif
/* ---- bshuf_compress_lz4_bound ----
*
* Bound on size of data compressed with *bshuf_compress_lz4*.
*
* Parameters
* ----------
* size : number of elements in input
* elem_size : element size of typed data
* block_size : Process in blocks of this many elements. Pass 0 to
* select automatically (recommended).
*
* Returns
* -------
* Bound on compressed data size.
*
*/
size_t bshuf_compress_lz4_bound(const size_t size,
const size_t elem_size, size_t block_size);
/* ---- bshuf_compress_lz4 ----
*
* Bitshuffled and compress the data using LZ4.
*
* Transpose within elements, in blocks of data of *block_size* elements then
* compress the blocks using LZ4. In the output buffer, each block is prefixed
* by a 4 byte integer giving the compressed size of that block.
*
* Output buffer must be large enough to hold the compressed data. This could
* be in principle substantially larger than the input buffer. Use the routine
* *bshuf_compress_lz4_bound* to get an upper limit.
*
* Parameters
* ----------
* in : input buffer, must be of size * elem_size bytes
* out : output buffer, must be large enough to hold data.
* size : number of elements in input
* elem_size : element size of typed data
* block_size : Process in blocks of this many elements. Pass 0 to
* select automatically (recommended).
*
* Returns
* -------
* number of bytes used in output buffer, negative error-code if failed.
*
*/
int64_t bshuf_compress_lz4(const void* in, void* out, const size_t size, const size_t
elem_size, size_t block_size);
/* ---- bshuf_decompress_lz4 ----
*
* Undo compression and bitshuffling.
*
* Decompress data then un-bitshuffle it in blocks of *block_size* elements.
*
* To properly unshuffle bitshuffled data, *size*, *elem_size* and *block_size*
* must patch the parameters used to compress the data.
*
* NOT TO BE USED WITH UNTRUSTED DATA: This routine uses the function
* LZ4_decompress_fast from LZ4, which does not protect against maliciously
* formed datasets. By modifying the compressed data, this function could be
* coerced into leaving the boundaries of the input buffer.
*
* Parameters
* ----------
* in : input buffer
* out : output buffer, must be of size * elem_size bytes
* size : number of elements in input
* elem_size : element size of typed data
* block_size : Process in blocks of this many elements. Pass 0 to
* select automatically (recommended).
*
* Returns
* -------
* number of bytes consumed in *input* buffer, negative error-code if failed.
*
*/
int64_t bshuf_decompress_lz4(const void* in, void* out, const size_t size,
const size_t elem_size, size_t block_size);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // BITSHUFFLE_H
File diff suppressed because it is too large Load Diff
+158
View File
@@ -0,0 +1,158 @@
/*
* Bitshuffle - Filter for improving compression of typed binary data.
*
* This file is part of Bitshuffle
* Author: Kiyoshi Masui <kiyo@physics.ubc.ca>
* Website: http://www.github.com/kiyo-masui/bitshuffle
* Created: 2014
*
* See LICENSE file for details about copyright and rights to use.
*
*
* Header File
*
* Worker routines return an int64_t which is the number of bytes processed
* if positive or an error code if negative.
*
* Error codes:
* -1 : Failed to allocate memory.
* -11 : Missing SSE.
* -12 : Missing AVX.
* -80 : Input size not a multiple of 8.
* -81 : block_size not multiple of 8.
* -91 : Decompression error, wrong number of bytes processed.
* -1YYY : Error internal to compression routine with error code -YYY.
*/
#ifndef BITSHUFFLE_CORE_H
#define BITSHUFFLE_CORE_H
// We assume GNU g++ defining `__cplusplus` has stdint.h
#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199900L) || defined(__cplusplus)
#include <stdint.h>
#else
/*
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef signed int int32_t;
typedef unsigned long long uint64_t;
typedef long long int64_t;
*/
#endif
#include <stdlib.h>
// These are usually set in the setup.py.
#ifndef BSHUF_VERSION_MAJOR
#define BSHUF_VERSION_MAJOR 0
#define BSHUF_VERSION_MINOR 3
#define BSHUF_VERSION_POINT 4
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* --- bshuf_using_SSE2 ----
*
* Whether routines where compiled with the SSE2 instruction set.
*
* Returns
* -------
* 1 if using SSE2, 0 otherwise.
*
*/
int bshuf_using_SSE2(void);
/* ---- bshuf_using_AVX2 ----
*
* Whether routines where compiled with the AVX2 instruction set.
*
* Returns
* -------
* 1 if using AVX2, 0 otherwise.
*
*/
int bshuf_using_AVX2(void);
/* ---- bshuf_default_block_size ----
*
* The default block size as function of element size.
*
* This is the block size used by the blocked routines (any routine
* taking a *block_size* argument) when the block_size is not provided
* (zero is passed).
*
* The results of this routine are guaranteed to be stable such that
* shuffled/compressed data can always be decompressed.
*
* Parameters
* ----------
* elem_size : element size of data to be shuffled/compressed.
*
*/
size_t bshuf_default_block_size(const size_t elem_size);
/* ---- bshuf_bitshuffle ----
*
* Bitshuffle the data.
*
* Transpose the bits within elements, in blocks of *block_size*
* elements.
*
* Parameters
* ----------
* in : input buffer, must be of size * elem_size bytes
* out : output buffer, must be of size * elem_size bytes
* size : number of elements in input
* elem_size : element size of typed data
* block_size : Do transpose in blocks of this many elements. Pass 0 to
* select automatically (recommended).
*
* Returns
* -------
* number of bytes processed, negative error-code if failed.
*
*/
int64_t bshuf_bitshuffle(const void* in, void* out, const size_t size,
const size_t elem_size, size_t block_size);
/* ---- bshuf_bitunshuffle ----
*
* Unshuffle bitshuffled data.
*
* Untranspose the bits within elements, in blocks of *block_size*
* elements.
*
* To properly unshuffle bitshuffled data, *size*, *elem_size* and *block_size*
* must match the parameters used to shuffle the data.
*
* Parameters
* ----------
* in : input buffer, must be of size * elem_size bytes
* out : output buffer, must be of size * elem_size bytes
* size : number of elements in input
* elem_size : element size of typed data
* block_size : Do transpose in blocks of this many elements. Pass 0 to
* select automatically (recommended).
*
* Returns
* -------
* number of bytes processed, negative error-code if failed.
*
*/
int64_t bshuf_bitunshuffle(const void* in, void* out, const size_t size,
const size_t elem_size, size_t block_size);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // BITSHUFFLE_CORE_H
+77
View File
@@ -0,0 +1,77 @@
/*
* Bitshuffle - Filter for improving compression of typed binary data.
*
* This file is part of Bitshuffle
* Author: Kiyoshi Masui <kiyo@physics.ubc.ca>
* Website: http://www.github.com/kiyo-masui/bitshuffle
* Created: 2014
*
* See LICENSE file for details about copyright and rights to use.
*/
#ifndef BITSHUFFLE_INTERNALS_H
#define BITSHUFFLE_INTERNALS_H
// We assume GNU g++ defining `__cplusplus` has stdint.h
#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199900L) || defined(__cplusplus)
#include <stdint.h>
#else
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef signed int int32_t;
typedef unsigned long long uint64_t;
//typedef long long int64_t;
#endif
#include <stdlib.h>
#include "iochain.h"
// Constants.
#ifndef BSHUF_MIN_RECOMMEND_BLOCK
#define BSHUF_MIN_RECOMMEND_BLOCK 128
#define BSHUF_BLOCKED_MULT 8 // Block sizes must be multiple of this.
#define BSHUF_TARGET_BLOCK_SIZE_B 8192
#endif
// Macros.
#define CHECK_ERR_FREE(count, buf) if (count < 0) { free(buf); return count; }
#ifdef __cplusplus
extern "C" {
#endif
/* ---- Utility functions for internal use only ---- */
int64_t bshuf_trans_bit_elem(const void* in, void* out, const size_t size,
const size_t elem_size);
/* Read a 32 bit unsigned integer from a buffer big endian order. */
uint32_t bshuf_read_uint32_BE(const void* buf);
/* Write a 32 bit unsigned integer to a buffer in big endian order. */
void bshuf_write_uint32_BE(void* buf, uint32_t num);
int64_t bshuf_untrans_bit_elem(const void* in, void* out, const size_t size,
const size_t elem_size);
/* Function definition for worker functions that process a single block. */
typedef int64_t (*bshufBlockFunDef)(ioc_chain* C_ptr,
const size_t size, const size_t elem_size);
/* Wrap a function for processing a single block to process an entire buffer in
* parallel. */
int64_t bshuf_blocked_wrap_fun(bshufBlockFunDef fun, const void* in, void* out,
const size_t size, const size_t elem_size, size_t block_size);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // BITSHUFFLE_INTERNALS_H
+218
View File
@@ -0,0 +1,218 @@
/*
* Bitshuffle HDF5 filter
*
* This file is part of Bitshuffle
* Author: Kiyoshi Masui <kiyo@physics.ubc.ca>
* Website: http://www.github.com/kiyo-masui/bitshuffle
* Created: 2014
*
* See LICENSE file for details about copyright and rights to use.
*
*/
#include "bitshuffle.h"
#include "bshuf_h5filter.h"
#define PUSH_ERR(func, minor, str) \
H5Epush1(__FILE__, func, __LINE__, H5E_PLINE, minor, str)
// Prototypes from bitshuffle.c
void bshuf_write_uint64_BE(void* buf, uint64_t num);
uint64_t bshuf_read_uint64_BE(void* buf);
void bshuf_write_uint32_BE(void* buf, uint32_t num);
uint32_t bshuf_read_uint32_BE(const void* buf);
// Only called on compresion, not on reverse.
herr_t bshuf_h5_set_local(hid_t dcpl, hid_t type, hid_t space){
herr_t r;
size_t ii;
unsigned int elem_size;
unsigned int flags;
size_t nelements = 8;
size_t nelem_max = 11;
unsigned values[] = {0,0,0,0,0,0,0,0,0,0,0};
unsigned tmp_values[] = {0,0,0,0,0,0,0,0};
char msg[80];
r = H5Pget_filter_by_id2(dcpl, BSHUF_H5FILTER, &flags, &nelements,
tmp_values, 0, NULL, NULL);
if(r<0) return -1;
// First 3 slots reserved. Move any passed options to higher addresses.
for (ii=0; ii < nelements && ii + 3 < nelem_max; ii++) {
values[ii + 3] = tmp_values[ii];
}
nelements = 3 + nelements;
values[0] = BSHUF_VERSION_MAJOR;
values[1] = BSHUF_VERSION_MINOR;
elem_size = H5Tget_size(type);
if(elem_size <= 0) {
PUSH_ERR("bshuf_h5_set_local", H5E_CALLBACK,
"Invalid element size.");
return -1;
}
values[2] = elem_size;
// Validate user supplied arguments.
if (nelements > 3) {
if (values[3] % 8 || values[3] < 0) {
sprintf(msg, "Error in bitshuffle. Invalid block size: %u.",
values[3]);
PUSH_ERR("bshuf_h5_set_local", H5E_CALLBACK, msg);
return -1;
}
}
if (nelements > 4) {
switch (values[4]) {
case 0:
break;
case BSHUF_H5_COMPRESS_LZ4:
break;
default:
PUSH_ERR("bshuf_h5_set_local", H5E_CALLBACK,
"Invalid bitshuffle compression.");
}
}
r = H5Pmodify_filter(dcpl, BSHUF_H5FILTER, flags, nelements, values);
if(r<0) return -1;
return 1;
}
size_t bshuf_h5_filter(unsigned int flags, size_t cd_nelmts,
const unsigned int cd_values[], size_t nbytes,
size_t *buf_size, void **buf) {
size_t size, elem_size;
int err;
char msg[80];
size_t block_size = 0;
size_t buf_size_out, nbytes_uncomp, nbytes_out;
char* in_buf = *buf;
void *out_buf;
if (cd_nelmts < 3) {
PUSH_ERR("bshuf_h5_filter", H5E_CALLBACK,
"Not enough parameters.");
return 0;
}
elem_size = cd_values[2];
// User specified block size.
if (cd_nelmts > 3) block_size = cd_values[3];
if (block_size == 0) block_size = bshuf_default_block_size(elem_size);
// Compression in addition to bitshiffle.
if (cd_nelmts > 4 && cd_values[4] == BSHUF_H5_COMPRESS_LZ4) {
if (flags & H5Z_FLAG_REVERSE) {
// First eight bytes is the number of bytes in the output buffer,
// little endian.
nbytes_uncomp = bshuf_read_uint64_BE(in_buf);
// Override the block size with the one read from the header.
block_size = bshuf_read_uint32_BE((const char*) in_buf + 8) / elem_size;
// Skip over the header.
in_buf += 12;
buf_size_out = nbytes_uncomp;
} else {
nbytes_uncomp = nbytes;
buf_size_out = bshuf_compress_lz4_bound(nbytes_uncomp / elem_size,
elem_size, block_size) + 12;
}
} else {
nbytes_uncomp = nbytes;
buf_size_out = nbytes;
}
// TODO, remove this restriction by memcopying the extra.
if (nbytes_uncomp % elem_size) {
PUSH_ERR("bshuf_h5_filter", H5E_CALLBACK,
"Non integer number of elements.");
return 0;
}
size = nbytes_uncomp / elem_size;
out_buf = malloc(buf_size_out);
if (out_buf == NULL) {
PUSH_ERR("bshuf_h5_filter", H5E_CALLBACK,
"Could not allocate output buffer.");
return 0;
}
if (cd_nelmts > 4 && cd_values[4] == BSHUF_H5_COMPRESS_LZ4) {
if (flags & H5Z_FLAG_REVERSE) {
// Bit unshuffle/decompress.
err = bshuf_decompress_lz4(in_buf, out_buf, size, elem_size, block_size);
nbytes_out = nbytes_uncomp;
} else {
// Bit shuffle/compress.
// Write the header, described in
// http://www.hdfgroup.org/services/filters/HDF5_LZ4.pdf.
// Techincally we should be using signed integers instead of
// unsigned ones, however for valid inputs (positive numbers) these
// have the same representation.
bshuf_write_uint64_BE(out_buf, nbytes_uncomp);
bshuf_write_uint32_BE((char*) out_buf + 8, block_size * elem_size);
err = bshuf_compress_lz4(in_buf, (char*) out_buf + 12, size,
elem_size, block_size); nbytes_out = err + 12; } } else {
if (flags & H5Z_FLAG_REVERSE) {
// Bit unshuffle.
err = bshuf_bitunshuffle(in_buf, out_buf, size, elem_size,
block_size); } else {
// Bit shuffle.
err = bshuf_bitshuffle(in_buf, out_buf, size, elem_size,
block_size); } nbytes_out = nbytes; }
//printf("nb_in %d, nb_uncomp %d, nb_out %d, buf_out %d, block %d\n",
//nbytes, nbytes_uncomp, nbytes_out, buf_size_out, block_size);
if (err < 0) {
sprintf(msg, "Error in bitshuffle with error code %d.", err);
PUSH_ERR("bshuf_h5_filter", H5E_CALLBACK, msg);
free(out_buf);
return 0;
} else {
free(*buf);
*buf = out_buf;
*buf_size = buf_size_out;
return nbytes_out;
}
}
H5Z_class_t bshuf_H5Filter[1] = {{
H5Z_CLASS_T_VERS,
(H5Z_filter_t)(BSHUF_H5FILTER),
1, 1,
"bitshuffle; see https://github.com/kiyo-masui/bitshuffle",
NULL,
(H5Z_set_local_func_t)(bshuf_h5_set_local),
(H5Z_func_t)(bshuf_h5_filter)
}};
int bshuf_register_h5filter(void){
int retval;
retval = H5Zregister(bshuf_H5Filter);
if(retval<0){
PUSH_ERR("bshuf_register_h5filter",
H5E_CANTREGISTER, "Can't register bitshuffle filter");
}
return retval;
}
+59
View File
@@ -0,0 +1,59 @@
/*
* Bitshuffle HDF5 filter
*
* This file is part of Bitshuffle
* Author: Kiyoshi Masui <kiyo@physics.ubc.ca>
* Website: http://www.github.com/kiyo-masui/bitshuffle
* Created: 2014
*
* See LICENSE file for details about copyright and rights to use.
*
*
* Header File
*
* Filter Options
* --------------
* block_size (option slot 0) : interger (optional)
* What block size to use (in elements not bytes). Default is 0,
* for which bitshuffle will pick a block size with a target of 8kb.
* Compression (option slot 1) : 0 or BSHUF_H5_COMPRESS_LZ4
* Whether to apply LZ4 compression to the data after bitshuffling.
* This is much faster than applying compression as a second filter
* because it is done when the small block of data is already in the
* L1 cache.
*
* For LZ4 compression, the compressed format of the data is the same as
* for the normal LZ4 filter described in
* http://www.hdfgroup.org/services/filters/HDF5_LZ4.pdf.
*
*/
#ifndef BSHUF_H5FILTER_H
#define BSHUF_H5FILTER_H
#define H5Z_class_t_vers 2
#include "hdf5.h"
#define BSHUF_H5FILTER 32008
#define BSHUF_H5_COMPRESS_LZ4 2
extern H5Z_class_t bshuf_H5Filter[1];
/* ---- bshuf_register_h5filter ----
*
* Register the bitshuffle HDF5 filter within the HDF5 library.
*
* Call this before using the bitshuffle HDF5 filter from C unless
* using dynamically loaded filters.
*
*/
int bshuf_register_h5filter(void);
#endif // BSHUF_H5FILTER_H
+19
View File
@@ -0,0 +1,19 @@
/*
* Dynamically loaded filter plugin for HDF5 Bitshuffle filter.
*
* This file is part of Bitshuffle
* Author: Kiyoshi Masui <kiyo@physics.ubc.ca>
* Website: http://www.github.com/kiyo-masui/bitshuffle
* Created: 2014
*
* See LICENSE file for details about copyright and rights to use.
*
*/
#include "bshuf_h5filter.h"
#include "H5PLextern.h"
H5PL_type_t H5PLget_plugin_type(void) {return H5PL_TYPE_FILTER;}
const void* H5PLget_plugin_info(void) {return bshuf_H5Filter;}
+90
View File
@@ -0,0 +1,90 @@
/*
* IOchain - Distribute a chain of dependant IO events amoung threads.
*
* This file is part of Bitshuffle
* Author: Kiyoshi Masui <kiyo@physics.ubc.ca>
* Website: http://www.github.com/kiyo-masui/bitshuffle
* Created: 2014
*
* See LICENSE file for details about copyright and rights to use.
*
*/
#include <stdlib.h>
#include "iochain.h"
void ioc_init(ioc_chain *C, const void *in_ptr_0, void *out_ptr_0) {
#ifdef _OPENMP
omp_init_lock(&C->next_lock);
for (size_t ii = 0; ii < IOC_SIZE; ii ++) {
omp_init_lock(&(C->in_pl[ii].lock));
omp_init_lock(&(C->out_pl[ii].lock));
}
#endif
C->next = 0;
C->in_pl[0].ptr = in_ptr_0;
C->out_pl[0].ptr = out_ptr_0;
}
void ioc_destroy(ioc_chain *C) {
#ifdef _OPENMP
omp_destroy_lock(&C->next_lock);
for (size_t ii = 0; ii < IOC_SIZE; ii ++) {
omp_destroy_lock(&(C->in_pl[ii].lock));
omp_destroy_lock(&(C->out_pl[ii].lock));
}
#endif
}
const void * ioc_get_in(ioc_chain *C, size_t *this_iter) {
#ifdef _OPENMP
omp_set_lock(&C->next_lock);
#pragma omp flush
#endif
*this_iter = C->next;
C->next ++;
#ifdef _OPENMP
omp_set_lock(&(C->in_pl[*this_iter % IOC_SIZE].lock));
omp_set_lock(&(C->in_pl[(*this_iter + 1) % IOC_SIZE].lock));
omp_set_lock(&(C->out_pl[(*this_iter + 1) % IOC_SIZE].lock));
omp_unset_lock(&C->next_lock);
#endif
return C->in_pl[*this_iter % IOC_SIZE].ptr;
}
void ioc_set_next_in(ioc_chain *C, size_t* this_iter, void* in_ptr) {
C->in_pl[(*this_iter + 1) % IOC_SIZE].ptr = in_ptr;
#ifdef _OPENMP
omp_unset_lock(&(C->in_pl[(*this_iter + 1) % IOC_SIZE].lock));
#endif
}
void * ioc_get_out(ioc_chain *C, size_t *this_iter) {
#ifdef _OPENMP
omp_set_lock(&(C->out_pl[(*this_iter) % IOC_SIZE].lock));
#pragma omp flush
#endif
void *out_ptr = C->out_pl[*this_iter % IOC_SIZE].ptr;
#ifdef _OPENMP
omp_unset_lock(&(C->out_pl[(*this_iter) % IOC_SIZE].lock));
#endif
return out_ptr;
}
void ioc_set_next_out(ioc_chain *C, size_t *this_iter, void* out_ptr) {
C->out_pl[(*this_iter + 1) % IOC_SIZE].ptr = out_ptr;
#ifdef _OPENMP
omp_unset_lock(&(C->out_pl[(*this_iter + 1) % IOC_SIZE].lock));
// *in_pl[this_iter]* lock released at the end of the iteration to avoid being
// overtaken by previous threads and having *out_pl[this_iter]* corrupted.
// Especially worried about thread 0, iteration 0.
omp_unset_lock(&(C->in_pl[(*this_iter) % IOC_SIZE].lock));
#endif
}
+94
View File
@@ -0,0 +1,94 @@
/*
* IOchain - Distribute a chain of dependant IO events amoung threads.
*
* This file is part of Bitshuffle
* Author: Kiyoshi Masui <kiyo@physics.ubc.ca>
* Website: http://www.github.com/kiyo-masui/bitshuffle
* Created: 2014
*
* See LICENSE file for details about copyright and rights to use.
*
*
* Header File
*
* Similar in concept to a queue. Each task includes reading an input
* and writing output, but the location of the input/output (the pointers)
* depend on the previous item in the chain.
*
* This is designed for parallelizing blocked compression/decompression IO,
* where the destination of a compressed block depends on the compressed size
* of all previous blocks.
*
* Implemented with OpenMP locks.
*
*
* Usage
* -----
* - Call `ioc_init` in serial block.
* - Each thread should create a local variable *size_t this_iter* and
* pass its address to all function calls. Its value will be set
* inside the functions and is used to identify the thread.
* - Each thread must call each of the `ioc_get*` and `ioc_set*` methods
* exactly once per iteration, starting with `ioc_get_in` and ending
* with `ioc_set_next_out`.
* - The order (`ioc_get_in`, `ioc_set_next_in`, *work*, `ioc_get_out`,
* `ioc_set_next_out`, *work*) is most efficient.
* - Have each thread call `ioc_end_pop`.
* - `ioc_get_in` is blocked until the previous entry's
* `ioc_set_next_in` is called.
* - `ioc_get_out` is blocked until the previous entry's
* `ioc_set_next_out` is called.
* - There are no blocks on the very first iteration.
* - Call `ioc_destroy` in serial block.
* - Safe for num_threads >= IOC_SIZE (but less efficient).
*
*/
#ifndef IOCHAIN_H
#define IOCHAIN_H
#include <stdlib.h>
#ifdef _OPENMP
#include <omp.h>
#endif
#define IOC_SIZE 33
typedef struct ioc_ptr_and_lock {
#ifdef _OPENMP
omp_lock_t lock;
#endif
void *ptr;
} ptr_and_lock;
typedef struct ioc_const_ptr_and_lock {
#ifdef _OPENMP
omp_lock_t lock;
#endif
const void *ptr;
} const_ptr_and_lock;
typedef struct ioc_chain {
#ifdef _OPENMP
omp_lock_t next_lock;
#endif
size_t next;
const_ptr_and_lock in_pl[IOC_SIZE];
ptr_and_lock out_pl[IOC_SIZE];
} ioc_chain;
void ioc_init(ioc_chain *C, const void *in_ptr_0, void *out_ptr_0);
void ioc_destroy(ioc_chain *C);
const void * ioc_get_in(ioc_chain *C, size_t *this_iter);
void ioc_set_next_in(ioc_chain *C, size_t* this_iter, void* in_ptr);
void * ioc_get_out(ioc_chain *C, size_t *this_iter);
void ioc_set_next_out(ioc_chain *C, size_t *this_iter, void* out_ptr);
#endif // IOCHAIN_H
+42
View File
@@ -0,0 +1,42 @@
/*
* Dynamically loaded filter plugin for HDF5 LZF filter.
*
* This file is part of Bitshuffle
* Author: Kiyoshi Masui <kiyo@physics.ubc.ca>
* Website: http://www.github.com/kiyo-masui/bitshuffle
* Created: 2014
*
* See LICENSE file for details about copyright and rights to use.
*
*/
#define H5Z_class_t_vers 2
#include "lzf_filter.h"
#include "H5PLextern.h"
#include <stdint.h>
size_t lzf_filter(unsigned flags, size_t cd_nelmts,
const unsigned cd_values[], size_t nbytes,
size_t *buf_size, void **buf);
herr_t lzf_set_local(hid_t dcpl, hid_t type, hid_t space);
H5Z_class_t lzf_H5Filter[1] = {{
H5Z_CLASS_T_VERS,
(H5Z_filter_t)(H5PY_FILTER_LZF),
1, 1,
"lzf",
NULL,
(H5Z_set_local_func_t)(lzf_set_local),
(H5Z_func_t)(lzf_filter)
}};
H5PL_type_t H5PLget_plugin_type(void) {return H5PL_TYPE_FILTER;}
const void* H5PLget_plugin_info(void) {return lzf_H5Filter;}
+1751 -819
View File
File diff suppressed because it is too large Load Diff
+479 -244
View File
File diff suppressed because it is too large Load Diff
+311 -154
View File
File diff suppressed because it is too large Load Diff
+495 -247
View File
File diff suppressed because it is too large Load Diff
+85 -42
View File
@@ -13,16 +13,18 @@
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace std;
using namespace boost::posix_time;
//has config.h
#include <loadCollectionXMLParser.h>
#include <loadGroupXMLParser.h>
#include <restorePVGroupXMLParser.h>
#if HAVE_LIBQTXML
using namespace std;
using namespace boost::posix_time;
/**
* \brief loadCollections from XML \n
* Routine first searches the given directory before CAFE_XML_PATH environment variable
@@ -33,6 +35,7 @@ int CAFE::loadCollectionsFromXML(const char * collectionFile)
{
#define __METHOD__ "CAFE::loadCollectionsFromXML(char * collectionFile)"
//First check for existence of file in current directory
//before searching in CAFE_XML_PATH
@@ -40,7 +43,8 @@ int CAFE::loadCollectionsFromXML(const char * collectionFile)
file = new QFile(collectionFile);
if (!file->exists()) {
if (!file->exists())
{
std::string envS;
char * env = getenv("CAFE_XML_PATH");
@@ -50,23 +54,27 @@ int CAFE::loadCollectionsFromXML(const char * collectionFile)
file = new QFile(envS.c_str());
if (!file->exists()) {
if (!file->exists())
{
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "envS=" << envS << endl;
cout << "COLLECTION FILE " << collectionFile << " NOT FOUND " << endl;
cout << "IN THE CURRENT (OR GIVEN) DIRECTORY" << endl;
if (env != NULL) {
if (env != NULL)
{
cout << "NOR IN CAFE_XML_PATH/=" << endl;
cout << env << endl;
}
else {
else
{
cout << "OPTIONAL ENVIRONMENT VARIABLE CAFE_XML_PATH IS UNDEFINED" << endl;
}
delete file;
return ECAFE_LOAD_COLLECTION;
}
}
else {
else
{
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << " COLLECTION LOADED FROM CURRENT (OR GIVEN) DIRECTORY" << endl;
}
@@ -80,7 +88,8 @@ int CAFE::loadCollectionsFromXML(const char * collectionFile)
bool isOK = reader.parse(source);
if (!isOK) {
if (!isOK)
{
return ECAFE_LOAD_COLLECTION;
}
deviceCollectionV=handler.deviceCollectionV;
@@ -110,7 +119,8 @@ int CAFE::loadGroupsFromXML (const char * groupFile)
QFile * file;
file = new QFile(groupFile);
if (!file->exists()) {
if (!file->exists())
{
std::string envS;
char * env = getenv("CAFE_XML_PATH");
@@ -120,16 +130,19 @@ int CAFE::loadGroupsFromXML (const char * groupFile)
file = new QFile(envS.c_str());
if (!file->exists()) {
if (!file->exists())
{
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "GROUP FILE " << groupFile << " NOT FOUND " << endl;
cout << "NEITHER IN THE CURRENT (OR GIVEN) DIRECTORY" << endl;
if (env != NULL) {
if (env != NULL)
{
cout << "NOR IN CAFE_XML_PATH/=" << endl;
cout << env << endl;
}
else {
else
{
cout << "OPTIONAL ENVIRONMENT VARIABLE CAFE_XML_PATH IS UNDEFINED" << endl;
}
delete file;
@@ -137,7 +150,8 @@ int CAFE::loadGroupsFromXML (const char * groupFile)
return ECAFE_LOAD_GROUP;
}
}
else {
else
{
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << " GROUPS LOADED FROM CURRENT (OR GIVEN) DIRECTORY" << endl;
}
@@ -152,15 +166,18 @@ int CAFE::loadGroupsFromXML (const char * groupFile)
bool isOK = reader.parse(source);
if (!isOK) {
if (!isOK)
{
return ECAFE_LOAD_GROUP;
}
for (std::vector<deviceGroup>::const_iterator group=handler.groups.begin();
group!=handler.groups.end(); ++group) {
group!=handler.groups.end(); ++group)
{
if(isGroup((char *)(*group).getName().c_str())) {
if(isGroup((char *)(*group).getName().c_str()))
{
localStatus=ECAFE_GROUP_PREV_DEF;
std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl;
@@ -183,10 +200,12 @@ int CAFE::loadGroupsFromXML (const char * groupFile)
cg=(*group).getCollections();
for (size_t i=0; i <cg.size(); ++i) {
for (size_t i=0; i <cg.size(); ++i)
{
//cout << cg[i].id << " " << cg[i].attrib << " " << endl; //cg[i].collectiveType << endl;
if(!isCollection((char *)cg[i].id.c_str())) {
if(!isCollection((char *)cg[i].id.c_str()))
{
localStatus=ECAFE_UNKNOWN_COLLECTION;
std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl;
std::cout << "FAILED TO LOAD COLLECTION WITH NAME(ID) " << cg[i].id << std::endl;
@@ -199,7 +218,8 @@ int CAFE::loadGroupsFromXML (const char * groupFile)
vector<string> members;
collectionFetch((char *)cg[i].id.c_str(),members);
for(size_t j=0; j<members.size(); ++j) {
for(size_t j=0; j<members.size(); ++j)
{
string da=members[j] + deviceAttributeDeliminator + cg[i].attrib;
pvList.push_back(da);
}
@@ -209,21 +229,25 @@ int CAFE::loadGroupsFromXML (const char * groupFile)
vector<string> cm= (*group).getXMLMembers();
for (size_t i=0; i <cm.size(); ++i) {
for (size_t i=0; i <cm.size(); ++i)
{
pvList.push_back(cm[i]);
}
if (pvList.size()>0 ) {
if (pvList.size()>0 )
{
groupDefine((const char *) (*group).getName().c_str(), pvList);
}
else {
else
{
cout << "GROUP " << (*group).getName().c_str()
<< " NOT DEFINED AS IT HAS NO MEMBERS! " << endl;
}
}
return ICAFE_NORMAL;
#undef __METHOD__
}
@@ -253,7 +277,8 @@ int CAFE::restoreFromXML (const char * snapshotFile)
file = new QFile(snapshotFile);
if (!file->exists()) {
if (!file->exists())
{
std::string envS;
char * env = getenv("CAFE_SAR_PATH");
@@ -263,7 +288,8 @@ int CAFE::restoreFromXML (const char * snapshotFile)
file = new QFile(envS.c_str());
if (!file->exists()) {
if (!file->exists())
{
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "PVGROUP FILE " << snapshotFile << " NOT FOUND " << endl;
cout << "NEITHER IN THE CURRENT (OR GIVEN) DIRECTORY NOR IN CAFE_SAR_PATH=" << envS << endl;
@@ -272,7 +298,8 @@ int CAFE::restoreFromXML (const char * snapshotFile)
ssf=envS;
}
else {
else
{
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << " PVGROUP LOADED FROM CURRENT (OR GIVEN) DIRECTORY" << endl;
}
@@ -288,7 +315,8 @@ int CAFE::restoreFromXML (const char * snapshotFile)
bool isOK = reader.parse(source);
if (!isOK) {
if (!isOK)
{
return ECAFE_LOAD_GROUP;
}
@@ -302,11 +330,14 @@ int CAFE::restoreFromXML (const char * snapshotFile)
localStatus=groupOpen(pvg, gh);
if (localStatus != ICAFE_NORMAL) {
if (localStatus != ICAFE_NORMAL)
{
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "GROUP OPEN REPORTS FOLLOWING ERROR " << endl;
for (unsigned int i=0; i<pvg.npv; ++i ) {
if(pvg.pvdata[i].status !=ICAFE_NORMAL) {
for (unsigned int i=0; i<pvg.npv; ++i )
{
if(pvg.pvdata[i].status !=ICAFE_NORMAL)
{
pvg.pvdata[i].print();
}
}
@@ -325,7 +356,8 @@ int CAFE::restoreFromXML (const char * snapshotFile)
QXmlInputSource source2(&file2);
isOK = reader2.parse(source2);
if (!isOK) {
if (!isOK)
{
return ECAFE_LOAD_GROUP;
}
@@ -335,11 +367,14 @@ int CAFE::restoreFromXML (const char * snapshotFile)
localStatus=groupSet(gh, pvg);
if (localStatus != ICAFE_NORMAL) {
if (localStatus != ICAFE_NORMAL)
{
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "GROUP SET REPORTS FOLLOWING ERROR " << endl;
for (unsigned int i=0; i<pvg.npv; ++i ) {
if(pvg.pvdata[i].status !=ICAFE_NORMAL) {
for (unsigned int i=0; i<pvg.npv; ++i )
{
if(pvg.pvdata[i].status !=ICAFE_NORMAL)
{
pvg.pvdata[i].print();
}
}
@@ -348,9 +383,11 @@ int CAFE::restoreFromXML (const char * snapshotFile)
groupClose(gh);
return localStatus;
#undef __METHOD__
}
#endif
#endif //HAVE_LIBATXML
/**
@@ -385,11 +422,13 @@ int CAFE::snapshot2XML (PVGroup pg)
//First determine maximum pv size
unsigned short maxL=0;
std::string sn="";
for (unsigned int j=0; j<pg.getNPV(); ++j) {
for (unsigned int j=0; j<pg.getNPV(); ++j)
{
sn=pvd[j].getPV();
if(sn.size() > maxL) maxL=sn.size()+0;
}
for (unsigned int j=0; j<pg.getNPV(); ++j) {
for (unsigned int j=0; j<pg.getNPV(); ++j)
{
s.append("<cafe:member><cafe:name> ");
s.append(pvd[j].getPV());
sn=pvd[j].getPV();
@@ -400,7 +439,8 @@ int CAFE::snapshot2XML (PVGroup pg)
s.append(sBuffer);
s.append(" </cafe:nelem><cafe:val> ");
for (unsigned int i=0; i<pvd[j].getNelem(); ++i) {
for (unsigned int i=0; i<pvd[j].getNelem(); ++i)
{
s.append(pvd[j].getAsString(i));
s.append(" ");
}
@@ -411,10 +451,12 @@ int CAFE::snapshot2XML (PVGroup pg)
ChannelRegalia cr;
getInfo().getChannelRegalia(hl, cr);
if ( cr.getWriteAccess() ) {
if ( cr.getWriteAccess() )
{
s.append("true");
}
else {
else
{
s.append("false");
}
@@ -520,7 +562,8 @@ int CAFE::group2XML (const char * grpName, std::string fileName)
int status=CAFE::groupMemberList(grpName, lg);
for (int j=0; j<lg.size(); ++j) {
for (unsigned int j=0; j<lg.size(); ++j)
{
s.append(" <cafe:member> <cafe:name> ");
s.append(lg[j]);
s.append(" </cafe:name> </cafe:member>\n");
+144 -74
View File
@@ -31,26 +31,30 @@ using namespace std;
void ChannelCreatePolicy::callbackHandlerCreate(struct connection_handler_args args)
{
#define __METHOD__ "ChannelCreatePolicy::callbackHandlerCreate"
//Use for debugging
unsigned int _handle = (unsigned long) ca_puser(args.chid);
//std::cout << __METHOD__ << " args.op " << args.op << " for handle " << _handle << std:: endl;
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find((unsigned int)_handle);
if (it_handle != handle_index.end()) {
if (args.op == CA_OP_CONN_UP) {
//START MUTEX LOCK
if (it_handle != handle_index.end())
{
if (args.op == CA_OP_CONN_UP)
{
//START MUTEX LOCK
//Modifies corresponding local variables
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_connectionHandlerArgs(args));
//if(MUTEX){cafeMutex.unlock();}
if(MUTEX)
{
cafeMutex.unlock();
}
chtype buffer_TIME_Type = dbf_type_to_DBR_TIME(ca_field_type(args.chid)); //DBF_STRING
chtype buffer_CTRL_Type = dbf_type_to_DBR_CTRL(ca_field_type(args.chid));
@@ -60,25 +64,33 @@ void ChannelCreatePolicy::callbackHandlerCreate(struct connection_handler_args a
//BUFFER FOR PUT has DBR size
//BUFFER FOR CTRL has DBR_CTRL size
//////if(MUTEX){cafeMutex.lock();}
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_dataBufferSize_PRIMITIVE(buffer_PRIMITIVE_TYPE));
handle_index.modify(it_handle, change_dataBufferSize_CTRL (buffer_CTRL_Type));
handle_index.modify(it_handle, change_dataBufferSize_TIME (buffer_TIME_Type));
handle_index.modify(it_handle, change_dataBufferSize_STSACK ()); //fixed size DBR_STSACK_STRING
if ( (*it_handle).getAccessRead() != ca_read_access(args.chid) ) {
//cout << " This will only occur if CAFE's access right handler is not used " << endl;
//cout << " accessRightsEventHandler not called BEFORE channelEventHandler! " << endl;
//cout << " FORCING MODIFICATION IN HASH TABLE FOR READ ACCESS=" << ca_read_access(args.chid) << endl;
if ( (*it_handle).getAccessRead() != ca_read_access(args.chid) )
{
cout << " This will only occur if CAFE's access right handler is not used " << endl;
cout << " accessRightsEventHandler not called BEFORE channelEventHandler! " << endl;
cout << " FORCING MODIFICATION IN HASH TABLE FOR READ ACCESS=" << ca_read_access(args.chid) << endl;
handle_index.modify(it_handle, change_accessRead(ca_read_access(args.chid)));
}
if ( (*it_handle).getAccessWrite() != ca_write_access(args.chid) ) {
//cout << " This will only occur if CAFE's access right handler is not used " << endl;
//cout << " accessRightsEventHandler not called BEFORE channelEventHandler! " << endl;
//cout << " FORCING MODIFICATION IN HASH TABLE FOR WRITE ACCESS=" << ca_write_access(args.chid) << endl;
if ( (*it_handle).getAccessWrite() != ca_write_access(args.chid) )
{
cout << " This will only occur if CAFE's access right handler is not used " << endl;
cout << " accessRightsEventHandler not called BEFORE channelEventHandler! " << endl;
cout << " FORCING MODIFICATION IN HASH TABLE FOR WRITE ACCESS=" << ca_write_access(args.chid) << endl;
handle_index.modify(it_handle, change_accessWrite(ca_write_access(args.chid)));
}
//////if(MUTEX){cafeMutex.unlock();}
if(MUTEX)
{
cafeMutex.unlock();
}
//Set prerequestStatus
ChannelRequestStatus channelRequestStatusGet;
@@ -89,7 +101,8 @@ void ChannelCreatePolicy::callbackHandlerCreate(struct connection_handler_args a
channelRequestStatusGet = (*it_handle).getChannelRequestStatusGet();
channelRequestStatusGet.setRequestStatus (status);
if (status != ECA_NORMAL) {
if (status != ECA_NORMAL)
{
channelRequestStatusGet.setCallbackKind(false, false); // NOT_INITIATED NOT_TRIGGERED
//////if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_status(status));
@@ -99,23 +112,29 @@ void ChannelCreatePolicy::callbackHandlerCreate(struct connection_handler_args a
CAFEStatus cafeStatus;
cafeStatus.report(status);
}
else {
else
{
channelRequestStatusGet.setCallbackKind(true, false); //PENDING NOT_TRIGGERED
}
//////if(MUTEX){cafeMutex.lock();}
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_channelRequestStatusGet(channelRequestStatusGet));
//if(MUTEX){cafeMutex.unlock();}
if(MUTEX)
{
cafeMutex.unlock();
}
//ca_flush_io();
//cout << __METHOD__ << " handlerGetCtrl " << endl;
//Call callback methods for all types!!
status=(*it_handle).getCtrlWithCallback(CALLBACK_CAFE::handlerGetCtrl);
status=(*it_handle).getCtrlWithCallback(CALLBACK_CAFE::handlerGetCtrlAtConnect);
channelRequestStatusGet = (*it_handle).getChannelRequestStatusGetCtrl();
channelRequestStatusGet.setRequestStatus (status);
if (status != ECA_NORMAL) {
if (status != ECA_NORMAL)
{
channelRequestStatusGet.setCallbackKind(false, false); // NOT_INITIATED NOT_TRIGGERED
//////if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_status(status));
@@ -125,20 +144,28 @@ void ChannelCreatePolicy::callbackHandlerCreate(struct connection_handler_args a
CAFEStatus cafeStatus;
cafeStatus.report(status);
}
else {
else
{
channelRequestStatusGet.setCallbackKind(true, false); //PENDING NOT_TRIGGERED
}
//////if(MUTEX){cafeMutex.lock();}
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_channelRequestStatusGetCtrl(channelRequestStatusGet));
//////if(MUTEX){cafeMutex.unlock();}
if(MUTEX)
{
cafeMutex.unlock();
}
//ca_flush_io();
//cout << __METHOD__ << " handlerGetSTSACK " << endl;
status=(*it_handle).getSTSACKWithCallback(CALLBACK_CAFE::handlerGetSTSACK);
channelRequestStatusGet = (*it_handle).getChannelRequestStatusGetSTSACK();
channelRequestStatusGet.setRequestStatus (status);
if (status != ECA_NORMAL) {
if (status != ECA_NORMAL)
{
channelRequestStatusGet.setCallbackKind(false, false); // NOT_INITIATED NOT_TRIGGERED
//////if(MUTEX){cafeMutex.lock();}
handle_index.modify(it_handle, change_status(status));
@@ -148,57 +175,64 @@ void ChannelCreatePolicy::callbackHandlerCreate(struct connection_handler_args a
CAFEStatus cafeStatus;
cafeStatus.report(status);
}
else {
else
{
channelRequestStatusGet.setCallbackKind(true, false); //PENDING NOT_TRIGGERED
}
//////if(MUTEX){cafeMutex.lock();}
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_channelRequestStatusGetSTSACK(channelRequestStatusGet));
//END MUTEX LOCK
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
//usleep(10000);
//ca_flush_io();
//cout << __METHOD__ << " handlerGetClassName" << endl;
status=(*it_handle).getClassNameWithCallback(CALLBACK_CAFE::handlerGetClassName);
if ( status != ECA_NORMAL) {
if ( status != ECA_NORMAL)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "getClassNameWithCallback(CALLBACK_CAFE::handlerGetClassName) reported error:" << endl;
CAFEStatus cafeStatus;
cafeStatus.report(status);
}
// Check if any monitors for this channel are to be started.....
// If monitors are to be started, then start the monitors
// pass on handler functions
//
// Loop thru monitor waiting list
// monitor in waiting
vector<MonitorPolicy> mpInWaitingV =(*it_handle).getMonitorPolicyInWaitingVector();
vector<MonitorPolicy>::iterator it;
//std::cout << __METHOD__ << __LINE__ << " No of Monitors in Waiting " << mpInWaitingV.size() << std::endl << std::endl;
if (mpInWaitingV.size() > 0) {
ca_flush_io();
}
//std::cout << __METHOD__ << __LINE__ << " No of Monitors in Waiting " << mpInWaitingV.size() << std::endl << std::endl;
if (mpInWaitingV.size() > 0)
{
ca_flush_io();
}
//Iterate
for (it = mpInWaitingV.begin(); it != mpInWaitingV.end(); ++it) {
for (it = mpInWaitingV.begin(); it != mpInWaitingV.end(); ++it)
{
//Check start values;
if ((*it).getNelem()==0) {
if ((*it).getNelem()==0)
{
(*it).setNelem((*it_handle).getChannelRegalia().getNelem());
}
//Check start values;
if ((*it).getDataType()==CAFE_NOT_REQUESTED) {
if ((*it).getDataType()==CAFE_NOT_REQUESTED)
{
(*it).setDataType((*it_handle).getChannelRegalia().getDataType());
}
@@ -207,36 +241,54 @@ void ChannelCreatePolicy::callbackHandlerCreate(struct connection_handler_args a
//std::cout << __METHOD__ << __LINE__ << " STARTING MONITOR for pv " << (*it_handle).pv << std::endl;
status=(*it_handle).monitorStart((*it));
(*it).setStatus(status);
//std::cout << __METHOD__ << __LINE__ << " STARTed MONITOR for pv " << (*it_handle).pv << " with status" << status << std::endl;
//std::cout << __METHOD__ << __LINE__ << " STARTed MONITOR for pv " << (*it_handle).pv << " with status" << status << std::endl;
//Add to vector
//check in to vector<monitorMap>
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_monitorPolicyInsert((*it)));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
}
//loop
for (it = mpInWaitingV.begin(); it != mpInWaitingV.end(); ++it) {
for (it = mpInWaitingV.begin(); it != mpInWaitingV.end(); ++it)
{
unsigned int ID=(*it).getID();
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_monitorPolicyInWaitingErase(ID));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
}
//loop
// This is all done
// Invoke PyConnectHandler in getCtrlWithCallback
// This is because we will need to get the data from CtrlCache for enum strings
// status=(*it_handle).getCtrlWithCallback(CALLBACK_CAFE::handlerGetCtrl);
/*
#if HAVE_PYTHON_H
std::cout << __FILE__ << "//" << __METHOD__ << ":" << __LINE__ << std::endl;
std::cout <<" (*it_handle).PyConnectHandler(); at CONNECT " << (*it_handle).pv << std::endl;
if ((*it_handle).getPyCafe() && (*it_handle).getPyOpenCallbackFlag() ) {
(*it_handle).PyConnectHandler();
}
#endif
*/
}
else {
else
{
// DIS-CONNECTION (i.e. from a previously connected state)
// Setting Access Rights to boolean false. These will in any
@@ -253,42 +305,60 @@ void ChannelCreatePolicy::callbackHandlerCreate(struct connection_handler_args a
// On disconnection invoke PyCafe Monitor callback
//Modifies corresponding local variables
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_connectionHandlerArgs(args));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
#if HAVE_PYTHON_H
// monitors
if ((*it_handle).getPyCafe() )
{
vector<MonitorPolicy> mpV =(*it_handle).getMonitorPolicyVector();
vector<MonitorPolicy>::iterator itmp;
vector<MonitorPolicy> mpV =(*it_handle).getMonitorPolicyVector();
vector<MonitorPolicy>::iterator itmp;
//Iterate
for (itmp = mpV.begin(); itmp != mpV.end(); ++itmp)
{
//Iterate
for (itmp = mpV.begin(); itmp != mpV.end(); ++itmp) {
if(MUTEX) {
cafeMutex.lock();
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_usrArgs( (unsigned long) (*itmp).getMonitorID() ));
if(MUTEX)
{
cafeMutex.unlock();
}
//Add datatypes etc...
//std::cout << __METHOD__ << __LINE__ << " (*it_handle).CyDataeventHandler(); at DISCCONNECT " << (*it_handle).pv << std::endl;
//cout << "(*it_handle).PyEventHandler(); " << (*itmp).getMonitorID() << endl;
//(*it_handle).PyEventHandler((*itmp).getMonitorID());
(*it_handle).CyDataEventHandler();
}
handle_index.modify(it_handle, change_usrArgs( (unsigned long) (*itmp).getMonitorID() ));
if(MUTEX) {
cafeMutex.unlock();
//Disconnect signal
if ( (*it_handle).getPyOpenCallbackFlag() )
{
//std::cout << __METHOD__ << __LINE__ << " (*it_handle).PyConnectHandler(); at DISCCONNECT " << (*it_handle).pv << std::endl;
//cout << "(*it_handle).PyConnectHandler(); at Disconnect " << endl;
if ((*it_handle).getPyConnectCallbackVector().size() > 0) {
(*it_handle).PyConnectHandler();
}
}
//Add datatypes etc...
//cout << "(*it_handle).PyEventHandler(); " << (*itmp).getMonitorID() << endl;
(*it_handle).PyEventHandler((*itmp).getMonitorID() );
}
#endif
}
}
else {
else
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__
<< " called with an invalid CAFE handle:" << _handle << endl;
+145 -53
View File
@@ -16,7 +16,7 @@
using namespace std;
using namespace boost::posix_time;
/**
* \brief Callback function for monitor method is invoked
@@ -27,10 +27,11 @@ void MonitorPolicy::callbackHandlerMonitor( struct event_handler_args args)
{
#define __METHOD__ "MonitorPolicy::callbackHandlerMonitor"
if (args.status !=ECA_NORMAL) {
if (args.status !=ECA_NORMAL)
{
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
//return;
}
unsigned int _handle = (unsigned long) ca_puser(args.chid);// args.usr; // ca_puser(args.chid);
@@ -40,40 +41,45 @@ void MonitorPolicy::callbackHandlerMonitor( struct event_handler_args args)
it_handle = handle_index.find((unsigned int)_handle);
if (it_handle != handle_index.end()) {
if (it_handle != handle_index.end())
{
//cout << (*it_handle).getPV() << " " << (*it_handle).getHandle() << endl;
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
/*
if (args.type < DBR_GR_STRING) {
PVDataHolder pvd(args.count);
(*it_handle).getPVDataHolder(pvd);
//// pvd.print();
cout << "val/D//= " << pvd.getAsString(0) << endl;
/*
if (args.type < DBR_GR_STRING) {
PVDataHolder pvd(args.count);
(*it_handle).getPVDataHolder(pvd);
//// pvd.print();
cout << "val/D//= " << pvd.getAsString(0) << endl;
}
else if (args.type < DBR_PUT_ACKT) {
PVCtrlHolder pvc(args.count);
(*it_handle).getPVCtrlHolder(pvc);
////pvc.print();
cout << "val/C/= " << pvc.getAsString(0) << endl;
}
*/
}
else if (args.type < DBR_PUT_ACKT) {
PVCtrlHolder pvc(args.count);
(*it_handle).getPVCtrlHolder(pvc);
////pvc.print();
cout << "val/C/= " << pvc.getAsString(0) << endl;
}
*/
}
else {
else
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
return;
}
#if HAVE_ZEROMQ
if (SF_WITH_PULSE_ID) {
if (SF_WITH_PULSE_ID)
{
cafeConduit_set::iterator itcs;
unsigned long long pulseID=0;
@@ -82,36 +88,46 @@ void MonitorPolicy::callbackHandlerMonitor( struct event_handler_args args)
cafeConduit_set_by_pv::iterator it_pv;
it_pv = pv_index.find(SF_PULSE_ID_PV);
// Three possibilities of getting a match!
if (it_pv != pv_index.end()) {
if ((*it_pv).getChannelID() != NULL) {
// Two possibilities of getting a match!
if (it_pv != pv_index.end())
{
if ((*it_pv).getChannelID() != NULL)
{
(*it_pv).getPVDataHolder(pvd);
pulseID = (unsigned long long) pvd.getAsLongLong();
}
}
else {
else
{
// Loop through all elements and search for pv match
for (itcs = cs.begin(); itcs != cs.end(); ++itcs) {
if ((*itcs).getChannelID() != NULL && (*itcs).getPV()==SF_PULSE_ID_PV) {
for (itcs = cs.begin(); itcs != cs.end(); ++itcs)
{
if ((*itcs).getChannelID() != NULL && (*itcs).getPV()==SF_PULSE_ID_PV)
{
(*itcs).getPVDataHolder(pvd);
pulseID = (unsigned long long) pvd.getAsLongLong();
break;
}
}
}
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
//std::cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << std::endl;
//std::cout << "Pulse Id " << pulseID << std::endl;
handle_index.modify(it_handle, change_beamEventNo(pulseID));
(*it_handle).getPVDataHolder(pvd);
//handle_index.modify(it_handle, change_mapPulseID(pvd));
handle_index.modify(it_handle, change_dequePulseID(pvd));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
} // if SF_WITH_PULSE_ID
} // if SF_WITH_PULSE_ID
#endif
return;
@@ -129,11 +145,14 @@ void MonitorPolicy::PyCallbackHandlerMonitorData (struct event_handler_args args
{
#define __METHOD__ "MonitorPolicy::PyCallbackHandlerMonitorData"
//cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
// cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
if (args.status !=ECA_NORMAL) {
if (args.status !=ECA_NORMAL)
{
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
// return;
}
unsigned int _handle = (unsigned long) ca_puser(args.chid);// args.usr; // ca_puser(args.chid);
@@ -143,32 +162,79 @@ void MonitorPolicy::PyCallbackHandlerMonitorData (struct event_handler_args args
it_handle = handle_index.find((unsigned int)_handle);
if (it_handle != handle_index.end()) {
if (it_handle != handle_index.end())
{
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
#if HAVE_PYTHON_H
if (args.type < DBR_GR_STRING) {
//For monitors args.usr is the id of the monitorpolicy class
//std::cout << "usrArgs == " << args.usr << std::endl;
//Place timecheck here
//Get present timestamp
unsigned long monid = (unsigned long) (*it_handle).getUsrArgs();
//std::cout << "monitorID " << monid << std::endl;
MonitorPolicy mp = (*it_handle).getMonitorPolicy(monid);
//std::cout << "monitorID " << mp.getNotifyDeltaMilliSeconds() << std::endl;
//mp.setNotifyDeltaMilliSeconds(1000);
(*it_handle).PyDataEventHandler();
ptime timeNow(microsec_clock::local_time());
//Get time of last update as recorded in cache
ptime timePrevious = mp.getLastUpdate(); //(*it_handle).getCallback_ptime();
//Compare times and if delta is greater than requested - fire event
time_duration duration(timeNow-timePrevious);
double timeElapsedMilliseconds= (double) duration.total_milliseconds();
double updateDeltaMillioseconds = mp.getNotifyDeltaMilliSeconds(); //1000; //1Hz
//if ( (*it_handle).pv == "SINSB03-DSCR110:ENERGY-OP" ) {
//std::cout << (*it_handle).pv <<" time elapses " << timeElapsedMilliseconds << std::endl;
//std::cout << "monitorID " << monid << " wait" << mp.getNotifyDeltaMilliSeconds() << std::endl;
//}
if (timeElapsedMilliseconds < updateDeltaMillioseconds*0.998) {
return;
}
else {
//update cache with timeNow
// handle_index.modify(it_handle, change_callback_ptime(timeNow));
mp.setLastUpdate(timeNow);
handle_index.modify(it_handle, change_monitorPolicy(mp));
//std::cout << (*it_handle).pv <<" time elapses " << timeElapsedMilliseconds << std::endl;
}
if (args.type < DBR_GR_STRING)
{
//(*it_handle).PyDataEventHandler();
(*it_handle).CyDataEventHandler();
//std::cout << (*it_handle).pv <<" time elapses " << timeElapsedMilliseconds << std::endl;
}
else if (args.type < DBR_PUT_ACKT) {
(*it_handle).PyCtrlEventHandler();
else if (args.type < DBR_PUT_ACKT)
{
//(*it_handle).PyCtrlEventHandler();
(*it_handle).CyCtrlEventHandler();
}
#endif
}
else {
else
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
@@ -178,8 +244,6 @@ void MonitorPolicy::PyCallbackHandlerMonitorData (struct event_handler_args args
};
/**
* \brief Callback function for monitor method is invoked
* with a pointer to the retrieved value; also fires a user supplied Python callback.
@@ -190,10 +254,11 @@ void MonitorPolicy::PyCallbackHandlerMonitor (struct event_handler_args args)
#define __METHOD__ "MonitorPolicy::PyCallbackHandlerMonitor"
if (args.status !=ECA_NORMAL) {
if (args.status !=ECA_NORMAL)
{
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
// return;
}
unsigned int _handle = (unsigned long) ca_puser(args.chid);// args.usr; // ca_puser(args.chid);
@@ -203,26 +268,53 @@ void MonitorPolicy::PyCallbackHandlerMonitor (struct event_handler_args args)
it_handle = handle_index.find((unsigned int)_handle);
if (it_handle != handle_index.end()) {
if (it_handle != handle_index.end())
{
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
#if HAVE_PYTHON_H
(*it_handle).PyEventHandler();
unsigned long monid = (unsigned long) (*it_handle).getUsrArgs();
MonitorPolicy mp = (*it_handle).getMonitorPolicy(monid);
ptime timeNow(microsec_clock::local_time());
//Get time of last update as recorded in cache
ptime timePrevious = mp.getLastUpdate(); //(*it_handle).getCallback_ptime();
//Compare times and if delta is greater than requested - fire event
time_duration duration(timeNow-timePrevious);
double timeElapsedMilliseconds= (double) duration.total_milliseconds();
double updateDeltaMillioseconds = mp.getNotifyDeltaMilliSeconds();
if (timeElapsedMilliseconds < updateDeltaMillioseconds*0.998) {
return;
}
else {
mp.setLastUpdate(timeNow);
handle_index.modify(it_handle, change_monitorPolicy(mp));
}
//(*it_handle).PyEventHandler();
(*it_handle).CyEventHandler();
#endif
}
else {
else
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
+293 -84
View File
@@ -7,6 +7,7 @@
#include <conduit.h>
#include <helper.h>
//include <boost/date_time/posix_time/posix_time.hpp>
unsigned int Conduit::handleNext=0; //4294967295;
unsigned int MonitorPolicy::idNext=0xfff; //4095
@@ -21,7 +22,6 @@ Conduit::Conduit( ) {};
*/
Conduit::~Conduit() {};
/*
Conduit::Conduit(const char * _pv, ca_client_context *_ccc, bool _pyCafeFlag) {
@@ -57,8 +57,7 @@ Conduit::Conduit(const char * _pv, ca_client_context *_ccc,
ChannelRequestPolicy _channelRequestPolicyPut, ChannelRequestPolicy _channelRequestPolicyGet,
ChannelGetActionWhenMonitorPolicy _channelGetActionWhenMonitorPolicy,
bool _pyCafeFlag)
{
{
// To avoid the following compilation error
// conduit.cpp:41: warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x
//epicsAlarmSeverityStrings= {"NO_ALARM","MINOR","MAJOR","INVALID"};
@@ -97,7 +96,8 @@ Conduit::Conduit(const char * _pv, ca_client_context *_ccc,
pv = _pv;
++handleNext;
if(handleNext==0) { // In case we loop round 4294967295(!)
if(handleNext==0) // In case we loop round 4294967295(!)
{
++handleNext; // 0 reserved for handle not found
}
@@ -105,30 +105,31 @@ Conduit::Conduit(const char * _pv, ca_client_context *_ccc,
mapPulseIDBufferSize=SF_PULSE_ID_BUFFER_SIZE;
//connectionHandlerArgs = (connect_handler_args) NULL;
//eventHandlerArgs = (event_handler_args) NULL;
handle = handleNext;
groupHandle= 0;
groupHandle = 0;
channelID=NULL;
alarmStatus=-1;
alarmSeverity=-1;
//New Oct. 2018
desc="";
//hhsv=-1;
//hsv =-1;
//lsv =-1;
//llsv=-1;
alarmStatus = -1;
alarmSeverity = -1;
//New Oct. 2018
desc="";
//hhsv=-1;
//hsv =-1;
//lsv =-1;
//llsv=-1;
aSevStruct.hhsv=-1;
aSevStruct.hsv =-1;
aSevStruct.lsv =-1;
aSevStruct.llsv=-1;
hasDesc=false;
hasAlarmSevStruct=false;
hasDesc=false;
hasAlarmSevStruct=false;
ts.secPastEpoch=0;
ts.nsec=0;
@@ -159,11 +160,15 @@ Conduit::Conduit(const char * _pv, ca_client_context *_ccc,
deviceAttributeDeliminator=DEFAULT_DEVICE_ATTRIBUTE_DELIMINATOR;
channelDeviceAttribute.init(pv,deviceAttributeDeliminator);
widgetV.reserve(2);
mpV.reserve(2);
monitorAction.reserve(2);
hasNewData=true; // used by HandleHelper.getMonitorAction(); start with true
//channelRequestPolicyPut
channelRequestPolicyPut.setPolicy(_channelRequestPolicyPut.getWhenToFlushSendBuffer(),
_channelRequestPolicyPut.getWaitKind(), _channelRequestPolicyPut.getMethodKind());
@@ -192,21 +197,36 @@ Conduit::Conduit(const char * _pv, ca_client_context *_ccc,
// CAFENUM::WAIT, CAFENUM::WITHOUT_CALLBACK); //WITH_CALLBACK_DEFAULT);
#if HAVE_PYTHON_H
pyConnectCallbackVector.reserve(1);
pyOpenCallbackFlag=false;
#if HAVE_PYCAFE_EXT
//Do nothing as PyCafe_ext is compiled
//Py_Initialize();
//dlopen("libpython2.6.so", RTLD_GLOBAL|RTLD_LAZY);
//dlopen("/opt/gfa/python-3.5/latest/lib/libpython3.5m.so", RTLD_GLOBAL|RTLD_LAZY);
//PyInit_PyCafe(); from Python 3 onwards
//initPyCafe(); //only if PyCafe.h as opposed to PyCafe_api.h
//PyEval_InitThreads();
//#else
//Py_Initialize();
#else
//Give non Python APIs (e.g. MATLAB) a chance to turn this off
//MATLAB needs to turn this off
//Careful With That GIL, Eugene
//Careful With That GIL,
//Any method that calls this from Python, e.g., open, must be done so ***with*** the GIL
if (pyCafeFlag) {
//Py_Initialize();
import_PyCafe(); // Use PyCafe_api.h
//Set pyCafeFlag to false if opening from C++!
if (pyCafeFlag)
{
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
//std::cout << "GIL state " << std::endl;
import_PyCafe(); // Use PyCafe_api.h
PyGILState_Release(gstate);
}
#endif
@@ -215,9 +235,52 @@ Conduit::Conduit(const char * _pv, ca_client_context *_ccc,
}
#if HAVE_PYTHON_H
void * Conduit::PyGetHandler() const
/*void * Conduit::PyOpenHandler() const
{
py_cb_handle_open_wrapper(handle, channelRegalia.cafeConnectionState);
return (void *) 0;
}*/
/*void * Conduit::PyConnectHandler() const
{
py_cb_handle_connect_wrapper(handle, pv, channelRegalia.cafeConnectionState);
return (void *) 0;
}*/
void * Conduit::PyConnectHandler() const
{
//std::cout << pyConnectCallbackFn << std::endl;
//if (pyConnectCallbackFn != NULL) {
// cy_connect_handler_wrapper(pyConnectCallbackFn, handle, pv, channelRegalia.cafeConnectionState);
// }
for (unsigned int i=0; i < pyConnectCallbackVector.size(); ++i) {
//std::cout << "\n void * Conduit::PyConnectHandler() " << handle << " "
// << " " << pv << " " << channelRegalia.cafeConnectionState << std::endl;
//std::cout << i << " " << pyConnectCallbackVector[i] << std::endl;
cy_connect_handler_wrapper(pyConnectCallbackVector[i], handle, pv, channelRegalia.cafeConnectionState);
//std::cout << "==============================================================================\n" << std::endl;
}
return (void *) 0;
}
void * Conduit::PyGetHandler() const
{
//PVDataHolder pvd(channelRequestMetaData.nelem);
//size is set in conduitEventHandlerArgs.h
//getPVDataHolder(pvd);
//std::cout << "PyGetHandler" << pvd.getAsString(0) << std::endl;
py_cb_handle_get_wrapper(handle);
return (void *) 0;
@@ -231,37 +294,89 @@ void * Conduit::PyPutHandler() const
return (void *) 0;
}
void * Conduit::PyEventHandler() const
/*void * Conduit::PyEventHandler() const
{
//py_cb_handle_wrapper(handle);
py_cb_handle_monid_wrapper(handle, (unsigned long) usrArgs);
return (void *) 0;
}
}*/
void * Conduit::PyEventHandler(unsigned int monid) const
/*void * Conduit::PyEventHandler(unsigned int monid) const
{
//py_cb_handle_wrapper(handle);
py_cb_handle_monid_wrapper(handle, monid);
return (void *) 0;
}*/
void * Conduit::CyEventHandler() const
{
void * cythonCallback = NULL;
for (int i=0; i < mpV.size(); ++i) {
if ((unsigned long) mpV[i].getID() == (unsigned long) usrArgs) {
cythonCallback = mpV[i].getCyCallback();
break;
}
}
//std::cout << " cythonCallback " << cythonCallback << std:: endl;
if (cythonCallback == NULL) {
//std::cout << " NO CYTHON CALLBACK MATCH FOUND in Conduit::CyEventHandler()" << std::endl;
return (void *) 0; ;
}
cy_event_handler_wrapper(cythonCallback, handle, pv);
return (void *) 0;
}
void * Conduit::PyDataEventHandler() const
{
/*void * Conduit::PyDataEventHandler() const
{
PVDataHolder pvd(channelRequestMetaData.nelem);
//size is set in conduitEventHandlerArgs.h
getPVDataHolder(pvd);
py_cb_wrapper(pvd, handle, pv);
return (void *) 0;
}*/
void * Conduit::CyDataEventHandler() const
{
PVDataHolder pvd(channelRequestMetaData.nelem);
//size is set in conduitEventHandlerArgs.h
void * cythonCallback = NULL;
for (int i=0; i < mpV.size(); ++i) {
//std::cout << i << " " << mpV[i].getCyCallback()
// << " " << mpV[i].getID()
// << std::endl;
if ((unsigned long) mpV[i].getID() == (unsigned long) usrArgs) {
cythonCallback = mpV[i].getCyCallback();
break;
}
}
if (cythonCallback == NULL) {
//std::cout << " NO CYTHON CALLBACK MATCH FOUND Conduit::CyDataEventHandler()" << std::endl;
return (void *) 0; ;
}
getPVDataHolder(pvd);
cy_data_event_handler_wrapper(cythonCallback, handle, pv, pvd);
//std::cout << " CYTHON CALLBACK MATCH FOUND Conduit::CyDataEventHandler()" << std::endl;
return (void *) 0;
}
void * Conduit::PyCtrlEventHandler() const
/*void * Conduit::PyCtrlEventHandler() const
{
PVCtrlHolder pvc(channelRequestMetaCtrl.nelem);
@@ -269,10 +384,39 @@ void * Conduit::PyCtrlEventHandler() const
getPVCtrlHolder(pvc);
py_cb_ctrl_wrapper(pvc, handle, pv);
return (void *) 0;
}*/
void * Conduit::CyCtrlEventHandler() const
{
PVCtrlHolder pvc(channelRequestMetaCtrl.nelem);
//size is set in conduitEventHandlerArgs.h
void * cythonCallback = NULL;
for (int i=0; i < mpV.size(); ++i) {
//std::cout << i << " " << mpV[i].getCyCallback()
// << " " << mpV[i].getID()
// << std::endl;
if ((unsigned long) mpV[i].getID() == (unsigned long) usrArgs) {
cythonCallback = mpV[i].getCyCallback();
break;
}
}
if (cythonCallback == NULL) {
//std::cout << " NO CYTHON CALLBACK MATCH FOUND in Conduit::CyCtrlEventHandler()" << std::endl;
return (void *) 0; ;
}
getPVCtrlHolder(pvc);
cy_ctrl_event_handler_wrapper(cythonCallback, handle, pv, pvc);
return (void *) 0;
}
#endif
/**
* \brief Called from Granules.cc \n
* Sends data from the Conduit::putBuffer to the process variable.
@@ -326,8 +470,22 @@ int Conduit::putWithCallback(pCallback callbackHandlerPut) const
int Conduit::get(void) const
{
#define __METHOD__ "Conduit::get(void) "
/* For testing readout time for waveforms!
using namespace boost::posix_time;
ptime timeStart(microsec_clock::local_time());
double timeElapsed=0;
unsigned int nPoll=0;
for (int i=0; i< 100000; ++i) {
ca_array_get(channelRequestMetaData.dbrDataType, channelRequestMetaData.nelem,
channelRegalia.channelID,dataBuffer);
}
ptime timeEnd(microsec_clock::local_time());
time_duration duration(timeEnd-timeStart);
timeElapsed= (double) duration.total_microseconds()/1000000.0;
std::cout << "Time Elapsed " << timeElapsed << std::endl;
*/
return ca_array_get(channelRequestMetaData.dbrDataType, channelRequestMetaData.nelem,
channelRegalia.channelID, dataBuffer);
@@ -344,9 +502,6 @@ int Conduit::getWithCallback(pCallback callbackHandlerGet) const
{
#define __METHOD__ "Conduit::getCallback(pCallback callbackHandlerGet) "
//std::cout << __FILE__ << "//" << __METHOD__ << std::endl;
//std::cout << "nelem= " << channelRequestMetaData.nelem << " handle = " << handle << endl;
return ca_array_get_callback(channelRequestMetaData.dbrDataType, channelRequestMetaData.nelem,
channelRegalia.channelID,callbackHandlerGet,(void *) (long long) handle );
#undef __METHOD__
@@ -439,11 +594,11 @@ int Conduit::getPVDataHolder(PVDataHolder & _pvd) const
chtype channelType = channelRequestMetaData.getDbrDataType();
CAFENUM::DBR_TYPE dbrTypeClass=helper.convertToCAFEDbrTypeClass(channelType);
if ( channelRegalia.getCafeConnectionState() != ICAFE_CS_NEVER_CONN && channelRegalia.getCafeConnectionState() != ICAFE_CS_CLOSED)
{
if ( channelRegalia.getCafeConnectionState() != ICAFE_CS_NEVER_CONN && channelRegalia.getCafeConnectionState() != ICAFE_CS_CLOSED) {
switch(dbrTypeClass) {
switch(dbrTypeClass)
{
case CAFENUM::DBR_PRIMITIVE:
case CAFENUM::DBR_STS:
case CAFENUM::DBR_TIME:
@@ -462,17 +617,17 @@ int Conduit::getPVDataHolder(PVDataHolder & _pvd) const
unsigned int offset = channelRequestMetaData.getOffset(); //channelRequestMetaDataClient.getOffset();
unsigned int nelem = channelRequestMetaData.getNelem()-offset;
nelem=min(_pvd.nelem,nelem); // Add this for getCache method
_pvd.alarmStatus = -1;//alarmStatus;
_pvd.alarmSeverity = -1;//alarmSeverity;
_pvd.ts.nsec = 0;//ts;
_pvd.ts.secPastEpoch= 0;
_pvd.nelem = min(_pvd.size,nelem); //channelRequestMetaData.getNelem();
_pvd.beamEventNo = beamEventNo;
_pvd.status = status;
_pvd.status = status; //ICAFE_NORMAL;
_pvd.dataTypeNative = (CAFE_DATATYPE) channelRegalia.getDataType();
_pvd.dataType = (CAFE_DATATYPE) channelRequestMetaData.getDataType();//dataTypeRequest;
@@ -483,25 +638,29 @@ int Conduit::getPVDataHolder(PVDataHolder & _pvd) const
strcpy(_pvd.device, channelDeviceAttribute.getDevice());
strcpy(_pvd.attrib, channelDeviceAttribute.getAttribute());
if (_pvd.dataTypeNative==DBR_ENUM) {
if (_pvd.dataTypeNative==DBR_ENUM)
{
_pvd.noStr = ((struct dbr_ctrl_enum *) ctrlBuffer)->no_str;
memcpy( _pvd.strs, &(((struct dbr_ctrl_enum *) ctrlBuffer)->strs), sizeof(_pvd.strs)) ;
//for (int i=0; i<_pvd.noStr; ++i) cout << __METHOD__ << i << " " << _pvd.strs[i] << endl;
}
switch (channelType) {
switch (channelType)
{
case DBR_TIME_DOUBLE:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].d = (*(&((dataBuffer)->tdblval.value)+i+offset));
}
_pvd.ts = ((struct dbr_time_double *) dataBuffer)->stamp;
_pvd.alarmStatus = ((struct dbr_time_double *) dataBuffer)->status;
_pvd.alarmSeverity = ((struct dbr_time_double *) dataBuffer)->severity;
break;
case DBR_TIME_FLOAT:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].f = (*(&((dataBuffer)->tfltval.value)+i+offset));
}
_pvd.ts = (epicsTimeStamp) ((struct dbr_time_float *) dataBuffer)->stamp;
@@ -511,7 +670,8 @@ int Conduit::getPVDataHolder(PVDataHolder & _pvd) const
break;
case DBR_TIME_LONG:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].l = (*(&((dataBuffer)->tlngval.value)+i+offset));
}
_pvd.ts = ((struct dbr_time_long *) dataBuffer)->stamp;
@@ -521,7 +681,8 @@ int Conduit::getPVDataHolder(PVDataHolder & _pvd) const
break;
case DBR_TIME_SHORT:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].s = (*(&((dataBuffer)->tshrtval.value)+i+offset));
}
_pvd.ts = ((struct dbr_time_short *) dataBuffer)->stamp;
@@ -531,7 +692,8 @@ int Conduit::getPVDataHolder(PVDataHolder & _pvd) const
break;
case DBR_TIME_ENUM:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].us = (*(&((dataBuffer)->tenmval.value)+i+offset));
}
_pvd.ts = ((struct dbr_time_enum *) dataBuffer)->stamp;
@@ -541,7 +703,8 @@ int Conduit::getPVDataHolder(PVDataHolder & _pvd) const
break;
case DBR_TIME_CHAR:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].ch = (*(&((dataBuffer)->tchrval.value)+i+offset));
}
_pvd.ts = ((struct dbr_time_char *) dataBuffer)->stamp;
@@ -551,7 +714,8 @@ int Conduit::getPVDataHolder(PVDataHolder & _pvd) const
break;
case DBR_TIME_STRING:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
strcpy(_pvd.val[i].str, (*(&((dataBuffer)->tstrval.value)+i+offset)));
}
_pvd.ts = ((struct dbr_time_string *) dataBuffer)->stamp;
@@ -561,7 +725,8 @@ int Conduit::getPVDataHolder(PVDataHolder & _pvd) const
break;
case DBR_STS_DOUBLE:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].d = (*(&((dataBuffer)->sdblval.value)+i+offset));
}
_pvd.alarmStatus = ((struct dbr_sts_double *) dataBuffer)->status;
@@ -570,7 +735,8 @@ int Conduit::getPVDataHolder(PVDataHolder & _pvd) const
break;
case DBR_STS_FLOAT:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].f = (*(&((dataBuffer)->sfltval.value)+i+offset));
}
_pvd.alarmStatus = ((struct dbr_sts_float *) dataBuffer)->status;
@@ -579,7 +745,8 @@ int Conduit::getPVDataHolder(PVDataHolder & _pvd) const
break;
case DBR_STS_LONG:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].l = (*(&((dataBuffer)->slngval.value)+i+offset));
}
_pvd.alarmStatus = ((struct dbr_sts_int *) dataBuffer)->status;
@@ -588,7 +755,8 @@ int Conduit::getPVDataHolder(PVDataHolder & _pvd) const
break;
case DBR_STS_SHORT:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].s = (*(&((dataBuffer)->sshrtval.value)+i+offset));
}
_pvd.alarmStatus = ((struct dbr_sts_short *) dataBuffer)->status;
@@ -597,7 +765,8 @@ int Conduit::getPVDataHolder(PVDataHolder & _pvd) const
break;
case DBR_STS_ENUM:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].us = (*(&((dataBuffer)->senmval.value)+i+offset));
}
_pvd.alarmStatus = ((struct dbr_sts_enum *) dataBuffer)->status;
@@ -606,7 +775,8 @@ int Conduit::getPVDataHolder(PVDataHolder & _pvd) const
break;
case DBR_STS_CHAR:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].ch = (*(&((dataBuffer)->schrval.value)+i+offset));
}
_pvd.alarmStatus = ((struct dbr_sts_char *) dataBuffer)->status;
@@ -615,7 +785,8 @@ int Conduit::getPVDataHolder(PVDataHolder & _pvd) const
break;
case DBR_STS_STRING:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
strcpy(_pvd.val[i].str, (*(&((dataBuffer)->sstrval.value)+i+offset)));
}
_pvd.alarmStatus = ((struct dbr_sts_string *) dataBuffer)->status;
@@ -624,49 +795,57 @@ int Conduit::getPVDataHolder(PVDataHolder & _pvd) const
break;
case DBR_DOUBLE:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].d = (*(&((dataBuffer)->doubleval)+i+offset));
}
break;
case DBR_FLOAT:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].f = (*(&((dataBuffer)->fltval)+i+offset));
}
break;
case DBR_LONG:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].l = (*(&((dataBuffer)->longval)+i+offset));
}
break;
case DBR_SHORT:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].s = (*(&((dataBuffer)->shrtval)+i+offset));
}
break;
case DBR_ENUM:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].us = (*(&((dataBuffer)->enmval)+i+offset));
}
break;
case DBR_CHAR:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
_pvd.val[i].ch = (*(&((dataBuffer)->charval)+i+offset));
}
break;
case DBR_STRING:
for (unsigned int i=0; i<_pvd.nelem; ++i) {
for (unsigned int i=0; i<_pvd.nelem; ++i)
{
strcpy(_pvd.val[i].str, (*(&((dataBuffer)->strval)+i+offset)));
}
break;
case TYPENOTCONN:
if ( channelRegalia.getCafeConnectionState() != ICAFE_CS_NEVER_CONN && channelRegalia.getCafeConnectionState() != ICAFE_CS_CLOSED ) {
if ( channelRegalia.getCafeConnectionState() != ICAFE_CS_NEVER_CONN && channelRegalia.getCafeConnectionState() != ICAFE_CS_CLOSED )
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "ERROR CAFE_TYPENOTCONN: dataType: "
<< channelType << " : " << dbr_type_to_text(channelType) << endl;
@@ -681,10 +860,11 @@ int Conduit::getPVDataHolder(PVDataHolder & _pvd) const
//Do this to prevent overflow error in epicsTime time(ts) routines!
//This bad number can occur in timeouts
if(_pvd.ts.nsec>1000000000) {
if(_pvd.ts.nsec>1000000000)
{
_pvd.ts.nsec=0;
}
return ICAFE_NORMAL;
#undef __METHOD__
@@ -707,9 +887,11 @@ int Conduit::getPVCtrlHolder(PVCtrlHolder & _pvc) const
CAFENUM::DBR_TYPE dbrTypeClass=helper.convertToCAFEDbrTypeClass(channelType);
if ( channelRegalia.getCafeConnectionState() != ICAFE_CS_NEVER_CONN && channelRegalia.getCafeConnectionState() != ICAFE_CS_CLOSED ) {
if ( channelRegalia.getCafeConnectionState() != ICAFE_CS_NEVER_CONN && channelRegalia.getCafeConnectionState() != ICAFE_CS_CLOSED )
{
switch(dbrTypeClass) {
switch(dbrTypeClass)
{
case CAFENUM::DBR_GR:
case CAFENUM::DBR_CTRL:
break;
@@ -749,17 +931,20 @@ int Conduit::getPVCtrlHolder(PVCtrlHolder & _pvc) const
strcpy(_pvc.attrib,channelDeviceAttribute.getAttribute());
if (_pvc.dataTypeNative==DBR_ENUM) {
if (_pvc.dataTypeNative==DBR_ENUM)
{
_pvc.noStr = ((struct dbr_ctrl_enum *) ctrlBuffer)->no_str;
memcpy( _pvc.strs, &(((struct dbr_ctrl_enum *) ctrlBuffer)->strs), sizeof(_pvc.strs)) ;
//for (int i=0; i<_pvc.noStr; ++i) cout << __METHOD__ << i << " " << _pvc.strs[i] << endl;
}
switch (channelType) {
switch (channelType)
{
case DBR_CTRL_CHAR:
for (unsigned int i=0; i<_pvc.nelem; ++i) {
for (unsigned int i=0; i<_pvc.nelem; ++i)
{
_pvc.val[i].ch = (*(&((ctrlBuffer)->cchrval.value)+i+offset));
}
@@ -784,7 +969,8 @@ int Conduit::getPVCtrlHolder(PVCtrlHolder & _pvc) const
break;
case DBR_CTRL_FLOAT:
for (unsigned int i=0; i<_pvc.nelem; ++i) {
for (unsigned int i=0; i<_pvc.nelem; ++i)
{
_pvc.val[i].f = (*(&((ctrlBuffer)->cfltval.value)+i+offset));
}
@@ -809,7 +995,8 @@ int Conduit::getPVCtrlHolder(PVCtrlHolder & _pvc) const
break;
case DBR_CTRL_DOUBLE:
for (unsigned int i=0; i<_pvc.nelem; ++i) {
for (unsigned int i=0; i<_pvc.nelem; ++i)
{
_pvc.val[i].d = (*(&((ctrlBuffer)->cdblval.value)+i+offset));
}
_pvc.precision = ((struct dbr_ctrl_double *) ctrlBuffer)->precision;
@@ -832,7 +1019,8 @@ int Conduit::getPVCtrlHolder(PVCtrlHolder & _pvc) const
break;
case DBR_CTRL_SHORT:
for (unsigned int i=0; i<_pvc.nelem; ++i) {
for (unsigned int i=0; i<_pvc.nelem; ++i)
{
_pvc.val[i].s = (*(&((ctrlBuffer)->cshrtval.value)+i+offset));
}
@@ -856,7 +1044,8 @@ int Conduit::getPVCtrlHolder(PVCtrlHolder & _pvc) const
break;
case DBR_CTRL_LONG:
for (unsigned int i=0; i<_pvc.nelem; ++i) {
for (unsigned int i=0; i<_pvc.nelem; ++i)
{
_pvc.val[i].l = (*(&((ctrlBuffer)->clngval.value)+i+offset));
}
@@ -891,8 +1080,10 @@ int Conduit::getPVCtrlHolder(PVCtrlHolder & _pvc) const
memcpy(_pvc.strs, &(((struct dbr_ctrl_enum *) ctrlBuffer)->strs),
sizeof(char)*MAX_ENUM_STRING_SIZE*MAX_ENUM_STATES);
//no units
memcpy(_pvc.units,"",sizeof(char[MAX_UNITS_SIZE]));
//no units - with gcc 9.3.0 gives warning:
//reading 8 bytes from a region of size 1
//memcpy(_pvc.units,"",sizeof(char[MAX_UNITS_SIZE]));
strcpy(_pvc.units, "");
_pvc.upperDispLimit.us = 0;
_pvc.lowerDispLimit.us = 0;
@@ -911,8 +1102,12 @@ int Conduit::getPVCtrlHolder(PVCtrlHolder & _pvc) const
_pvc.alarmStatus = ((struct dbr_sts_string *) ctrlBuffer)->status;
_pvc.alarmSeverity = ((struct dbr_sts_string *) ctrlBuffer)->severity;
memcpy(_pvc.units,"",sizeof(char[MAX_UNITS_SIZE]));
//no units - with gcc 9.3.0 gives warning:
//reading 8 bytes from a region of size 1
//memcpy(_pvc.units,"",sizeof(char[MAX_UNITS_SIZE]));
strcpy(_pvc.units, "");
_pvc.upperDispLimit.us = 0;
_pvc.lowerDispLimit.us = 0;
_pvc.upperAlarmLimit.us = 0;
@@ -928,7 +1123,7 @@ int Conduit::getPVCtrlHolder(PVCtrlHolder & _pvc) const
break;
}
return ICAFE_NORMAL;
@@ -939,7 +1134,11 @@ int Conduit::getPVCtrlHolder(PVCtrlHolder & _pvc) const
/**
* \brief Starts a monitor on the epics channel
* \brief Starts a monitor on the epics channel.
* Should the MonitorPolicy class have been configured before the channel was first connected
* then the dbrDataType will not be known (-1) if the user requested native data type,
* resulting in an ECA_BADTYPE error. To avoid this mp.dbrDataType should be overwritten
* after interrogating native and dbr data types
* \param mp input: MonitorPolicy class \n
* mp.eventID output: evid identifying the monitor subscription
* \return ECA_NORMAL - normal sucessful completiom
@@ -951,14 +1150,24 @@ int Conduit::monitorStart(MonitorPolicy &mp) const
{
#define __METHOD__ "Conduit::monitorStart(MonitorPolicy mp)"
//cout << __METHOD__ << " mp.getDbrDataType()= " << mp.getDbrDataType() << endl;
//cout << __METHOD__ << " mp.getHandler() = " << mp.getHandler() << endl;
//cout << __METHOD__ << " mp.getUserArgs() = " << mp.getUserArgs() << endl;
//cout << "dataType " << (CAFE_DATATYPE) channelRegalia.getDataType() << endl;
//cout << "native dataType " << (CAFE_DATATYPE) channelRequestMetaData.getDataType() << endl;
//cout << "dbrDataType " << channelRequestMetaData.getDbrDataType() << endl;
if (mp.getDbrDataType()== -1)
{
mp.setDataType((CAFE_DATATYPE) channelRegalia.getDataType() ); // Also sets dbrDataType accordingly
}
evid eventID;
int status = ca_create_subscription(mp.getDbrDataType(), mp.getNelem(), channelRegalia.channelID, mp.getMask(),
mp.getHandler(), (void *) mp.getUserArgs(), &eventID);
mp.setEventID(eventID);
return status;
#undef __METHOD__
};
+20 -10
View File
@@ -64,7 +64,8 @@ ConduitGroup::ConduitGroup(const char * _groupName, ca_client_context * _ccc, C
mStatus = new int [nMember];
mRule = new bool[nMember];
for (unsigned int i=0; i<nMember; ++i) {
for (unsigned int i=0; i<nMember; ++i)
{
mRule[i]=true;
mStatus[i]=ICAFE_NORMAL;
}
@@ -84,13 +85,16 @@ int ConduitGroup::get(void) const
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
for (unsigned int i=0; i<nMember; ++i) {
for (unsigned int i=0; i<nMember; ++i)
{
it_handle = handle_index.find(mHandle[i]);
if (it_handle != handle_index.end()) {
if (it_handle != handle_index.end())
{
if (mStatus[i]==ICAFE_NORMAL) {
if (mStatus[i]==ICAFE_NORMAL)
{
//Returns ECA_NORMAL, ECA_BADSYNCGRP, ECA_BADCHID, ECA_BADCOUNT,
//ECA_BADTYPE, ECA_GETFAIL, or 192 if not connected!
mStatus[i]=ca_sg_array_get (groupID,
@@ -115,12 +119,14 @@ int ConduitGroup::get(void) const
// && ntries<channelTimeoutPolicySGGet.getNtries()
//)
if (groupStatus== ECA_TIMEOUT) {
if (groupStatus== ECA_TIMEOUT)
{
CAFEStatus cafeStatus;
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cafeStatus.report(ECA_TIMEOUT);
}
else if (groupStatus!= ECA_NORMAL) {
else if (groupStatus!= ECA_NORMAL)
{
CAFEStatus cafeStatus;
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "groupID = " << groupID << " groupName = " << groupName << endl;
@@ -143,13 +149,16 @@ int ConduitGroup::put(void) const
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
for (unsigned int i=0; i<nMember; ++i) {
for (unsigned int i=0; i<nMember; ++i)
{
it_handle = handle_index.find(mHandle[i]);
if (it_handle != handle_index.end()) {
if (it_handle != handle_index.end())
{
if (mStatus[i]==ICAFE_NORMAL) {
if (mStatus[i]==ICAFE_NORMAL)
{
//Returns ECA_NORMAL, ECA_BADSYNCGRP, ECA_BADCHID, ECA_BADCOUNT,
//ECA_BADTYPE, ECA_GETFAIL, or 192 if not connected!
mStatus[i]=ca_sg_array_put (groupID,
@@ -198,7 +207,8 @@ int ConduitGroup::put(void) const
if (groupStatus== ECA_TIMEOUT) {
if (groupStatus== ECA_TIMEOUT)
{
CAFEStatus cafeStatus;
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cafeStatus.report(ECA_TIMEOUT);
+1250 -439
View File
File diff suppressed because it is too large Load Diff
+15 -6
View File
@@ -31,21 +31,28 @@ void Connect::callbackHandlerAccessRights(struct access_rights_handler_args args
//Note: At first connection the no of elements is unknown!
//Therefore we cannot allocate memory for data buffers here!
//cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
//std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl;
unsigned int _handle = (unsigned long) ca_puser(args.chid);
//std::cout << "handle " << _handle << std::endl;
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find((unsigned int) _handle);
if (it_handle != handle_index.end()) {
if(MUTEX) {
if (it_handle != handle_index.end())
{
if(MUTEX)
{
cafeMutex.lock();
}
//HandleHelper hh;
//std::cout << hh.getPVFromHandle(_handle) << std::endl;
handle_index.modify(it_handle, change_accessRightsHandlerArgs(args));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
}
@@ -78,7 +85,8 @@ void Connect::callbackHandlerException(struct exception_handler_args args)
char pName[PVNAME_SIZE];
if (args.chid) {
if (args.chid)
{
strcpy(pName, ca_name(args.chid));
_handle = (unsigned long) ca_puser(args.chid);
sprintf(buf,
@@ -88,7 +96,8 @@ void Connect::callbackHandlerException(struct exception_handler_args args)
}
// This case is more usual(!)
else {
else
{
strcpy(pName, "unknown");
sprintf(buf,
"%s with channel=%s, op=%ld, datatype=%s, count=%ld. %s",
+575 -243
View File
File diff suppressed because it is too large Load Diff
+14 -7
View File
@@ -13,18 +13,21 @@
template<typename T>
struct enumStrings {
struct enumStrings
{
static char const* data[];
};
template<typename T>
struct enumRefHolder {
struct enumRefHolder
{
T& enumVal;
enumRefHolder(T& enumVal): enumVal(enumVal) {}
};
template<typename T>
struct enumConstRefHolder {
struct enumConstRefHolder
{
T const& enumVal;
enumConstRefHolder(T const& enumVal): enumVal(enumVal) {}
};
@@ -34,10 +37,12 @@ std::ostream& operator<<(std::ostream& str, enumConstRefHolder<T> const& data)
{
//Add check on enumStrings<T>::data size to ensure correspondence with entries in cafeEnumEpics.h
if ( boost::size( enumStrings<T>::data) > (unsigned int) data.enumVal) {
if ( boost::size( enumStrings<T>::data) > (unsigned int) data.enumVal)
{
return str << enumStrings<T>::data[data.enumVal];
}
else {
else
{
return str << "ERROR: enumStrings.h reports data.enumVal= " << data.enumVal
<< " DOES NOT HAVE A STRING EQUIVALENT!";
}
@@ -59,14 +64,16 @@ std::istream& operator>>(std::istream& str, enumRefHolder<T> const& data)
//if (find != end)
if ( std::find( boost::begin(enumStrings<T>::data), boost::end( enumStrings<T>::data), value) !=
boost::end( enumStrings<T>::data)) {
boost::end( enumStrings<T>::data))
{
//data.enumVal = static_cast<T>(std::distance(begin, find));
data.enumVal = static_cast<T>(std::distance(boost::begin(enumStrings<T>::data),
std::find (boost::begin(enumStrings<T>::data), boost::end(enumStrings<T>::data), value ) ));
}
if (data.enumVal > boost::size( enumStrings<T>::data) ) {
if (data.enumVal > boost::size( enumStrings<T>::data) )
{
std::cout << "ERROR: enumStrings.h reports data.enumVal = " << data.enumVal
<< " is out of enum range = " << boost::size( enumStrings<T>::data) << std::endl;
+46 -23
View File
@@ -20,44 +20,63 @@ using namespace std;
* \param ln input: line number of file from where the error originates
* \return struct CAFEException_pv
*/
CAFEException_pv ExceptionsHelper::prepareCAFEException_pv(const char *pv, const char *pvAlias,
CAFEException_pv ExceptionsHelper::prepareCAFEException_pv (
const char pv[PVNAME_SIZE], const char pvAlias[PVNAME_SIZE],
unsigned int handle, chid pCh, int status,
const char * source, unsigned int ln)
string source, unsigned int ln)
{
#define __METHOD__ "Connect::prepareCAFEException_pv"
CAFEStatus cafeStatus;
CAFEException_pv e;
// handle, pv, pvAlias
e.handle=handle;
if (pv!=NULL) {
if (pv != NULL)
{
strcpy(e.pv, (char *) pv);
}
else {
else
{
strcpy(e.pv, "");
}
if (pvAlias!=NULL) {
if (pvAlias != NULL)
{
strcpy(e.pvAlias, (char *) pvAlias);
}
else {
else
{
strcpy(e.pvAlias, "");
}
// native datatype
if (pCh == NULL) {
if (pCh == NULL)
{
e.dataTypeNative = (CAFE_DATATYPE) CAFE_NO_ACCESS;
}
else if (status == ECAFE_RULE_FALSE || status == ICAFE_RULE_FALSE) {
else if (status == ECAFE_RULE_FALSE || status == ICAFE_RULE_FALSE)
{
e.dataTypeNative = (CAFE_DATATYPE) CAFE_NOT_REQUESTED;
}
else {
else
{
e.dataTypeNative = (CAFE_DATATYPE) dbf_type_to_DBR(ca_field_type(pCh));
}
e.dataTypeNativeText = cafeDataTypeCode.message(e.dataTypeNative).c_str();
// status code, message, description
e.statusCode = status;
e.statusCodeText = (const char *) cafeStatus.csc.message(status).c_str();
e.statusMessage = (const char *) cafeStatus.csi.message(status).c_str();
std::cout << status << " " << (const char*) cafeStatus.csc.message(status).c_str() << std::endl;
std::cout << status << " " << (const char*) cafeStatus.csi.message(status).c_str() << std::endl;
e.statusCodeText = cafeStatus.csc.message(status);
e.statusMessage = cafeStatus.csi.message(status);
// method and line no of error source
e.source = (const char *) source;
e.source = source;
e.ln = ln;
return e;
@@ -77,7 +96,8 @@ void ExceptionsHelper::printCAFEException_pv(CAFEException_pv & e)
cout << "------------------------------------" << endl;
cout << "Handle : " << e.handle << endl;
cout << "Process Variable (PV): " << e.pv << endl;
if ( strcmp(e.pv,e.pvAlias) ) {
if ( strcmp(e.pv,e.pvAlias) )
{
cout << "PV Alias : " << e.pvAlias << endl;
}
cout << "PV Native Type : " << e.dataTypeNative << " ("
@@ -102,27 +122,30 @@ void ExceptionsHelper::printCAFEException_pv(CAFEException_pv & e)
* \param ln input: line number of file from where the error originates
* \return struct CAFEException_group
*/
CAFEException_group ExceptionsHelper::prepareCAFEException_group(char groupName[PVNAME_SIZE],
CAFEException_group ExceptionsHelper::prepareCAFEException_group(const char groupName[PVNAME_SIZE],
unsigned int ghandle, int status,
const char * source, unsigned int ln)
std::string source, unsigned int ln)
{
#define __METHOD__ "Connect::prepareCAFEExceptionGroup"
CAFEException_group e;
// handle, pv, pvAlias
e.groupHandle=ghandle;
if (groupName!=NULL) {
strcpy(e.groupName, groupName);
if (groupName != NULL)
{
strcpy(e.groupName, groupName);
}
else {
strcpy(e.groupName, "");
else
{
strcpy(e.groupName, "");
}
e.statusCode = status;
e.statusCodeText = (const char *) cafeStatus.csc.message(status).c_str();
e.statusMessage = (const char *) cafeStatus.csi.message(status).c_str();
e.statusCodeText = cafeStatus.csc.message(status);
e.statusMessage = cafeStatus.csi.message(status);
// method and line no of error source
e.source = (const char *) source;
e.source = source;
e.ln = ln;
return e;
+663 -333
View File
File diff suppressed because it is too large Load Diff
+1448 -509
View File
File diff suppressed because it is too large Load Diff
+46 -23
View File
@@ -26,7 +26,8 @@ void Helper::removeLeadingAndTrailingSpacesDbrString(const char * pv, char pvStr
size_t found1 = pvS.find_first_not_of(" ");
size_t found2 = pvS.find_last_not_of (" ");
if (found1!=std::string::npos && found2 !=std::string::npos) {
if (found1!=std::string::npos && found2 !=std::string::npos)
{
size_t found21 = std::min((int)((found2+1)-found1), (int) (MAX_STRING_SIZE-1));
size_t length = pvS.copy(pvStripped,found21,found1);
@@ -34,7 +35,8 @@ void Helper::removeLeadingAndTrailingSpacesDbrString(const char * pv, char pvStr
pvStripped[length]='\0'; //required
}
else {
else
{
std::strcpy(pvStripped,"");
}
@@ -58,7 +60,8 @@ void Helper::removeLeadingAndTrailingSpacesPseudo(const char * pv, char pvStripp
size_t found1 = pvS.find_first_not_of(" ");
size_t found2 = pvS.find_last_not_of (" ");
if (found1!=std::string::npos && found2 !=std::string::npos) {
if (found1!=std::string::npos && found2 !=std::string::npos)
{
size_t found21 = std::min((int)((found2+1)-found1), (int) (PVGROUP_PSEUDO_SIZE-1));
size_t length = pvS.copy(pvStripped,found21,found1);
@@ -66,7 +69,8 @@ void Helper::removeLeadingAndTrailingSpacesPseudo(const char * pv, char pvStripp
pvStripped[length]='\0'; //required
}
else {
else
{
std::strcpy(pvStripped,"isEmpty");
}
@@ -90,7 +94,8 @@ void Helper::removeLeadingAndTrailingSpaces(const char * pv, char pvStripped[PVN
size_t found1 = pvS.find_first_not_of(" ");
size_t found2 = pvS.find_last_not_of (" ");
if (found1!=std::string::npos && found2 !=std::string::npos) {
if (found1!=std::string::npos && found2 !=std::string::npos)
{
size_t found21 = std::min((int)((found2+1)-found1), (int) (PVNAME_SIZE-1));
size_t length = pvS.copy(pvStripped,found21,found1);
@@ -98,7 +103,8 @@ void Helper::removeLeadingAndTrailingSpaces(const char * pv, char pvStripped[PVN
pvStripped[length]='\0'; //required
}
else {
else
{
std::strcpy(pvStripped,"isEmpty");
}
@@ -137,19 +143,22 @@ unsigned int Helper::convertToUniqueNumber(const char * pv, ca_client_context *
unsigned int intValueIs=0;
unsigned int iL=0;
for (unsigned int i=0; i< myString.size(); i++) {
for (unsigned int i=0; i< myString.size(); i++)
{
intValueIs= (unsigned int) myString[i];
ld=1;
if ( (intValueIs >47 && intValueIs < 58) ||
(intValueIs >64 && intValueIs < 91) ||
(intValueIs >97 && intValueIs < 123) ) {
(intValueIs >97 && intValueIs < 123) )
{
dpow=pow((float) 42, (int) iL%4);
ld = static_cast<unsigned int>(dpow);
++iL;
}
else {
else
{
iL=0;
}
@@ -190,19 +199,22 @@ unsigned int Helper::convertToUniqueNumber(const char * pv, ca_client_context *
unsigned int intValueIs=0;
unsigned int iL=0;
for (unsigned int i=0; i< myString.size(); i++) {
for (unsigned int i=0; i< myString.size(); i++)
{
intValueIs= (unsigned int) myString[i];
ld=1;
if ( (intValueIs >47 && intValueIs < 58) ||
(intValueIs >64 && intValueIs < 91) ||
(intValueIs >97 && intValueIs < 123) ) {
(intValueIs >97 && intValueIs < 123) )
{
dpow=pow((float)42, (int)iL%4);
ld = static_cast<unsigned int>(dpow);
++iL;
}
else {
else
{
iL=0;
}
@@ -225,31 +237,40 @@ CAFENUM::DBR_TYPE Helper::convertToCAFEDbrTypeClass(const chtype _chtype) const
{
#define __METHOD__ "Helper::convertToCAFEDbrTypeClass(const chtype _chtype)"
if (_chtype>=DBR_STRING && _chtype <= DBR_DOUBLE) {
if (_chtype>=DBR_STRING && _chtype <= DBR_DOUBLE)
{
return CAFENUM::DBR_PRIMITIVE;
}
else if (_chtype>=DBR_STS_STRING && _chtype <= DBR_STS_DOUBLE) {
else if (_chtype>=DBR_STS_STRING && _chtype <= DBR_STS_DOUBLE)
{
return CAFENUM::DBR_STS;
}
else if (_chtype>=DBR_TIME_STRING && _chtype <= DBR_TIME_DOUBLE) {
else if (_chtype>=DBR_TIME_STRING && _chtype <= DBR_TIME_DOUBLE)
{
return CAFENUM::DBR_TIME;
}
else if (_chtype>=DBR_GR_STRING && _chtype <= DBR_GR_DOUBLE) {
else if (_chtype>=DBR_GR_STRING && _chtype <= DBR_GR_DOUBLE)
{
return CAFENUM::DBR_GR;
}
else if (_chtype>=DBR_CTRL_STRING && _chtype <= DBR_CTRL_DOUBLE) {
else if (_chtype>=DBR_CTRL_STRING && _chtype <= DBR_CTRL_DOUBLE)
{
return CAFENUM::DBR_CTRL;
}
else if (_chtype==DBR_PUT_ACKT || _chtype==DBR_PUT_ACKS) {
else if (_chtype==DBR_PUT_ACKT || _chtype==DBR_PUT_ACKS)
{
return CAFENUM::DBR_PUT;
}
else if (_chtype==DBR_STSACK_STRING) {
else if (_chtype==DBR_STSACK_STRING)
{
return CAFENUM::DBR_STSACK;
}
else if (_chtype==DBR_CLASS_NAME) {
else if (_chtype==DBR_CLASS_NAME)
{
return CAFENUM::DBR_CLASS;
}
else {
else
{
return CAFENUM::DBR_NONE;
}
@@ -267,8 +288,10 @@ std::string Helper::concatToString(dbr_char_t * inpChar, unsigned int nChar)
std::string psWF = "";
for (unsigned int i=0; i<nChar; ++i) {
if (inpChar[i] != '\0') {
for (unsigned int i=0; i<nChar; ++i)
{
if (inpChar[i] != '\0')
{
psWF.append(1, inpChar[i]);
}
}
+36 -14
View File
@@ -7,9 +7,14 @@
//has config.h
#include <loadCollectionXMLParser.h>
#if HAVE_LIBQTXML
//#include <QtCore/QString>
const QString& loadCollectionXMLParser::tagConfig = "config";
const QString& loadCollectionXMLParser::tagGroup = "collection";
const QString& loadCollectionXMLParser::tagDescription = "description";
@@ -32,59 +37,75 @@ bool loadCollectionXMLParser::startElement(const QString& namespaceURI, const QS
bool error = false;
if (localName.compare(tagConfig, Qt::CaseInsensitive) == 0) {
if (localName.compare(tagConfig, Qt::CaseInsensitive) == 0)
{
}
else if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0)
{
devCollection = deviceCollection();
devCollection.name = atts.value("id").toAscii().constData();
devCollection.name = atts.value("id").toLatin1().constData();
state=NotWaiting;
}
else if (localName.compare(tagDescription, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagDescription, Qt::CaseInsensitive) == 0)
{
state = WaitingForDescription;
}
else if (localName.compare(tagAttributes, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagAttributes, Qt::CaseInsensitive) == 0)
{
state=NotWaiting;
}
else if (localName.compare(tagAttribute, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagAttribute, Qt::CaseInsensitive) == 0)
{
state=WaitingForAttribute;
}
else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0)
{
cMember=collectionMember();
cMember.devicePosition = atts.value("pos").toFloat();
state=NotWaiting;
}
else if (localName.compare(tagDevice, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagDevice, Qt::CaseInsensitive) == 0)
{
state = WaitingForDevice;
}
else {
else
{
error = true;
}
return !error;
}
bool loadCollectionXMLParser::endElement(const QString& namespaceURI, const QString& localName,
const QString& qName)
{
if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0) {
if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0)
{
deviceCollectionV.push_back(devCollection);
}
else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0)
{
devCollection.cMembers.push_back(cMember);
}
else if (localName.compare(tagAttribute, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagAttribute, Qt::CaseInsensitive) == 0)
{
devCollection.attributes.push_back(attributeName);
}
return true;
}
bool loadCollectionXMLParser::characters(const QString& ch)
{
bool error = false;
std::string data = ch.trimmed().toAscii().constData();;
std::string data = ch.trimmed().toLatin1().constData();;
switch (state) {
switch (state)
{
case WaitingForDevice:
cMember.deviceName = data;
@@ -106,6 +127,7 @@ bool loadCollectionXMLParser::characters(const QString& ch)
break;
}
return !error;
}
#endif
+50 -23
View File
@@ -7,11 +7,13 @@
//Has config.h
#include <loadGroupXMLParser.h>
#if HAVE_LIBQTXML
#include <stdio.h>
#include <stdlib.h>
const QString&loadGroupXMLParser::tagCollection_list = "config";
const QString&loadGroupXMLParser::tagGroup = "group";
@@ -28,6 +30,7 @@ const QString&loadGroupXMLParser::tagId = "id";
const QString&loadGroupXMLParser::tagAttrib = "attribute";
const QString&loadGroupXMLParser::tagCollectiveType = "collectivetype";
loadGroupXMLParser::loadGroupXMLParser()
{
}
@@ -42,79 +45,102 @@ bool loadGroupXMLParser::startElement(const QString& namespaceURI, const QString
bool error = false;
if (localName.compare(tagCollection_list, Qt::CaseInsensitive) == 0) {
if (localName.compare(tagCollection_list, Qt::CaseInsensitive) == 0)
{
}
else if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0)
{
group = deviceGroup();
group.id = atts.value("id").toAscii().constData();
group.id = atts.value("id").toLatin1().constData();
}
else if (localName.compare(tagDescription, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagDescription, Qt::CaseInsensitive) == 0)
{
state = WaitingForDescription;
}
else if (localName.compare(tagStatusGroup, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagStatusGroup, Qt::CaseInsensitive) == 0)
{
state = WaitingForStatusGroup;
}
else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0)
{
state = WaitingForMember;
}
else if (localName.compare(tagName, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagName, Qt::CaseInsensitive) == 0)
{
state = WaitingForName;
}
else if (localName.compare(tagNelem, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagNelem, Qt::CaseInsensitive) == 0)
{
state = WaitingForNelem;
}
else if (localName.compare(tagStatus, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagStatus, Qt::CaseInsensitive) == 0)
{
state = WaitingForStatus;
}
else if (localName.compare(tagRule, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagRule, Qt::CaseInsensitive) == 0)
{
state = WaitingForRule;
}
else if (localName.compare(tagDataType, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagDataType, Qt::CaseInsensitive) == 0)
{
state = WaitingForDataType;
}
else if (localName.compare(tagCollection, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagCollection, Qt::CaseInsensitive) == 0)
{
collection = collectionInGroup();
}
else if (localName.compare(tagId, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagId, Qt::CaseInsensitive) == 0)
{
state = WaitingForId;
}
else if (localName.compare(tagAttrib, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagAttrib, Qt::CaseInsensitive) == 0)
{
state = WaitingForAttrib;
}
else if (localName.compare(tagCollectiveType, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagCollectiveType, Qt::CaseInsensitive) == 0)
{
state = WaitingForCollectiveType;
}
else {
else
{
error = true;
}
return !error;
}
bool loadGroupXMLParser::endElement(const QString& namespaceURI,
const QString& localName, const QString& qName)
{
if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0) {
if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0)
{
groups.push_back(group);
}
else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0)
{
group.xmlMembers.push_back(xmlMem);
}
else if (localName.compare(tagCollection, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagCollection, Qt::CaseInsensitive) == 0)
{
group.collections.push_back(collection);
}
return true;
}
bool loadGroupXMLParser::characters(const QString& ch)
{
bool error = false;
std::string data = ch.trimmed().toAscii().constData();
std::string data = ch.trimmed().toLatin1().constData();
switch (state) {
switch (state)
{
case WaitingForDescription:
group.description = data;
break;
@@ -151,6 +177,7 @@ bool loadGroupXMLParser::characters(const QString& ch)
break;
}
return !error;
}
#endif
+105 -26
View File
@@ -35,10 +35,16 @@ POST_UNINSTALL = :
build_triplet = x86_64-unknown-linux-gnu
host_triplet = x86_64-unknown-linux-gnu
#am__append_1 = PyCafe.cpp
#am__append_2 = zbsCafeService.cpp zbsDataHolders.cpp \
# bitshuffle/bitshuffle_core.c bitshuffle/bitshuffle.c bitshuffle/iochain.c
subdir = src
DIST_COMMON = $(srcdir)/makefile.am $(srcdir)/makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -76,8 +82,13 @@ am__libcafe_la_SOURCES_DIST = cafe.cpp cafeCache.cpp cafeGroup.cpp \
handleHelper.cpp loadCollectionXMLParser.cpp \
loadGroupXMLParser.cpp methodCallbacks.cpp helper.cpp \
policyHelper.cpp conduitGroup.cpp connectGroup.cpp \
transpose.cpp restorePVGroupXMLParser.cpp PyCafe.cpp
transpose.cpp restorePVGroupXMLParser.cpp PyCafe.cpp \
zbsCafeService.cpp zbsDataHolders.cpp \
bitshuffle/bitshuffle_core.c bitshuffle/bitshuffle.c \
bitshuffle/iochain.c
#am__objects_1 = PyCafe.lo
#am__objects_2 = zbsCafeService.lo zbsDataHolders.lo \
# bitshuffle_core.lo bitshuffle.lo iochain.lo
am_libcafe_la_OBJECTS = cafe.lo cafeCache.lo cafeGroup.lo \
cafeVectors.lo cafeXML.lo callbackHandlerCreate.lo \
callbackHandlerMonitor.lo conduit.lo connect.lo \
@@ -85,12 +96,24 @@ am_libcafe_la_OBJECTS = cafe.lo cafeCache.lo cafeGroup.lo \
handleHelper.lo loadCollectionXMLParser.lo \
loadGroupXMLParser.lo methodCallbacks.lo helper.lo \
policyHelper.lo conduitGroup.lo connectGroup.lo transpose.lo \
restorePVGroupXMLParser.lo $(am__objects_1)
restorePVGroupXMLParser.lo $(am__objects_1) $(am__objects_2)
libcafe_la_OBJECTS = $(am_libcafe_la_OBJECTS)
libcafe_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(libcafe_la_LDFLAGS) $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I. -I$(top_builddir)/./include
depcomp = $(SHELL) $(top_srcdir)/./depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
@@ -107,30 +130,27 @@ CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing --run aclocal-1.11
AMTAR = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing --run tar
#if HAVE_ZEROMQ
#libcafe_la_SOURCES += cafeService.cpp
#endif
AM_CPPFLAGS = -fexceptions -fPIC -Wno-deprecated -I/usr/local/epics/base/include/ -I/usr/local/epics/base/include/os/Linux -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include -I/usr/include/QtCore -I/usr/include/QtXml -I$(top_srcdir)/include
AM_LDFLAGS = -L/usr/local/epics/base/lib/SL6-x86_64 -Wl,-rpath,/usr/local/epics/base/lib/SL6-x86_64 -L/usr/lib64 -Wl,-rpath,/usr/lib64
AM_CPPFLAGS = -fexceptions -fPIC -std=c++1z -I/usr/local/epics/base/include/ -I/usr/local/epics/base/include/os/Linux -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include -I$(top_srcdir)/include
AM_LDFLAGS = -L/usr/local/epics/base/lib/SL6-x86_64 -Wl,-rpath,/usr/local/epics/base/lib/SL6-x86_64
AR = ar
AUTOCONF = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing --run autoconf
AUTOHEADER = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing --run autoheader
AUTOMAKE = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing --run automake-1.11
AWK = gawk
CAFE_CPPFLAGS = -I$(top_srcdir)/include
CC = /afs/psi.ch/sys/psi.x86_64_slp6/Programming/gcc/6.3.0/bin/gcc
CC = /opt/psi/Programming/gcc/6.3.0/bin/gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CPP = /afs/psi.ch/sys/psi.x86_64_slp6/Programming/gcc/6.3.0/bin/gcc -E
CPPFLAGS = -fexceptions -fPIC -Wno-deprecated -I/usr/local/epics/base/include/ -I/usr/local/epics/base/include/os/Linux -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include -I/usr/include/QtCore -I/usr/include/QtXml
CXX = /afs/psi.ch/sys/psi.x86_64_slp6/Programming/gcc/6.3.0/bin/g++
CXXCPP = /afs/psi.ch/sys/psi.x86_64_slp6/Programming/gcc/6.3.0/bin/g++ -E
CPP = /opt/psi/Programming/gcc/6.3.0/bin/gcc -E
CPPFLAGS = -fexceptions -fPIC -std=c++1z -I/usr/local/epics/base/include/ -I/usr/local/epics/base/include/os/Linux -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include
CXX = /opt/psi/Programming/gcc/6.3.0/bin/g++
CXXCPP = /opt/psi/Programming/gcc/6.3.0/bin/g++ -E
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
CYGPATH_W = echo
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
DLLTOOL = false
DSYMUTIL =
DUMPBIN =
ECHO_C =
@@ -146,14 +166,16 @@ INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
LD = /usr/bin/ld -m elf_x86_64
LDFLAGS = -L/usr/local/epics/base/lib/SL6-x86_64 -Wl,-rpath,/usr/local/epics/base/lib/SL6-x86_64 -L/usr/lib64 -Wl,-rpath,/usr/lib64
LDFLAGS = -L/usr/local/epics/base/lib/SL6-x86_64 -Wl,-rpath,/usr/local/epics/base/lib/SL6-x86_64
LIBOBJS =
LIBS = -lQtXml -lQtCore
LIBS =
LIBTOOL = $(SHELL) $(top_builddir)/libtool
LIPO =
LN_S = ln -s
LTLIBOBJS =
LT_SYS_LIBRARY_PATH =
MAKEINFO = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing --run makeinfo
MANIFEST_TOOL = :
MKDIR_P = /bin/mkdir -p
NM = /usr/bin/nm -B
NMEDIT =
@@ -164,21 +186,22 @@ OTOOL64 =
PACKAGE = cafe
PACKAGE_BUGREPORT = Bug reports to: jan.chrin@psi.ch
PACKAGE_NAME = CAFE
PACKAGE_STRING = CAFE 1.8.0
PACKAGE_STRING = CAFE 1.12.5
PACKAGE_TARNAME = cafe
PACKAGE_VERSION = 1.8.0
PACKAGE_VERSION = 1.12.5
PATH_SEPARATOR = :
RANLIB = ranlib
SED = /bin/sed
SET_MAKE =
SHELL = /bin/sh
STRIP = strip
VERSION = 1.8.0
VERSION = 1.12.5
abs_builddir = /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/src
abs_srcdir = /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/src
abs_top_builddir = /afs/psi.ch/project/cafe/gitlab/CAFE/cpp
abs_top_srcdir = /afs/psi.ch/project/cafe/gitlab/CAFE/cpp
ac_ct_CC = /afs/psi.ch/sys/psi.x86_64_slp6/Programming/gcc/6.3.0/bin/gcc
ac_ct_AR = ar
ac_ct_CC = /opt/psi/Programming/gcc/6.3.0/bin/gcc
ac_ct_CXX =
ac_ct_DUMPBIN =
am__include = include
@@ -207,16 +230,15 @@ htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/install-sh
libdir = /opt/gfa/cafe/cpp/cafe-1.8.0-gcc-6.3.0/lib
libdir = /opt/gfa/cafe/cpp/cafe-noqt-1.12.5-gcc-6.3.0/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
lt_ECHO = echo
mandir = ${datarootdir}/man
mkdir_p = /bin/mkdir -p
oldincludedir = /usr/include
pdfdir = ${docdir}
prefix = /opt/gfa/cafe/cpp/cafe-1.8.0-gcc-6.3.0
prefix = /opt/gfa/cafe/cpp/cafe-noqt-1.12.5-gcc-6.3.0
program_transform_name = s,x,x,
psdir = ${docdir}
sbindir = ${exec_prefix}/sbin
@@ -228,6 +250,15 @@ top_build_prefix = ../
top_builddir = ..
top_srcdir = ..
lib_LTLIBRARIES = libcafe.la
#10:2:9 11:2:10 12:0:11 12:1:11 13.0.12 13.1.12 13:2:12 13.4.12
#current:revision:age
#maps in soname to:
#1st: current-age
#2nd: age
#3rd: revision
#1.9.1 1.10.2 1.11.0 1.11.1 1.12.0 1.12.1 1.12.2 1.12.4
libcafe_la_LDFLAGS = -version-info 13:4:12
libcafe_la_SOURCES = cafe.cpp cafeCache.cpp cafeGroup.cpp \
cafeVectors.cpp cafeXML.cpp callbackHandlerCreate.cpp \
callbackHandlerMonitor.cpp conduit.cpp connect.cpp \
@@ -235,11 +266,12 @@ libcafe_la_SOURCES = cafe.cpp cafeCache.cpp cafeGroup.cpp \
handleHelper.cpp loadCollectionXMLParser.cpp \
loadGroupXMLParser.cpp methodCallbacks.cpp helper.cpp \
policyHelper.cpp conduitGroup.cpp connectGroup.cpp \
transpose.cpp restorePVGroupXMLParser.cpp $(am__append_1)
transpose.cpp restorePVGroupXMLParser.cpp $(am__append_1) \
$(am__append_2)
all: all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
.SUFFIXES: .c .cpp .lo .o .obj
$(srcdir)/makefile.in: $(srcdir)/makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
@@ -302,7 +334,7 @@ clean-libLTLIBRARIES:
rm -f "$${dir}/so_locations"; \
done
libcafe.la: $(libcafe_la_OBJECTS) $(libcafe_la_DEPENDENCIES)
$(CXXLINK) -rpath $(libdir) $(libcafe_la_OBJECTS) $(libcafe_la_LIBADD) $(LIBS)
$(libcafe_la_LINK) -rpath $(libdir) $(libcafe_la_OBJECTS) $(libcafe_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -311,6 +343,8 @@ distclean-compile:
-rm -f *.tab.c
include ./$(DEPDIR)/PyCafe.Plo
include ./$(DEPDIR)/bitshuffle.Plo
include ./$(DEPDIR)/bitshuffle_core.Plo
include ./$(DEPDIR)/cafe.Plo
include ./$(DEPDIR)/cafeCache.Plo
include ./$(DEPDIR)/cafeGroup.Plo
@@ -327,12 +361,57 @@ include ./$(DEPDIR)/exceptionsHelper.Plo
include ./$(DEPDIR)/granules.Plo
include ./$(DEPDIR)/handleHelper.Plo
include ./$(DEPDIR)/helper.Plo
include ./$(DEPDIR)/iochain.Plo
include ./$(DEPDIR)/loadCollectionXMLParser.Plo
include ./$(DEPDIR)/loadGroupXMLParser.Plo
include ./$(DEPDIR)/methodCallbacks.Plo
include ./$(DEPDIR)/policyHelper.Plo
include ./$(DEPDIR)/restorePVGroupXMLParser.Plo
include ./$(DEPDIR)/transpose.Plo
include ./$(DEPDIR)/zbsCafeService.Plo
include ./$(DEPDIR)/zbsDataHolders.Plo
.c.o:
$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
# source='$<' object='$@' libtool=no \
# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
# $(COMPILE) -c $<
.c.obj:
$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
# source='$<' object='$@' libtool=no \
# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
# $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
# source='$<' object='$@' libtool=yes \
# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
# $(LTCOMPILE) -c -o $@ $<
bitshuffle_core.lo: bitshuffle/bitshuffle_core.c
$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bitshuffle_core.lo -MD -MP -MF $(DEPDIR)/bitshuffle_core.Tpo -c -o bitshuffle_core.lo `test -f 'bitshuffle/bitshuffle_core.c' || echo '$(srcdir)/'`bitshuffle/bitshuffle_core.c
$(am__mv) $(DEPDIR)/bitshuffle_core.Tpo $(DEPDIR)/bitshuffle_core.Plo
# source='bitshuffle/bitshuffle_core.c' object='bitshuffle_core.lo' libtool=yes \
# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
# $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bitshuffle_core.lo `test -f 'bitshuffle/bitshuffle_core.c' || echo '$(srcdir)/'`bitshuffle/bitshuffle_core.c
bitshuffle.lo: bitshuffle/bitshuffle.c
$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bitshuffle.lo -MD -MP -MF $(DEPDIR)/bitshuffle.Tpo -c -o bitshuffle.lo `test -f 'bitshuffle/bitshuffle.c' || echo '$(srcdir)/'`bitshuffle/bitshuffle.c
$(am__mv) $(DEPDIR)/bitshuffle.Tpo $(DEPDIR)/bitshuffle.Plo
# source='bitshuffle/bitshuffle.c' object='bitshuffle.lo' libtool=yes \
# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
# $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bitshuffle.lo `test -f 'bitshuffle/bitshuffle.c' || echo '$(srcdir)/'`bitshuffle/bitshuffle.c
iochain.lo: bitshuffle/iochain.c
$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT iochain.lo -MD -MP -MF $(DEPDIR)/iochain.Tpo -c -o iochain.lo `test -f 'bitshuffle/iochain.c' || echo '$(srcdir)/'`bitshuffle/iochain.c
$(am__mv) $(DEPDIR)/iochain.Tpo $(DEPDIR)/iochain.Plo
# source='bitshuffle/iochain.c' object='iochain.lo' libtool=yes \
# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
# $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o iochain.lo `test -f 'bitshuffle/iochain.c' || echo '$(srcdir)/'`bitshuffle/iochain.c
.cpp.o:
$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+20 -9
View File
@@ -3,22 +3,33 @@
## input file for production of cafe library
##
lib_LTLIBRARIES = libcafe.la
#10:2:9 11:2:10 12:0:11 12:1:11 13.0.12 13.1.12 13:2:12 13.4.12
#current:revision:age
#maps in soname to:
#1st: current-age
#2nd: age
#3rd: revision
#1.9.1 1.10.2 1.11.0 1.11.1 1.12.0 1.12.1 1.12.2 1.12.4
libcafe_la_LDFLAGS = -version-info 13:4:12
libcafe_la_SOURCES = cafe.cpp cafeCache.cpp cafeGroup.cpp cafeVectors.cpp cafeXML.cpp \
callbackHandlerCreate.cpp callbackHandlerMonitor.cpp conduit.cpp connect.cpp connectCallbacks.cpp \
exceptionsHelper.cpp granules.cpp handleHelper.cpp loadCollectionXMLParser.cpp \
loadGroupXMLParser.cpp methodCallbacks.cpp helper.cpp policyHelper.cpp \
conduitGroup.cpp connectGroup.cpp transpose.cpp restorePVGroupXMLParser.cpp
callbackHandlerCreate.cpp callbackHandlerMonitor.cpp conduit.cpp connect.cpp connectCallbacks.cpp \
exceptionsHelper.cpp granules.cpp handleHelper.cpp loadCollectionXMLParser.cpp \
loadGroupXMLParser.cpp methodCallbacks.cpp helper.cpp policyHelper.cpp \
conduitGroup.cpp connectGroup.cpp transpose.cpp restorePVGroupXMLParser.cpp
if HAVE_PYCAFE_EXT
if HAVE_PYCAFE_EXT_
libcafe_la_SOURCES += PyCafe.cpp
endif
#if HAVE_ZEROMQ
#libcafe_la_SOURCES += cafeService.cpp
#endif
if HAVE_ZEROMQ_
libcafe_la_SOURCES += zbsCafeService.cpp zbsDataHolders.cpp \
bitshuffle/bitshuffle_core.c bitshuffle/bitshuffle.c bitshuffle/iochain.c
endif
##bitshuffle/bshuf_h5filter.c bitshuffle/bshuf_h5plugin.c bitshuffle/lzf_h5plugin.c
AM_CPPFLAGS = @AM_CPPFLAGS@ @CAFE_CPPFLAGS@
AM_LDFLAGS= @AM_LDFLAGS@
+402 -103
View File
@@ -28,7 +28,8 @@ void CALLBACK_CAFE::PyHandlerPut( struct event_handler_args args)
{
#define __METHOD__ "CALLBACK_CAFE::PyHandlerPut"
if (args.status !=ECA_NORMAL) {
if (args.status !=ECA_NORMAL)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
@@ -44,7 +45,8 @@ void CALLBACK_CAFE::PyHandlerPut( struct event_handler_args args)
it_handle = handle_index.find((unsigned int) _handle);
if (it_handle != handle_index.end()) {
if (it_handle != handle_index.end())
{
if(MUTEX)cafeMutex.lock();
@@ -66,14 +68,17 @@ void CALLBACK_CAFE::PyHandlerPut( struct event_handler_args args)
//endif
}
else {
else
{
bool internalFlag=false;
cafeConduit_set::iterator itcs;
// Loop through all elements and search for handle
for (itcs = cs.begin(); itcs != cs.end(); ++itcs) {
for (itcs = cs.begin(); itcs != cs.end(); ++itcs)
{
if ( (*itcs).getHandle()==_handle) {
if ( (*itcs).getHandle()==_handle)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " INFORMATION to author: MATCHed Handle= " << _handle << " to PV= " << (*itcs).getPV() << endl;
cout << " by looping through itcs::iterator, since the by_handle::iterator was NOT found! " << endl;
@@ -93,7 +98,8 @@ void CALLBACK_CAFE::PyHandlerPut( struct event_handler_args args)
}
}
if (!internalFlag) {
if (!internalFlag)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
@@ -120,33 +126,34 @@ void CALLBACK_CAFE::PyHandlerGet( struct event_handler_args args)
#define __METHOD__ "CALLBACK_CAFE::PyHandlerGet"
if (args.status !=ECA_NORMAL) {
if (args.status !=ECA_NORMAL)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
}
unsigned int _handle = (unsigned long) args.usr; // ca_puser(args.chid);
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find(_handle);
if (it_handle != handle_index.end()) {
if (it_handle != handle_index.end())
{
ChannelRequestStatus channelRequestStatusGet=(*it_handle).getChannelRequestStatusGet();
channelRequestStatusGet.setCallbackKind(false, true);
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
handle_index.modify(it_handle, change_channelRequestStatusGet(channelRequestStatusGet));
//cout << __METHOD__ << " CALLBACK DONE " << (*it_handle).getChannelRequestStatusGet().getCallbackProgressKind() << endl;
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
@@ -156,26 +163,31 @@ void CALLBACK_CAFE::PyHandlerGet( struct event_handler_args args)
//endif
}
else {
else
{
bool internalFlag=false;
cafeConduit_set::iterator itcs;
// Loop through all elements and search for handle
for (itcs = cs.begin(); itcs != cs.end(); ++itcs) {
for (itcs = cs.begin(); itcs != cs.end(); ++itcs)
{
if ( (*itcs).getHandle()==_handle) {
if ( (*itcs).getHandle()==_handle)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " INFORMATION to author: MATCHed Handle= " << _handle << " to PV= " << (*itcs).getPV() << endl;
cout << " by looping through tcs::iterator, since the by_handle::iterator was NOT found! " << endl;
ChannelRequestStatus channelRequestStatusGet=(*itcs).getChannelRequestStatusGet();
channelRequestStatusGet.setCallbackKind(false, true);
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(itcs, change_eventHandlerArgs (args));
handle_index.modify(itcs, change_channelRequestStatusGet(channelRequestStatusGet));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
@@ -190,16 +202,13 @@ void CALLBACK_CAFE::PyHandlerGet( struct event_handler_args args)
}
}
if (!internalFlag) {
if (!internalFlag)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
}
return;
#undef __METHOD__
@@ -218,7 +227,8 @@ void CALLBACK_CAFE::handlerPulseID( struct event_handler_args args)
{
#define __METHOD__ "CALLBACK_CAFE::handlerPulseID"
if (args.status !=ECA_NORMAL) {
if (args.status !=ECA_NORMAL)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
@@ -234,9 +244,11 @@ void CALLBACK_CAFE::handlerPulseID( struct event_handler_args args)
it_handle = handle_index.find((unsigned int) _handle);
if (it_handle != handle_index.end()) {
if (it_handle != handle_index.end())
{
//std::cout << (*it_handle).getPV() << " / " << (*it_handle).getHandle() ;
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
@@ -246,21 +258,20 @@ void CALLBACK_CAFE::handlerPulseID( struct event_handler_args args)
pulse_id = pvd.getAsULongLong();
//std::cout << " / pulse ID " << pulse_id << std::endl;
handle_index.modify(it_handle, change_beamEventNo(pulse_id));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
}
else {
else
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
return;
}
/*
PVDataHolder pvd;
(*it_handle).getPVDataHolder(pvd);
@@ -287,11 +298,6 @@ void CALLBACK_CAFE::handlerPulseID( struct event_handler_args args)
};
/**
* Callback function for when putWithCallback method is invoked
* \param args input: event handler_args structure
@@ -300,20 +306,26 @@ void CALLBACK_CAFE::handlerPut( struct event_handler_args args)
{
#define __METHOD__ "CALLBACK_CAFE::handlerPut"
if (args.status !=ECA_NORMAL) {
if (args.status !=ECA_NORMAL)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
}
unsigned int _handle = (unsigned long) args.usr;
//cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
//cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << " handle " << _handle << endl;
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find((unsigned int) _handle);
if (it_handle != handle_index.end()) {
if (it_handle != handle_index.end())
{
if(MUTEX)cafeMutex.lock();
@@ -325,19 +337,21 @@ void CALLBACK_CAFE::handlerPut( struct event_handler_args args)
handle_index.modify(it_handle, change_channelRequestStatusPut(channelRequestStatusPut));
if(MUTEX)cafeMutex.unlock();
if(MUTEX)cafeMutex.unlock();
}
else {
else
{
bool internalFlag=false;
cafeConduit_set::iterator itcs;
// Loop through all elements and search for handle
for (itcs = cs.begin(); itcs != cs.end(); ++itcs) {
for (itcs = cs.begin(); itcs != cs.end(); ++itcs)
{
if ( (*itcs).getHandle()==_handle) {
if ( (*itcs).getHandle()==_handle)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " INFORMATION to author: MATCHed Handle= " << _handle << " to PV= " << (*itcs).getPV() << endl;
cout << " by looping through itcs::iterator, since the by_handle::iterator was NOT found! " << endl;
@@ -354,7 +368,8 @@ void CALLBACK_CAFE::handlerPut( struct event_handler_args args)
}
}
if (!internalFlag) {
if (!internalFlag)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
@@ -376,9 +391,11 @@ void CALLBACK_CAFE::handlerGet( struct event_handler_args args)
{
#define __METHOD__ "CALLBACK_CAFE::handlerGet"
if (args.status !=ECA_NORMAL) {
if (args.status !=ECA_NORMAL)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
}
@@ -389,41 +406,50 @@ void CALLBACK_CAFE::handlerGet( struct event_handler_args args)
it_handle = handle_index.find(_handle);
if (it_handle != handle_index.end()) {
if (it_handle != handle_index.end())
{
ChannelRequestStatus channelRequestStatusGet=(*it_handle).getChannelRequestStatusGet();
channelRequestStatusGet.setCallbackKind(false, true);
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
handle_index.modify(it_handle, change_channelRequestStatusGet(channelRequestStatusGet));
//cout << __METHOD__ << " CALLBACK DONE " << (*it_handle).getChannelRequestStatusGet().getCallbackProgressKind() << endl;
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
}
else {
else
{
bool internalFlag=false;
cafeConduit_set::iterator itcs;
// Loop through all elements and search for handle
for (itcs = cs.begin(); itcs != cs.end(); ++itcs) {
for (itcs = cs.begin(); itcs != cs.end(); ++itcs)
{
if ( (*itcs).getHandle()==_handle) {
if ( (*itcs).getHandle()==_handle)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " INFORMATION to author: MATCHed Handle= " << _handle << " to PV= " << (*itcs).getPV() << endl;
cout << " by looping through tcs::iterator, since the by_handle::iterator was NOT found! " << endl;
ChannelRequestStatus channelRequestStatusGet=(*itcs).getChannelRequestStatusGet();
channelRequestStatusGet.setCallbackKind(false, true);
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(itcs, change_eventHandlerArgs (args));
handle_index.modify(itcs, change_channelRequestStatusGet(channelRequestStatusGet));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
@@ -432,7 +458,8 @@ void CALLBACK_CAFE::handlerGet( struct event_handler_args args)
}
}
if (!internalFlag) {
if (!internalFlag)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
@@ -444,19 +471,42 @@ void CALLBACK_CAFE::handlerGet( struct event_handler_args args)
};
/**
* Callback function for handlerGetCtrl method is invoked
* with a pointer to the retrieved value
* Callback function for getCtrlWithCallback at connect is invoked
* with a pointer to the retrieved value. Extra lines for Python
* to cater specifically for enum data types - so enum options
* are filled in advance.
* \param args input: event handler arguments
*/
void CALLBACK_CAFE::handlerGetCtrl( struct event_handler_args args)
void CALLBACK_CAFE::handlerGetCtrlAtConnect( struct event_handler_args args)
{
#define __METHOD__ "CALLBACK_CAFE::handlerGetCtrl "
#define __METHOD__ "CALLBACK_CAFE::handlerGetCtrlAtConnect "
if (args.status !=ECA_NORMAL) {
if (args.status !=ECA_NORMAL)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
#if HAVE_PYTHON_H
unsigned int _handle = (unsigned long) args.usr; // ca_puser(args.chid);
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find(_handle);
if (it_handle != handle_index.end())
{
if ((*it_handle).getPyCafe() && (*it_handle).getPyOpenCallbackFlag() )
{
if ((*it_handle).getPyConnectCallbackVector().size() > 0) {
(*it_handle).PyConnectHandler();
}
}
}
#endif
return;
}
@@ -468,51 +518,191 @@ void CALLBACK_CAFE::handlerGetCtrl( struct event_handler_args args)
it_handle = handle_index.find(_handle);
if (it_handle != handle_index.end()) {
if (it_handle != handle_index.end())
{
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
ChannelRequestStatus channelRequestStatusGetCtrl=(*it_handle).getChannelRequestStatusGetCtrl();
channelRequestStatusGetCtrl.setCallbackKind(false, true);
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_channelRequestStatusGetCtrl(channelRequestStatusGetCtrl));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
#if HAVE_PYTHON_H
//std::cout << __METHOD__ << std::endl;
//std::cout << " (*it_handle).getPyCafe() " << (*it_handle).getPyCafe() << std::endl;
//std::cout << " (*it_handle).getPyOpenCallbackFlag() " << (*it_handle).getPyOpenCallbackFlag()
// << std::endl;
//std::cout << " (*it_handle).getPyConnectCallbackVector().size() " << (*it_handle).getPyConnectCallbackVector().size() << std::endl;
if ((*it_handle).getPyCafe() && (*it_handle).getPyOpenCallbackFlag() )
{
if ((*it_handle).getPyConnectCallbackVector().size() > 0) {
(*it_handle).PyConnectHandler();
}
}
#endif
}
else {
else
{
bool internalFlag=false;
cafeConduit_set::iterator itcs;
// Loop through all elements and search for handle
for (itcs = cs.begin(); itcs != cs.end(); ++itcs) {
for (itcs = cs.begin(); itcs != cs.end(); ++itcs)
{
if ( (*itcs).getHandle()==_handle) {
if ( (*itcs).getHandle()==_handle)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " INFORMATION to author: MATCHed Handle= " << _handle << " to PV= " << (*itcs).getPV() << endl;
cout << " by looping through itcs::iterator, since the by_handle::iterator was NOT found! " << endl;
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(itcs, change_eventHandlerArgs (args));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
ChannelRequestStatus channelRequestStatusGetCtrl=(*itcs).getChannelRequestStatusGetCtrl();
channelRequestStatusGetCtrl.setCallbackKind(false, true);
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(itcs, change_channelRequestStatusGetCtrl(channelRequestStatusGetCtrl));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
#if HAVE_PYTHON_H
if ((*itcs).getPyCafe() && (*itcs).getPyOpenCallbackFlag() )
{
if ((*itcs).getPyConnectCallbackVector().size() > 0) {
(*itcs).PyConnectHandler();
}
}
#endif
internalFlag=true;
break;
}
}
if (!internalFlag)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
}
return;
#undef __METHOD__
};
/**
* Callback function, for getCtrl method, is invoked
* with a pointer to the retrieved value
* \param args input: event handler arguments
*/
void CALLBACK_CAFE::handlerGetCtrl( struct event_handler_args args)
{
#define __METHOD__ "CALLBACK_CAFE::handlerGetCtrl "
if (args.status !=ECA_NORMAL)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
}
unsigned int _handle = (unsigned long) args.usr; // ca_puser(args.chid);
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find(_handle);
if (it_handle != handle_index.end())
{
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
if(MUTEX)
{
cafeMutex.unlock();
}
ChannelRequestStatus channelRequestStatusGetCtrl=(*it_handle).getChannelRequestStatusGetCtrl();
channelRequestStatusGetCtrl.setCallbackKind(false, true);
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_channelRequestStatusGetCtrl(channelRequestStatusGetCtrl));
if(MUTEX)
{
cafeMutex.unlock();
}
}
else
{
bool internalFlag=false;
cafeConduit_set::iterator itcs;
// Loop through all elements and search for handle
for (itcs = cs.begin(); itcs != cs.end(); ++itcs)
{
if ( (*itcs).getHandle()==_handle)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " INFORMATION to author: MATCHed Handle= " << _handle << " to PV= " << (*itcs).getPV() << endl;
cout << " by looping through itcs::iterator, since the by_handle::iterator was NOT found! " << endl;
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(itcs, change_eventHandlerArgs (args));
if(MUTEX)
{
cafeMutex.unlock();
}
ChannelRequestStatus channelRequestStatusGetCtrl=(*itcs).getChannelRequestStatusGetCtrl();
channelRequestStatusGetCtrl.setCallbackKind(false, true);
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(itcs, change_channelRequestStatusGetCtrl(channelRequestStatusGetCtrl));
if(MUTEX)
{
cafeMutex.unlock();
}
@@ -521,7 +711,8 @@ void CALLBACK_CAFE::handlerGetCtrl( struct event_handler_args args)
}
}
if (!internalFlag) {
if (!internalFlag)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
@@ -542,8 +733,9 @@ void CALLBACK_CAFE::handlerGetSTSACK( struct event_handler_args args)
{
#define __METHOD__ "CALLBACK_CAFE::handlerGetSTSACK "
if (args.status !=ECA_NORMAL) {
if (args.status !=ECA_NORMAL)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
@@ -558,53 +750,65 @@ void CALLBACK_CAFE::handlerGetSTSACK( struct event_handler_args args)
it_handle = handle_index.find(_handle);
if (it_handle != handle_index.end()) {
if (it_handle != handle_index.end())
{
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
ChannelRequestStatus channelRequestStatusGetSTSACK=(*it_handle).getChannelRequestStatusGetSTSACK();
channelRequestStatusGetSTSACK.setCallbackKind(false, true);
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_channelRequestStatusGetSTSACK(channelRequestStatusGetSTSACK));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
}
else {
else
{
bool internalFlag=false;
cafeConduit_set::iterator itcs;
// Loop through all elements and search for handle
for (itcs = cs.begin(); itcs != cs.end(); ++itcs) {
for (itcs = cs.begin(); itcs != cs.end(); ++itcs)
{
if ( (*itcs).getHandle()==_handle) {
if ( (*itcs).getHandle()==_handle)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " INFORMATION to author: MATCHed Handle= " << _handle << " to PV= " << (*itcs).getPV() << endl;
cout << " by looping through itcs::iterator, since the by_handle::iterator was NOT found! " << endl;
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(itcs, change_eventHandlerArgs (args));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
ChannelRequestStatus channelRequestStatusGetSTSACK=(*itcs).getChannelRequestStatusGetSTSACK();
channelRequestStatusGetSTSACK.setCallbackKind(false, true);
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(itcs, change_channelRequestStatusGetSTSACK(channelRequestStatusGetSTSACK));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
internalFlag=true;
@@ -612,7 +816,8 @@ void CALLBACK_CAFE::handlerGetSTSACK( struct event_handler_args args)
}
}
if (!internalFlag) {
if (!internalFlag)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
@@ -634,8 +839,10 @@ void CALLBACK_CAFE::handlerGetClassName( struct event_handler_args args)
{
#define __METHOD__ "CALLBACK_CAFE::handlerGetClassName "
if (args.status !=ECA_NORMAL) {
if (args.status !=ECA_NORMAL)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
@@ -649,13 +856,16 @@ void CALLBACK_CAFE::handlerGetClassName( struct event_handler_args args)
it_handle = handle_index.find(_handle);
if (it_handle != handle_index.end()) {
if (it_handle != handle_index.end())
{
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
@@ -663,41 +873,50 @@ void CALLBACK_CAFE::handlerGetClassName( struct event_handler_args args)
channelRequestStatusGetClassName.setCallbackKind(false, true);
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_channelRequestStatusGetClassName(channelRequestStatusGetClassName));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
}
else {
else
{
bool internalFlag=false;
cafeConduit_set::iterator itcs;
// Loop through all elements and search for handle
for (itcs = cs.begin(); itcs != cs.end(); ++itcs) {
for (itcs = cs.begin(); itcs != cs.end(); ++itcs)
{
if ( (*itcs).getHandle()==_handle) {
if ( (*itcs).getHandle()==_handle)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " INFORMATION to author: MATCHed Handle= " << _handle << " to PV= " << (*itcs).getPV() << endl;
cout << " by looping through tcs::iterator, since the by_handle::iterator was NOT found! " << endl;
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(itcs, change_eventHandlerArgs (args));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
ChannelRequestStatus channelRequestStatusGetClassName=(*it_handle).getChannelRequestStatusGetClassName();
channelRequestStatusGetClassName.setCallbackKind(false, true);
if(MUTEX) {
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(itcs, change_channelRequestStatusGetClassName(channelRequestStatusGetClassName));
if(MUTEX) {
if(MUTEX)
{
cafeMutex.unlock();
}
@@ -706,7 +925,8 @@ void CALLBACK_CAFE::handlerGetClassName( struct event_handler_args args)
}
}
if (!internalFlag) {
if (!internalFlag)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
@@ -718,7 +938,86 @@ void CALLBACK_CAFE::handlerGetClassName( struct event_handler_args args)
/**
* Callback function for handlerClassName method is invoked
* with a pointer to the retrieved value
* \param args input: event handler arguments
*/
void CALLBACK_CAFE::handlerGetDescription( struct event_handler_args args)
{
#define __METHOD__ "CALLBACK_CAFE::handlerGetDesscription "
if (args.status !=ECA_NORMAL)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << "Status=" << args.status << " for channel " << ca_name (args.chid) << endl;
return;
}
unsigned int _handle = (unsigned long) args.usr; // ca_puser(args.chid);
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
cafeConduit_set_by_handle::iterator it_handle;
it_handle = handle_index.find(_handle);
if (it_handle != handle_index.end())
{
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(it_handle, change_eventHandlerArgs (args));
if(MUTEX)
{
cafeMutex.unlock();
}
}
else
{
bool internalFlag=false;
cafeConduit_set::iterator itcs;
// Loop through all elements and search for handle
for (itcs = cs.begin(); itcs != cs.end(); ++itcs)
{
if ( (*itcs).getHandle()==_handle)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " INFORMATION to author: MATCHed Handle= " << _handle << " to PV= " << (*itcs).getPV() << endl;
cout << " by looping through tcs::iterator, since the by_handle::iterator was NOT found! " << endl;
if(MUTEX)
{
cafeMutex.lock();
}
handle_index.modify(itcs, change_eventHandlerArgs (args));
if(MUTEX)
{
cafeMutex.unlock();
}
internalFlag=true;
break;
}
}
if (!internalFlag)
{
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
cout << " Internal CAFE ERROR! Unknown Handle! handle=" << _handle << endl;
}
}
//getCache....
//Find Parent Handle...
//getHandlefromPV
//Find New *it_handle
return;
#undef __METHOD__
};
+274 -141
View File
File diff suppressed because it is too large Load Diff
+50 -29
View File
@@ -12,18 +12,17 @@
#if HAVE_LIBQTXML
#include <stdio.h>
#include <stdlib.h>
#include <vector>
using namespace std;
std::vector<std::string> SplitString(const char *str, char c)
{
vector<string> result;
do {
do
{
const char *begin = str;
while(*str != c && *str) {
while(*str != c && *str)
{
str++;
}
result.push_back(string(begin, str));
@@ -64,48 +63,61 @@ bool restorePVGroupXMLParser::startElement(const QString& namespaceURI, const QS
bool error = false;
if (localName.compare(tagConfig, Qt::CaseInsensitive) == 0) {
if (localName.compare(tagConfig, Qt::CaseInsensitive) == 0)
{
state = WaitingForConfig;
}
else if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0)
{
group = PVGroup();
group.setName ( atts.value("id").toAscii().constData() );
group.setName ( atts.value("id").toLatin1().constData() );
pvd = new PVDataHolder[500]; //read in npv
state = WaitingForGroup;
}
else if (localName.compare(tagNPV, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagNPV, Qt::CaseInsensitive) == 0)
{
state = WaitingForNPV;
}
else if (localName.compare(tagDescription, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagDescription, Qt::CaseInsensitive) == 0)
{
state = WaitingForDescription;
}
else if (localName.compare(tagStatusGroup, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagStatusGroup, Qt::CaseInsensitive) == 0)
{
state = WaitingForStatusGroup;
}
else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0)
{
state = WaitingForMember;
}
else if (localName.compare(tagName, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagName, Qt::CaseInsensitive) == 0)
{
state = WaitingForName;
}
else if (localName.compare(tagNelem, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagNelem, Qt::CaseInsensitive) == 0)
{
state = WaitingForNelem;
}
else if (localName.compare(tagStatus, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagStatus, Qt::CaseInsensitive) == 0)
{
state = WaitingForStatus;
}
else if (localName.compare(tagRule, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagRule, Qt::CaseInsensitive) == 0)
{
state = WaitingForRule;
}
else if (localName.compare(tagVal, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagVal, Qt::CaseInsensitive) == 0)
{
state = WaitingForVal;
}
else if (localName.compare(tagSettable, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagSettable, Qt::CaseInsensitive) == 0)
{
state = WaitingForSettable;
}
else {
else
{
error = true;
}
return !error;
@@ -114,16 +126,19 @@ bool restorePVGroupXMLParser::startElement(const QString& namespaceURI, const QS
bool restorePVGroupXMLParser::endElement(const QString& namespaceURI,
const QString& localName, const QString& qName)
{
if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0) {
if (localName.compare(tagGroup, Qt::CaseInsensitive) == 0)
{
group.setPVData(pvd);
group.npv=icount;
}
else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagMember, Qt::CaseInsensitive) == 0)
{
if(settable)++icount;
}
else if (localName.compare(tagNPV, Qt::CaseInsensitive) == 0) {
else if (localName.compare(tagNPV, Qt::CaseInsensitive) == 0)
{
}
@@ -139,10 +154,11 @@ bool restorePVGroupXMLParser::characters(const QString& ch)
bool error = false;
std::string data = ch.trimmed().toAscii().constData();
std::string data = ch.trimmed().toLatin1().constData();
switch (state) {
switch (state)
{
case WaitingForDescription:
case WaitingForGroup:
@@ -172,7 +188,8 @@ bool restorePVGroupXMLParser::characters(const QString& ch)
//if elements > 1, then break up string
//read no of elements and break up with space as deliminater!
if ( pvd[icount].getNelem() >1) {
if ( pvd[icount].getNelem() >1)
{
//parse string
vector<string> v;
@@ -181,21 +198,25 @@ bool restorePVGroupXMLParser::characters(const QString& ch)
v = SplitString(data.c_str(), ' ');
dbr_string_t * arr = new dbr_string_t[ pvd[icount].getNelem()];
for (size_t i=0; i<v.size(); ++i) {
for (size_t i=0; i<v.size(); ++i)
{
strcpy(arr[i], v[i].c_str());
}
pvd[icount].set(arr);
}
else {
else
{
pvd[icount].set(data);
}
break;
case WaitingForSettable:
if ( strcmp(data.c_str(),"true")==0) {
if ( strcmp(data.c_str(),"true")==0)
{
settable = true;
}
else {
else
{
settable=false;
}
break;
+337 -163
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+486
View File
@@ -0,0 +1,486 @@
///
/// \file zbsDataHolders.cpp
/// \author Jan Chrin, PSI
/// \date Release: December 2017
/// \version CAFE 1.5.1
///
#include <zbsDataHolders.h>
using namespace std;
string contentsS="";
string contentsBS="";
unsigned long nCBs=0;
bool callbackLiveFlag=false;
namespace CAFEBS
{
BSChannel BSDataHolder::getBSChannel(unsigned int idx)
{
if(BSDataHolder::isIndexOutOfRange(idx))
{
std::ostringstream oss;
oss << "Exception! Index " << idx
<< " to getBSChannel method is out of range. Valid range is from 0 to " << nPV-1;
throw std::out_of_range(oss.str());
}
return bsChannel[idx];
};
BSChannel BSDataHolder::getBSChannel(std::string _name)
{
for (unsigned int i=0; i<bsChannel.size(); ++i)
{
if (_name == bsChannel[i].getName())
{
return bsChannel[i];
}
}
std::ostringstream oss;
oss << "Exception! PV " << _name
<< " to getBSChannel method is not recognized. Invalid index to bsChannel " ;
throw std::out_of_range(oss.str());
};
void BSDataHolder::setBSChannel(unsigned int idx, BSChannel bsc)
{
bsChannel[idx]=bsc;
return;
}
void BSDataHolder::setBSChannel(BSChannel bsc)
{
int idx= BSDataHolder::getIdxFromName(bsc.getName());
if (idx >-1)
{
bsChannel[idx]=bsc;
}
else
{
std::ostringstream oss;
oss << "Exception! PV " << bsc.getName()
<< " to setBSChannel method is not recognized. Invalid index (-1) to bsChannel " ;
throw std::out_of_range(oss.str());
}
return;
}
int BSDataHolder::getIdxFromName(std::string _name)
{
for (unsigned int i=0; i<bsChannel.size(); ++i)
{
if (_name == bsChannel[i].getName())
{
return (int) i;
}
}
return -1;
}
void BSDataHolder::verifyIndex(unsigned int idx)
{
if(idx >= nPV)
{
std::ostringstream oss;
oss << "Exception! Index " << idx
<< " to BSDataHolder method is out of range. Valid range is from 0 to " << nPV-1;
throw std::out_of_range(oss.str());
}
};
int BSDataHolder::reconnect()
{
#if HAVE_ZEROMQ
if (BSInitialized && isBS)
{
zmq_close (subscriber);
zmq_ctx_destroy (context);
//cout << "Reconnecting to ZMQ stream " << endl;
context = zmq_ctx_new ();
subscriber = zmq_socket (context, ZMQ_SUB);
rc = zmq_connect (subscriber, (const char *) globalBSZmqStream.c_str());
if (rc != 0 )
{
cout << " (BSDataHolder::reconnect() Error is " << zmq_errno() << " " << zmq_strerror(zmq_errno()) << endl;
return ICAFE_ERRNO_BASE+zmq_errno();
}
//Failed rc==0. This is a chnage in the API weher crypto_box returns -1 on a null server key, wheres it used
//to ignore this error (as it ignores other invalid server keys).
//Hintjens added: can't be sure crypto_box always returns 0
//Solution is not to assert on this error, handle it gracefully
//assert (rc == 0);
rc=zmq_setsockopt (subscriber,ZMQ_RCVHWM, &nhwm, sizeof(int));
rc=zmq_setsockopt (subscriber,ZMQ_SNDHWM, &nhwm, sizeof(int));
//assert (rc == 0);
rc=zmq_setsockopt (subscriber,ZMQ_RCVTIMEO, &timeoutMS, sizeof(int));
//assert (rc == 0);
rc=zmq_setsockopt (subscriber,ZMQ_SUBSCRIBE,"",0);
//assert (rc == 0);
//not required
BSInitialized=true;
resourceConnected=false; // Try false so that bsread can have a couple of attempts to bypass resources not available error
//cout << "New zmq context and subscriber created " << endl;
}
#endif
return ICAFE_NORMAL;
}
bool BSDataHolder::setBS(bool BSFlag)
{
if(MUTEX)
{
cafeMutex.lock();
}
if (BSFlag)
{
#if HAVE_CURL
string dataChannels=string("{\"channels\":[");
vector<string> pvNew=pv;
std::cout << " BSInitialized " << BSInitialized << std::endl;
#if HAVE_ZEROMQ
if (!BSInitialized)
{
globalBSZmqStream.clear();
// Curl stuff
CURL *curl;
CURLcode res;
struct curl_slist * slist;
slist = NULL;
slist = curl_slist_append(slist, "Content-Type: application/json");
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
// Curl stuff - end
/*
curl -H "Content-Type: application/json" -X POST -d '{"name": "SINEG01-RCIR-PUP10:SIG-AMPLT", "backend":"sf-databuffer"}' https://dispatcher-api.psi.ch/sf/channel/live
*/
if (curl)
{
curl_easy_setopt(curl, CURLOPT_URL, "https://dispatcher-api.psi.ch/sf/channel/live");
//curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{\"name\": \"SINEG01-RCIR-PUP10:SIG-AMPLT\", \"backend\":\"sf-databuffer\"}");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
//cout << "WAITING FOR CALLBACK... " << endl;
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &RecvResponseCallbackLive);
//res = curl_easy_perform(curl);
//if (res != CURLE_OK) {
// cout << "curl_easy_perform failed " << curl_easy_strerror(res) << endl;
//}
//else {
//cout << " CALLBACK DONE" << endl;
//}
}//if curl
stringstream ss;
size_t found;
string liveString;
std::cout << " bsChannel.size() = " << bsChannel.size() << std::endl;
//reset counter
nBSEnabled=0;
for (size_t i=0; i < bsChannel.size(); ++i)
{
std::cout << " i = " << i << std::endl;
std::cout << bsChannel[i].getName() << std::endl;
liveString=string("{\"name\": \"");
liveString=liveString + string(bsChannel[i].getName());
liveString=liveString + string("\", \"backend\":\"sf-databuffer\"}" );
//Verify Channel
callbackLiveFlag=false;
//std::cout << "liveString " << std::endl;
//std::cout << liveString.c_str() << std::endl;
curl_easy_setopt(curl, CURLOPT_POSTFIELDS,(const char *) liveString.c_str());
res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
cout << "curl_easy_perform failed " << curl_easy_strerror(res) << endl;
}
else
{
cout << " CALLBACK DONE..." << endl;
//curl_easy_cleanup(curl);
//curl_slist_free_all(slist);
//cout << " Value of callback Live is " << callbackLiveFlag << endl;
//slist=NULL;
if (!callbackLiveFlag)
{
cout << "Channel " << bsChannel[i].getName() << " is not available from BSREAD !!" << endl;
bsChannel[i].setBSEnabled(false);
continue;
}
else
{
cout << "Channel " << bsChannel[i].getName() << " IS available from BSREAD " << endl;
++nBSEnabled;
}
}
/*
for (size_t i=1; i < pvNew.size(); ++i) {
found = pvNew[i].find("SARUN08-DBPM210");
if (found != std::string::npos) continue;
found = pvNew[i].find("SARUN08-DBPM410");
if (found != std::string::npos) continue;
found = pvNew[i].find("ENERGY");
if (found != std::string::npos) continue;
dataChannels= dataChannels + string(",{\"name\":\"");
dataChannels= dataChannels + pvNew[i];
dataChannels= dataChannels + string("\",\"backend\":\"sf-databuffer\",\"modulo\":1,\"offset\":0}");
*/
/////found = (bsChannel[i].getName()).find("ENERGY");
////if (found != std::string::npos) continue;
//No joining comma for first entry
if (nBSEnabled==1)
{
dataChannels= dataChannels + string("{\"name\":\"");
}
else
{
dataChannels= dataChannels + string(",{\"name\":\"");
}
dataChannels= dataChannels + string(bsChannel[i].getName());
dataChannels= dataChannels + string("\",\"backend\":\"sf-databuffer\",\"modulo\":");
ss.clear();
ss.str(""); //clear stream;
ss << bsChannel[i].getModulo();
dataChannels= dataChannels + ss.str();
dataChannels= dataChannels + string(",\"offset\":");
ss.clear();
ss.str(""); //clear stream;
ss << bsChannel[i].getOffset();
dataChannels= dataChannels + ss.str();
dataChannels= dataChannels + string("}");
}
dataChannels= dataChannels + string("],");
dataChannels= dataChannels + "\"mapping\":{\"incomplete\":\"fill-null\"},\"channelValidation\":{\"inconsistency\":\"keep-as-is\"},\"sendBehaviour\":{\"strategy\":\"complete-all\"}}";
cout << dataChannels << endl;
const char * data = dataChannels.c_str();
if (curl && (nBSEnabled>0))
{
curl_easy_cleanup(curl);
curl_slist_free_all(slist);
slist=NULL;
//Reinit
slist = curl_slist_append(slist, "Content-Type: application/json");
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "https://dispatcher-api.psi.ch/sf/stream");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); //"-F file=@./dbpm.json"); //data); //
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
cout << "WAITING FOR CALLBACK.... " << endl;
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &RecvResponseCallback);
cout << "curl_easy_perform(curl)" << endl;
res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
cout << "curl_easy_perform failed " << curl_easy_strerror(res) << endl;
}
else
{
cout << " CALLBACK DONE!!" << endl;
curl_easy_cleanup(curl);
curl_slist_free_all(slist);
slist=NULL;
}
}//if curl
else if (curl)
{
curl_easy_cleanup(curl);
curl_slist_free_all(slist);
slist=NULL;
}
curl_global_cleanup();
//cout << " //1// SHOW contentS " << endl;
//cout << contentsBS.c_str() << endl;
Json::Value parsedFromString;
Json::Reader reader;
bool parsingSuccessful;
Json::FastWriter fastWriter;
printf("value= %s\n", contentsBS.c_str());
if (contentsBS.size() > 3)
{
parsingSuccessful=reader.parse(contentsBS.c_str(), parsedFromString);
if (parsingSuccessful)
{
Json::StyledWriter styledWriter;
cout << "STYLED: --------------------------------" << endl;
//cout << styledWriter.write(parsedFromString) << endl;
cout << "----------------------------------" << endl;
cout << parsedFromString["stream"] << endl;
cout << "----------------------------------" << endl;
globalBSZmqStream = fastWriter.write(parsedFromString["stream"]).c_str();
cout << "ZMQ STREAM c_str():" << globalBSZmqStream << endl;
if ( parsedFromString["stream"].isNull() )
{
globalBSZmqStream.clear();
}
}
else
{
cout << "PARSING IN CURL CALLBACK FUNCTION WAS UNSUCCESSFUL !!!" << endl;
cout << contentsBS.c_str() << endl;
cout << reader.getFormattedErrorMessages() << endl;
}
}
if (globalBSZmqStream.empty())
{
cout << "BS Data is not available - EMPTY globalBSZmqStream" << endl;
if(MUTEX)
{
cafeMutex.unlock();
}
BSInitialized=false;
contentsBS="";
return isBS=false;
}
context = zmq_ctx_new ();
//// receiver = zmq_socket (context, ZMQ_PULL);
//HWM has no effect for PULL
//See documentation on zmq-socket
//WHEN PUSH Sender reachers HWM, then it blocks
//// int nhwm=10;
//// zmq_setsockopt (receiver,ZMQ_RCVHWM ,&nhwm, sizeof(int));
// rc = zmq_bind (receiver, "tcp://129.129.145.206:5558"); //ZMQ_PULL
//// assert (rc == 0);
subscriber = zmq_socket (context, ZMQ_SUB);
globalBSZmqStream=globalBSZmqStream.substr(1,globalBSZmqStream.size()-3);
cout << " globalBSZmqStream.c_str() 1 to end-3: " << globalBSZmqStream.c_str() << endl;
rc = zmq_connect (subscriber, (const char *) globalBSZmqStream.c_str());
if (rc != 0 )
{
cout << " Error is " << zmq_errno() << " " << zmq_strerror(zmq_errno()) << " " << ICAFE_ERRNO_BASE+zmq_errno() <<endl;
//return ICAFE_ERRNO_BASE+zmq_errno();
}
//Failed rc==0. This is a change in the API where crypto_box returns -1 on a null server key, whereas it used
//to ignore this error (as it ignores other invalid server keys).
//Hintjens added: can't be sure crypto_box always returns 0
//Solution is not to assert on this error, handle it gracefully
//assert (rc == 0);
//int nhwm=1;
//int timeoutMS=1000; //10; //-1 Wait for Ever
rc=zmq_setsockopt (subscriber,ZMQ_RCVHWM, &nhwm, sizeof(int));
////assert (rc == 0);
//For the subscriber we do not send
rc=zmq_setsockopt (subscriber,ZMQ_SNDHWM, &nhwm, sizeof(int));
rc=zmq_setsockopt (subscriber,ZMQ_RCVTIMEO, &timeoutMS, sizeof(int));
////assert (rc == 0);
rc=zmq_setsockopt (subscriber,ZMQ_SUBSCRIBE,"",0);
////assert (rc == 0);
BSInitialized=true;
}//is BS initialized
#endif //have zeromq
if(MUTEX)
{
cafeMutex.unlock();
}
contentsBS="";
return isBS=BSFlag;
#else //have curl
if(MUTEX)
{
cafeMutex.unlock();
}
return isBS=false;
#endif //have curl
}//isBSFlag
else
{
//Reset these as they are not applicabel for non bsread
global_timestamp.secPastEpoch=0;
global_timestamp.nsec=0;
pulse_id=0;
}
if(MUTEX)
{
cafeMutex.unlock();
}
return isBS=BSFlag;
} // setBS
void BSDataHolder::printHeader()
{
cout << "----------------------------------" << endl;
cout << "htype = " << htype << endl;
cout << "pulse_id = " << pulse_id << endl;
cout << "global_ts = " << global_timestamp.secPastEpoch << " sec. " << global_timestamp.nsec << " nsec" << endl;
cout << "hash = " << hash << endl;
cout << "dh_compression = " << dh_compression << endl;
cout << "----------------------------------" << endl;
//for (size_t i=0; i<bsChannel.size(); ++i) {
//cout << bsChannel[i].getName() << " Val= " << getPVData(i).getAsString()
// << " TS = " << getPVData(i).getEpicsTimeStamp().secPastEpoch
// << " sec. " << getPVData(i).getEpicsTimeStamp().nsec << " nsec." << endl;
//}
}
} //namespace