C99 forbids flex array members in nested structs

Even when they are at the end.  GCC & Clang allow it, but not all
compilers do.

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2019-07-07 10:31:14 +02:00 committed by eboasson
parent ecbee32422
commit 3afce30c37
7 changed files with 88 additions and 80 deletions

View file

@ -95,10 +95,10 @@ nn_entityid_t nn_ntoh_entityid (nn_entityid_t e);
nn_guid_t nn_hton_guid (nn_guid_t g);
nn_guid_t nn_ntoh_guid (nn_guid_t g);
void bswap_sequence_number_set_hdr (nn_sequence_number_set_t *snset);
void bswap_sequence_number_set_bitmap (nn_sequence_number_set_t *snset);
void bswap_fragment_number_set_hdr (nn_fragment_number_set_t *fnset);
void bswap_fragment_number_set_bitmap (nn_fragment_number_set_t *fnset);
void bswap_sequence_number_set_hdr (nn_sequence_number_set_header_t *snset);
void bswap_sequence_number_set_bitmap (nn_sequence_number_set_header_t *snset, uint32_t *bits);
void bswap_fragment_number_set_hdr (nn_fragment_number_set_header_t *fnset);
void bswap_fragment_number_set_bitmap (nn_fragment_number_set_header_t *fnset, uint32_t *bits);
#if defined (__cplusplus)
}

View file

