Use row and type as identifiers in prv_register()

Prevents multiple channels from being accidentally set to the same row
with the same type.
This commit is contained in:
Rodrigo Arias 2023-02-20 15:34:27 +01:00 committed by Rodrigo Arias Mallo
parent 1c90947f82
commit b98ccfe3ad
4 changed files with 50 additions and 6 deletions

View File

@ -52,11 +52,17 @@ prv_close(struct prv *prv)
return 0;
}
static long
get_id(struct prv *prv, long type, long row)
{
return type * prv->nrows + row;
}
static struct prv_chan *
find_prv_chan(struct prv *prv, const char *name)
find_prv_chan(struct prv *prv, long id)
{
struct prv_chan *rchan = NULL;
HASH_FIND_STR(prv->channels, name, rchan);
HASH_FIND_LONG(prv->channels, &id, rchan);
return rchan;
}
@ -145,10 +151,11 @@ cb_prv(struct chan *chan, void *ptr)
int
prv_register(struct prv *prv, long row, long type, struct bay *bay, struct chan *chan, long flags)
{
/* FIXME: use the type instead of channel name as key */
struct prv_chan *rchan = find_prv_chan(prv, chan->name);
long id = get_id(prv, type, row);
struct prv_chan *rchan = find_prv_chan(prv, id);
if (rchan != NULL) {
err("channel %s already registered", chan->name);
err("row=%ld type=%ld has channel '%s' registered",
row, type, chan->name);
return -1;
}
@ -158,6 +165,7 @@ prv_register(struct prv *prv, long row, long type, struct bay *bay, struct chan
return -1;
}
rchan->id = id;
rchan->chan = chan;
rchan->row_base1 = row + 1;
rchan->type = type;
@ -173,7 +181,7 @@ prv_register(struct prv *prv, long row, long type, struct bay *bay, struct chan
}
/* Add to hash table */
HASH_ADD_STR(prv->channels, chan->name, rchan);
HASH_ADD_LONG(prv->channels, id, rchan);
return 0;
}

View File

@ -18,6 +18,7 @@ enum prv_flags {
struct prv_chan {
struct prv *prv;
struct chan *chan;
long id;
long row_base1;
long type;
long flags;

View File

@ -510,6 +510,12 @@ typedef unsigned char uint8_t;
HASH_ADD(hh, head, intfield, sizeof(int), add)
#define HASH_REPLACE_INT(head, intfield, add, replaced) \
HASH_REPLACE(hh, head, intfield, sizeof(int), add, replaced)
#define HASH_FIND_LONG(head, findlong, out) \
HASH_FIND(hh, head, findlong, sizeof(long), out)
#define HASH_ADD_LONG(head, longfield, add) \
HASH_ADD(hh, head, longfield, sizeof(long), add)
#define HASH_REPLACE_LONG(head, longfield, add, replaced) \
HASH_REPLACE(hh, head, longfield, sizeof(long), add, replaced)
#define HASH_FIND_PTR(head, findptr, out) \
HASH_FIND(hh, head, findptr, sizeof(void *), out)
#define HASH_ADD_PTR(head, ptrfield, add) \

View File

@ -1,5 +1,7 @@
#define _GNU_SOURCE
#include "unittest.h"
#include "emu/pv/prv.h"
#include "common.h"
@ -108,6 +110,32 @@ test_duplicate(const char *path)
err("test duplicate OK\n");
}
/* Detect same types being registered to the same row */
static void
test_same_type(const char *path)
{
long type = 100;
long row = 0;
struct bay bay;
bay_init(&bay);
struct prv prv;
prv_open(&prv, NROWS, path);
struct chan chan;
chan_init(&chan, CHAN_SINGLE, "testchan");
/* Allow setting the same value in the channel */
chan_prop_set(&chan, CHAN_DUPLICATES, 1);
OK(bay_register(&bay, &chan));
OK(prv_register(&prv, row, type, &bay, &chan, 0));
ERR(prv_register(&prv, row, type, &bay, &chan, 0));
err("ok");
}
int main(void)
{
/* Create temporary trace file */
@ -118,6 +146,7 @@ int main(void)
test_emit(fname);
test_duplicate(fname);
test_same_type(fname);
close(fd);