@ -32,25 +32,28 @@ typedef struct {
#define NN_SEQUENCE_NUMBER_UNKNOWN_HIGH -1
#define NN_SEQUENCE_NUMBER_UNKNOWN_LOW 0
#define NN_SEQUENCE_NUMBER_UNKNOWN ((seqno_t) (((uint64_t)NN_SEQUENCE_NUMBER_UNKNOWN_HIGH << 32) | NN_SEQUENCE_NUMBER_UNKNOWN_LOW))
typedef struct nn_sequence_number_set {
/* C99 disallows flex array in nested struct, so only put the
header in. (GCC and Clang allow it, but there are other
compilers in the world as well.) */
typedef struct nn_sequence_number_set_header {
nn_sequence_number_t bitmap_base;
uint32_t numbits;
uint32_t bits[];
} nn_sequence_number_set_t;
} nn_sequence_number_set_header_t;
/* SequenceNumberSet size is base (2 words) + numbits (1 word) +
bitmap ((numbits+31)/32 words), and this at 4 bytes/word */
#define NN_SEQUENCE_NUMBER_SET_MAX_BITS (256u)
#define NN_SEQUENCE_NUMBER_SET_BITS_SIZE(numbits) ((unsigned) (4 * (((numbits) + 31) / 32)))
#define NN_SEQUENCE_NUMBER_SET_SIZE(numbits) (offsetof (nn_sequence_number_set_t, bits) + NN_SEQUENCE_NUMBER_SET_BITS_SIZE (numbits))
#define NN_SEQUENCE_NUMBER_SET_SIZE(numbits) (sizeof (nn_sequence_number_set_header_t) + NN_SEQUENCE_NUMBER_SET_BITS_SIZE (numbits))
typedef unsigned nn_fragment_number_t;
typedef struct nn_fragment_number_set {
typedef struct nn_fragment_number_set_header {
nn_fragment_number_t bitmap_base;
uint32_t numbits;
uint32_t bits[];
} nn_fragment_number_set_t;
} nn_fragment_number_set_header_t;
/* FragmentNumberSet size is base (2 words) + numbits (1 word) +
bitmap ((numbits+31)/32 words), and this at 4 bytes/word */
#define NN_FRAGMENT_NUMBER_SET_MAX_BITS (256u)
#define NN_FRAGMENT_NUMBER_SET_BITS_SIZE(numbits) ((unsigned) (4 * (((numbits) + 31) / 32)))
#define NN_FRAGMENT_NUMBER_SET_SIZE(numbits) (offsetof (nn_fragment_number_set_t, bits) + NN_FRAGMENT_NUMBER_SET_BITS_SIZE (numbits))
#define NN_FRAGMENT_NUMBER_SET_SIZE(numbits) (sizeof (nn_fragment_number_set_header_t) + NN_FRAGMENT_NUMBER_SET_BITS_SIZE (numbits))
typedef int32_t nn_count_t;
#define DDSI_COUNT_MIN (-2147483647 - 1)
#define DDSI_COUNT_MAX (2147483647)
@ -224,11 +227,12 @@ typedef struct AckNack {
SubmessageHeader_t smhdr;
nn_entityid_t readerId;
nn_entityid_t writerId;
nn_sequence_number_set_t readerSNState;
nn_sequence_number_set_header_t readerSNState;
uint32_t bits[];
/* nn_count_t count; */
} AckNack_t;
#define ACKNACK_FLAG_FINAL 0x02u
#define ACKNACK_SIZE(numbits) (offsetof (AckNack_t, readerSNState) + NN_SEQUENCE_NUMBER_SET_SIZE (numbits) + 4)
#define ACKNACK_SIZE(numbits) (offsetof (AckNack_t, bits) + NN_SEQUENCE_NUMBER_SET_SIZE (numbits) + 4)
#define ACKNACK_SIZE_MAX ACKNACK_SIZE (256u)
typedef struct Gap {
@ -236,9 +240,10 @@ typedef struct Gap {
nn_entityid_t readerId;
nn_entityid_t writerId;
nn_sequence_number_t gapStart;
nn_sequence_number_set_t gapList;
nn_sequence_number_set_header_t gapList;
uint32_t bits[];
} Gap_t;
#define GAP_SIZE(numbits) (offsetof (Gap_t, gapList) + NN_SEQUENCE_NUMBER_SET_SIZE (numbits))
#define GAP_SIZE(numbits) (offsetof (Gap_t, bits) + NN_SEQUENCE_NUMBER_SET_SIZE (numbits))
#define GAP_SIZE_MAX GAP_SIZE (256u)
typedef struct InfoTS {
@ -272,7 +277,8 @@ typedef struct NackFrag {
nn_entityid_t readerId;
nn_entityid_t writerId;
nn_sequence_number_t writerSN;
nn_fragment_number_set_t fragmentNumberState;
nn_fragment_number_set_header_t fragmentNumberState;
uint32_t bits[];
/* nn_count_t count; */
} NackFrag_t;
#define NACKFRAG_SIZE(numbits) (offsetof (NackFrag_t, fragmentNumberState) + NN_FRAGMENT_NUMBER_SET_SIZE (numbits) + 4)

View file

@ -46,16 +46,16 @@ struct nn_rmsg_chunk {
/* Size is 0 after initial allocation, must be set with
nn_rmsg_setsize after receiving a packet from the kernel and
before processing it. */
union {
uint32_t size;
/* to ensure reasonable alignment of payload[] */
union {
/* to ensure reasonable alignment of payload */
int64_t l;
double d;
void *p;
} u;
/* payload array stretched to whatever it really is */
unsigned char payload[];
/* unsigned char payload[] -- disallowed by C99 because of nesting */
};
struct nn_rmsg {
@ -95,7 +95,7 @@ struct nn_rmsg {
struct nn_rmsg_chunk chunk;
};
#define NN_RMSG_PAYLOAD(m) ((m)->chunk.payload)
#define NN_RMSG_PAYLOAD(m) ((unsigned char *) (&(m)->chunk + 1))
#define NN_RMSG_PAYLOADOFF(m, o) (NN_RMSG_PAYLOAD (m) + (o))
struct receiver_state {
@ -213,7 +213,7 @@ struct nn_defrag *nn_defrag_new (enum nn_defrag_drop_mode drop_mode, uint32_t ma
void nn_defrag_free (struct nn_defrag *defrag);
struct nn_rsample *nn_defrag_rsample (struct nn_defrag *defrag, struct nn_rdata *rdata, const struct nn_rsample_info *sampleinfo);
void nn_defrag_notegap (struct nn_defrag *defrag, seqno_t min, seqno_t maxp1);
int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnum, struct nn_fragment_number_set *map, uint32_t maxsz);
int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnum, struct nn_fragment_number_set_header *map, uint32_t *mapbits, uint32_t maxsz);
struct nn_reorder *nn_reorder_new (enum nn_reorder_mode mode, uint32_t max_samples);
void nn_reorder_free (struct nn_reorder *r);
@ -222,7 +222,7 @@ struct nn_rdata *nn_rsample_fragchain (struct nn_rsample *rsample);
nn_reorder_result_t nn_reorder_rsample (struct nn_rsample_chain *sc, struct nn_reorder *reorder, struct nn_rsample *rsampleiv, int *refcount_adjust, int delivery_queue_full_p);
nn_reorder_result_t nn_reorder_gap (struct nn_rsample_chain *sc, struct nn_reorder *reorder, struct nn_rdata *rdata, seqno_t min, seqno_t maxp1, int *refcount_adjust);
int nn_reorder_wantsample (struct nn_reorder *reorder, seqno_t seq);
unsigned nn_reorder_nackmap (struct nn_reorder *reorder, seqno_t base, seqno_t maxseq, struct nn_sequence_number_set *map, uint32_t maxsz, int notail);
unsigned nn_reorder_nackmap (struct nn_reorder *reorder, seqno_t base, seqno_t maxseq, struct nn_sequence_number_set_header *map, uint32_t *mapbits, uint32_t maxsz, int notail);
seqno_t nn_reorder_next_seq (const struct nn_reorder *reorder);
struct nn_dqueue *nn_dqueue_new (const char *name, uint32_t max_samples, nn_dqueue_handler_t handler, void *arg);

View file

@ -53,28 +53,28 @@ nn_guid_t nn_ntoh_guid (nn_guid_t g)
return g;
}
void bswap_sequence_number_set_hdr (nn_sequence_number_set_t *snset)
void bswap_sequence_number_set_hdr (nn_sequence_number_set_header_t *snset)
{
bswapSN (&snset->bitmap_base);
snset->numbits = bswap4u (snset->numbits);
}
void bswap_sequence_number_set_bitmap (nn_sequence_number_set_t *snset)
void bswap_sequence_number_set_bitmap (nn_sequence_number_set_header_t *snset, uint32_t *bits)
{
const uint32_t n = (snset->numbits + 31) / 32;
for (uint32_t i = 0; i < n; i++)
snset->bits[i] = bswap4u (snset->bits[i]);
bits[i] = bswap4u (bits[i]);
}
void bswap_fragment_number_set_hdr (nn_fragment_number_set_t *fnset)
void bswap_fragment_number_set_hdr (nn_fragment_number_set_header_t *fnset)
{
fnset->bitmap_base = bswap4u (fnset->bitmap_base);
fnset->numbits = bswap4u (fnset->numbits);
}
void bswap_fragment_number_set_bitmap (nn_fragment_number_set_t *fnset)
void bswap_fragment_number_set_bitmap (nn_fragment_number_set_header_t *fnset, uint32_t *bits)
{
const uint32_t n = (fnset->numbits + 31) / 32;
for (uint32_t i = 0; i < n; i++)
fnset->bits[i] = bswap4u (fnset->bits[i]);
bits[i] = bswap4u (bits[i]);
}

View file

@ -320,8 +320,8 @@ static uint32_t max_rmsg_size_w_hdr (uint32_t max_rmsg_size)
allocate for the worst case, and may waste a few bytes here or
there. */
return
max_uint32 ((uint32_t) offsetof (struct nn_rmsg, chunk.payload),
(uint32_t) offsetof (struct nn_rmsg_chunk, payload))
max_uint32 ((uint32_t) (offsetof (struct nn_rmsg, chunk) + sizeof (struct nn_rmsg_chunk)),
(uint32_t) sizeof (struct nn_rmsg_chunk))
+ max_rmsg_size;
}
@ -512,7 +512,7 @@ static void init_rmsg_chunk (struct nn_rmsg_chunk *chunk, struct nn_rbuf *rbuf)
{
chunk->rbuf = rbuf;
chunk->next = NULL;
chunk->size = 0;
chunk->u.size = 0;
ddsrt_atomic_inc32 (&rbuf->n_live_rmsg_chunks);
}
@ -544,10 +544,10 @@ void nn_rmsg_setsize (struct nn_rmsg *rmsg, uint32_t size)
ASSERT_RBUFPOOL_OWNER (rmsg->chunk.rbuf->rbufpool);
ASSERT_RMSG_UNCOMMITTED (rmsg);
assert (ddsrt_atomic_ld32 (&rmsg->refcount) == RMSG_REFCOUNT_UNCOMMITTED_BIAS);
assert (rmsg->chunk.size == 0);
assert (rmsg->chunk.u.size == 0);
assert (size8 <= rmsg->chunk.rbuf->max_rmsg_size);
assert (rmsg->lastchunk == &rmsg->chunk);
rmsg->chunk.size = size8;
rmsg->chunk.u.size = size8;
#if USE_VALGRIND
VALGRIND_MEMPOOL_CHANGE (rmsg->chunk.rbuf->rbufpool, rmsg, rmsg, offsetof (struct nn_rmsg, chunk.u.payload) + rmsg->chunk.size);
#endif
@ -587,7 +587,7 @@ static void commit_rmsg_chunk (struct nn_rmsg_chunk *chunk)
{
struct nn_rbuf *rbuf = chunk->rbuf;
DDS_LOG(DDS_LC_RADMIN, "commit_rmsg_chunk(%p)\n", (void *) chunk);
rbuf->freeptr = chunk->payload + chunk->size;
rbuf->freeptr = (unsigned char *) (chunk + 1) + chunk->u.size;
}
void nn_rmsg_commit (struct nn_rmsg *rmsg)
@ -602,11 +602,11 @@ void nn_rmsg_commit (struct nn_rmsg *rmsg)
completed before we got to commit. */
struct nn_rmsg_chunk *chunk = rmsg->lastchunk;
DDS_LOG(DDS_LC_RADMIN, "rmsg_commit(%p) refcount 0x%"PRIx32" last-chunk-size %"PRIu32"\n",
(void *) rmsg, rmsg->refcount.v, chunk->size);
(void *) rmsg, rmsg->refcount.v, chunk->u.size);
ASSERT_RBUFPOOL_OWNER (chunk->rbuf->rbufpool);
ASSERT_RMSG_UNCOMMITTED (rmsg);
assert (chunk->size <= chunk->rbuf->max_rmsg_size);
assert ((chunk->size % 8) == 0);
assert (chunk->u.size <= chunk->rbuf->max_rmsg_size);
assert ((chunk->u.size % 8) == 0);
assert (ddsrt_atomic_ld32 (&rmsg->refcount) >= RMSG_REFCOUNT_UNCOMMITTED_BIAS);
assert (ddsrt_atomic_ld32 (&rmsg->chunk.rbuf->n_live_rmsg_chunks) > 0);
assert (ddsrt_atomic_ld32 (&chunk->rbuf->n_live_rmsg_chunks) > 0);
@ -668,10 +668,10 @@ void *nn_rmsg_alloc (struct nn_rmsg *rmsg, uint32_t size)
DDS_LOG(DDS_LC_RADMIN, "rmsg_alloc(%p, %"PRIu32" => %"PRIu32")\n", (void *) rmsg, size, size8);
ASSERT_RBUFPOOL_OWNER (rbuf->rbufpool);
ASSERT_RMSG_UNCOMMITTED (rmsg);
assert ((chunk->size % 8) == 0);
assert ((chunk->u.size % 8) == 0);
assert (size8 <= rbuf->max_rmsg_size);
if (chunk->size + size8 > rbuf->max_rmsg_size)
if (chunk->u.size + size8 > rbuf->max_rmsg_size)
{
struct nn_rbufpool *rbufpool = rbuf->rbufpool;
struct nn_rmsg_chunk *newchunk;
@ -688,8 +688,8 @@ void *nn_rmsg_alloc (struct nn_rmsg *rmsg, uint32_t size)
chunk = newchunk;
}
ptr = chunk->payload + chunk->size;
chunk->size += size8;
ptr = (unsigned char *) (chunk + 1) + chunk->u.size;
chunk->u.size += size8;
DDS_LOG(DDS_LC_RADMIN, "rmsg_alloc(%p, %"PRIu32") = %p\n", (void *) rmsg, size, ptr);
#if USE_VALGRIND
if (chunk == &rmsg->chunk) {
@ -1422,7 +1422,7 @@ void nn_defrag_notegap (struct nn_defrag *defrag, seqno_t min, seqno_t maxp1)
defrag->max_sample = ddsrt_avl_find_max (&defrag_sampletree_treedef, &defrag->sampletree);
}
int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnum, struct nn_fragment_number_set *map, uint32_t maxsz)
int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnum, struct nn_fragment_number_set_header *map, uint32_t *mapbits, uint32_t maxsz)
{
struct nn_rsample *s;
struct nn_defrag_iv *iv;
@ -1446,7 +1446,7 @@ int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnu
else
map->numbits = maxfragnum + 1;
map->bitmap_base = 0;
nn_bitset_one (map->numbits, map->bits);
nn_bitset_one (map->numbits, mapbits);
return (int) map->numbits;
}
}
@ -1491,7 +1491,7 @@ int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnu
/* Clear bitmap, then set bits for gaps in available fragments */
if (map->numbits > maxsz)
map->numbits = maxsz;
nn_bitset_zero (map->numbits, map->bits);
nn_bitset_zero (map->numbits, mapbits);
i = map->bitmap_base;
while (iv && i < map->bitmap_base + map->numbits)
{
@ -1509,7 +1509,7 @@ int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnu
for (; i < map->bitmap_base + map->numbits && i < bound; i++)
{
unsigned x = (unsigned) (i - map->bitmap_base);
nn_bitset_set (map->numbits, map->bits, x);
nn_bitset_set (map->numbits, mapbits, x);
}
/* next sequence of fragments to request retranmsission of starts
at fragment containing maxp1 (because we don't have that byte
@ -1521,7 +1521,7 @@ int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnu
for (; i < map->bitmap_base + map->numbits; i++)
{
unsigned x = (unsigned) (i - map->bitmap_base);
nn_bitset_set (map->numbits, map->bits, x);
nn_bitset_set (map->numbits, mapbits, x);
}
return (int) map->numbits;
}
@ -2268,7 +2268,7 @@ int nn_reorder_wantsample (struct nn_reorder *reorder, seqno_t seq)
return (s == NULL || s->u.reorder.maxp1 <= seq);
}
unsigned nn_reorder_nackmap (struct nn_reorder *reorder, seqno_t base, seqno_t maxseq, struct nn_sequence_number_set *map, uint32_t maxsz, int notail)
unsigned nn_reorder_nackmap (struct nn_reorder *reorder, seqno_t base, seqno_t maxseq, struct nn_sequence_number_set_header *map, uint32_t *mapbits, uint32_t maxsz, int notail)
{
struct nn_rsample *iv;
seqno_t i;
@ -2305,7 +2305,7 @@ unsigned nn_reorder_nackmap (struct nn_reorder *reorder, seqno_t base, seqno_t m
map->numbits = maxsz;
else
map->numbits = (uint32_t) (maxseq + 1 - base);
nn_bitset_zero (map->numbits, map->bits);
nn_bitset_zero (map->numbits, mapbits);
if ((iv = ddsrt_avl_find_min (&reorder_sampleivtree_treedef, &reorder->sampleivtree)) != NULL)
assert (iv->u.reorder.min > base);
@ -2315,7 +2315,7 @@ unsigned nn_reorder_nackmap (struct nn_reorder *reorder, seqno_t base, seqno_t m
for (; i < base + map->numbits && i < iv->u.reorder.min; i++)
{
unsigned x = (unsigned) (i - base);
nn_bitset_set (map->numbits, map->bits, x);
nn_bitset_set (map->numbits, mapbits, x);
}
i = iv->u.reorder.maxp1;
iv = ddsrt_avl_find_succ (&reorder_sampleivtree_treedef, &reorder->sampleivtree, iv);
@ -2327,7 +2327,7 @@ unsigned nn_reorder_nackmap (struct nn_reorder *reorder, seqno_t base, seqno_t m
for (; i < base + map->numbits; i++)
{
unsigned x = (unsigned) (i - base);
nn_bitset_set (map->numbits, map->bits, x);
nn_bitset_set (map->numbits, mapbits, x);
}
}
return map->numbits;

View file

@ -102,12 +102,12 @@ static void maybe_set_reader_in_sync (struct proxy_writer *pwr, struct pwr_rd_ma
}
}
static int valid_sequence_number_set (const nn_sequence_number_set_t *snset)
static int valid_sequence_number_set (const nn_sequence_number_set_header_t *snset)
{
return (fromSN (snset->bitmap_base) > 0 && snset->numbits <= 256);
}
static int valid_fragment_number_set (const nn_fragment_number_set_t *fnset)
static int valid_fragment_number_set (const nn_fragment_number_set_header_t *fnset)
{
return (fnset->bitmap_base > 0 && fnset->numbits <= 256);
}
@ -136,7 +136,7 @@ static int valid_AckNack (AckNack_t *msg, size_t size, int byteswap)
count = (nn_count_t *) ((char *) &msg->readerSNState + NN_SEQUENCE_NUMBER_SET_SIZE (msg->readerSNState.numbits));
if (byteswap)
{
bswap_sequence_number_set_bitmap (&msg->readerSNState);
bswap_sequence_number_set_bitmap (&msg->readerSNState, msg->bits);
*count = bswap4 (*count);
}
return 1;
@ -162,7 +162,7 @@ static int valid_Gap (Gap_t *msg, size_t size, int byteswap)
if (size < GAP_SIZE (msg->gapList.numbits))
return 0;
if (byteswap)
bswap_sequence_number_set_bitmap (&msg->gapList);
bswap_sequence_number_set_bitmap (&msg->gapList, msg->bits);
return 1;
}
@ -287,7 +287,7 @@ static int valid_NackFrag (NackFrag_t *msg, size_t size, int byteswap)
NN_FRAGMENT_NUMBER_SET_SIZE (msg->fragmentNumberState.numbits));
if (byteswap)
{
bswap_fragment_number_set_bitmap (&msg->fragmentNumberState);
bswap_fragment_number_set_bitmap (&msg->fragmentNumberState, msg->bits);
*count = bswap4 (*count);
}
return 1;
@ -542,7 +542,7 @@ static int add_Gap (struct nn_xmsg *msg, struct writer *wr, struct proxy_reader
gap->gapStart = toSN (start);
gap->gapList.bitmap_base = toSN (base);
gap->gapList.numbits = numbits;
memcpy (gap->gapList.bits, bits, NN_SEQUENCE_NUMBER_SET_BITS_SIZE (numbits));
memcpy (gap->bits, bits, NN_SEQUENCE_NUMBER_SET_BITS_SIZE (numbits));
nn_xmsg_submsg_setnext (msg, sm_marker);
return 0;
}
@ -590,12 +590,12 @@ static int acknack_is_nack (const AckNack_t *msg)
even we generate them) */
return 0;
for (i = 0; i < (int) NN_SEQUENCE_NUMBER_SET_BITS_SIZE (msg->readerSNState.numbits) / 4 - 1; i++)
x |= msg->readerSNState.bits[i];
x |= msg->bits[i];
if ((msg->readerSNState.numbits % 32) == 0)
mask = ~0u;
else
mask = ~(~0u >> (msg->readerSNState.numbits % 32));
x |= msg->readerSNState.bits[i] & mask;
x |= msg->bits[i] & mask;
return x != 0;
}
@ -660,7 +660,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
DDS_TRACE("ACKNACK(%s#%"PRId32":%"PRId64"/%"PRIu32":", msg->smhdr.flags & ACKNACK_FLAG_FINAL ? "F" : "",
*countp, fromSN (msg->readerSNState.bitmap_base), msg->readerSNState.numbits);
for (uint32_t i = 0; i < msg->readerSNState.numbits; i++)
DDS_TRACE("%c", nn_bitset_isset (msg->readerSNState.numbits, msg->readerSNState.bits, i) ? '1' : '0');
DDS_TRACE("%c", nn_bitset_isset (msg->readerSNState.numbits, msg->bits, i) ? '1' : '0');
seqbase = fromSN (msg->readerSNState.bitmap_base);
if (!rst->forme)
@ -863,7 +863,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
contained in the acknack, and assumes all messages beyond the
set are NACK'd -- don't feel like tracking where exactly we
left off ... */
if (i >= msg->readerSNState.numbits || nn_bitset_isset (numbits, msg->readerSNState.bits, i))
if (i >= msg->readerSNState.numbits || nn_bitset_isset (numbits, msg->bits, i))
{
seqno_t seq = seqbase + i;
struct whc_borrowed_sample sample;
@ -1352,11 +1352,12 @@ static int handle_HeartbeatFrag (struct receiver_state *rst, UNUSED_ARG(nn_etime
else
{
/* Check if we are missing something */
union {
struct nn_fragment_number_set set;
char pad[NN_FRAGMENT_NUMBER_SET_SIZE (256)];
DDSRT_STATIC_ASSERT ((NN_FRAGMENT_NUMBER_SET_MAX_BITS % 32) == 0);
struct {
struct nn_fragment_number_set_header set;
uint32_t bits[NN_FRAGMENT_NUMBER_SET_MAX_BITS / 32];
} nackfrag;
if (nn_defrag_nackmap (pwr->defrag, seq, fragnum, &nackfrag.set, 256) > 0)
if (nn_defrag_nackmap (pwr->defrag, seq, fragnum, &nackfrag.set, nackfrag.bits, NN_FRAGMENT_NUMBER_SET_MAX_BITS) > 0)
{
/* Yes we are (note that this potentially also happens for
samples we no longer care about) */
@ -1389,7 +1390,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N
DDS_TRACE("NACKFRAG(#%"PRId32":%"PRId64"/%u/%"PRIu32":", *countp, seq, msg->fragmentNumberState.bitmap_base, msg->fragmentNumberState.numbits);
for (uint32_t i = 0; i < msg->fragmentNumberState.numbits; i++)
DDS_TRACE("%c", nn_bitset_isset (msg->fragmentNumberState.numbits, msg->fragmentNumberState.bits, i) ? '1' : '0');
DDS_TRACE("%c", nn_bitset_isset (msg->fragmentNumberState.numbits, msg->bits, i) ? '1' : '0');
if (!rst->forme)
{
@ -1446,7 +1447,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N
DDS_TRACE(" scheduling requested frags ...\n");
for (uint32_t i = 0; i < msg->fragmentNumberState.numbits && enqueued; i++)
{
if (nn_bitset_isset (msg->fragmentNumberState.numbits, msg->fragmentNumberState.bits, i))
if (nn_bitset_isset (msg->fragmentNumberState.numbits, msg->bits, i))
{
struct nn_xmsg *reply;
if (create_fragment_message (wr, seq, sample.plist, sample.serdata, base + i, prd, &reply, 0) < 0)
@ -1642,7 +1643,7 @@ static int handle_Gap (struct receiver_state *rst, nn_etime_t tnow, struct nn_rm
1 bit, but check for it just in case, to reduce the number of
sequence number gaps to be processed. */
for (listidx = 0; listidx < msg->gapList.numbits; listidx++)
if (!nn_bitset_isset (msg->gapList.numbits, msg->gapList.bits, listidx))
if (!nn_bitset_isset (msg->gapList.numbits, msg->bits, listidx))
break;
last_included_rel = (int32_t) listidx - 1;
@ -1693,13 +1694,13 @@ static int handle_Gap (struct receiver_state *rst, nn_etime_t tnow, struct nn_rm
}
while (listidx < msg->gapList.numbits)
{
if (!nn_bitset_isset (msg->gapList.numbits, msg->gapList.bits, listidx))
if (!nn_bitset_isset (msg->gapList.numbits, msg->bits, listidx))
listidx++;
else
{
uint32_t j;
for (j = listidx + 1; j < msg->gapList.numbits; j++)
if (!nn_bitset_isset (msg->gapList.numbits, msg->gapList.bits, j))
if (!nn_bitset_isset (msg->gapList.numbits, msg->bits, j))
break;
/* spec says gapList (2) identifies an additional list of sequence numbers that
are invalid (8.3.7.4.2), so by that rule an insane start would simply mean the

View file

@ -698,9 +698,10 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
uint32_t i, numbits;
seqno_t base;
DDSRT_STATIC_ASSERT ((NN_FRAGMENT_NUMBER_SET_MAX_BITS % 32) == 0);
union {
struct nn_fragment_number_set set;
char pad[NN_FRAGMENT_NUMBER_SET_SIZE (256)];
struct nn_fragment_number_set_header set;
uint32_t bits[NN_FRAGMENT_NUMBER_SET_MAX_BITS / 32];
} nackfrag;
int nackfrag_numbits;
seqno_t nackfrag_seq = 0;
@ -735,7 +736,7 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
/* Make bitmap; note that we've made sure to have room for the
maximum bitmap size. */
numbits = nn_reorder_nackmap (reorder, bitmap_base, pwr->last_seq, &an->readerSNState, max_numbits, notail);
numbits = nn_reorder_nackmap (reorder, bitmap_base, pwr->last_seq, &an->readerSNState, an->bits, max_numbits, notail);
base = fromSN (an->readerSNState.bitmap_base);
/* Scan through bitmap, cutting it off at the first missing sample
@ -746,13 +747,13 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
{
uint32_t fragnum;
nackfrag_seq = base + i;
if (!nn_bitset_isset (numbits, an->readerSNState.bits, i))
if (!nn_bitset_isset (numbits, an->bits, i))
continue;
if (nackfrag_seq == pwr->last_seq)
fragnum = pwr->last_fragnum;
else
fragnum = UINT32_MAX;
nackfrag_numbits = nn_defrag_nackmap (pwr->defrag, nackfrag_seq, fragnum, &nackfrag.set, max_numbits);
nackfrag_numbits = nn_defrag_nackmap (pwr->defrag, nackfrag_seq, fragnum, &nackfrag.set, nackfrag.bits, max_numbits);
}
if (nackfrag_numbits >= 0) {
/* Cut the NACK short, NACKFRAG will be added after the NACK's is
@ -800,7 +801,7 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
PGUID (rwn->rd_guid), PGUID (pwr->e.guid), rwn->count,
base, an->readerSNState.numbits);
for (uint32_t ui = 0; ui != an->readerSNState.numbits; ui++)
DDS_TRACE("%c", nn_bitset_isset (numbits, an->readerSNState.bits, ui) ? '1' : '0');
DDS_TRACE("%c", nn_bitset_isset (numbits, an->bits, ui) ? '1' : '0');
}
if (nackfrag_numbits > 0)
@ -819,7 +820,7 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
nf->writerSN = toSN (nackfrag_seq);
nf->fragmentNumberState.bitmap_base = nackfrag.set.bitmap_base + 1;
nf->fragmentNumberState.numbits = nackfrag.set.numbits;
memcpy (nf->fragmentNumberState.bits, nackfrag.set.bits, NN_FRAGMENT_NUMBER_SET_BITS_SIZE (nackfrag_numbits));
memcpy (nf->bits, nackfrag.bits, NN_FRAGMENT_NUMBER_SET_BITS_SIZE (nackfrag_numbits));
{
nn_count_t *countp =
@ -829,7 +830,7 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
DDS_TRACE(" + nackfrag #%"PRId32":%"PRId64"/%u/%"PRIu32":", *countp, fromSN (nf->writerSN), nf->fragmentNumberState.bitmap_base, nf->fragmentNumberState.numbits);
for (uint32_t ui = 0; ui != nf->fragmentNumberState.numbits; ui++)
DDS_TRACE("%c", nn_bitset_isset (nf->fragmentNumberState.numbits, nf->fragmentNumberState.bits, ui) ? '1' : '0');
DDS_TRACE("%c", nn_bitset_isset (nf->fragmentNumberState.numbits, nf->bits, ui) ? '1' : '0');
}
}