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; return 0;
} }
static long
get_id(struct prv *prv, long type, long row)
{
return type * prv->nrows + row;
}
static struct prv_chan * 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; struct prv_chan *rchan = NULL;
HASH_FIND_STR(prv->channels, name, rchan); HASH_FIND_LONG(prv->channels, &id, rchan);
return rchan; return rchan;
} }
@ -145,10 +151,11 @@ cb_prv(struct chan *chan, void *ptr)
int int
prv_register(struct prv *prv, long row, long type, struct bay *bay, struct chan *chan, long flags) 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 */ long id = get_id(prv, type, row);
struct prv_chan *rchan = find_prv_chan(prv, chan->name); struct prv_chan *rchan = find_prv_chan(prv, id);
if (rchan != NULL) { 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; return -1;
} }
@ -158,6 +165,7 @@ prv_register(struct prv *prv, long row, long type, struct bay *bay, struct chan
return -1; return -1;
} }
rchan->id = id;
rchan->chan = chan; rchan->chan = chan;
rchan->row_base1 = row + 1; rchan->row_base1 = row + 1;
rchan->type = type; 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 */ /* Add to hash table */
HASH_ADD_STR(prv->channels, chan->name, rchan); HASH_ADD_LONG(prv->channels, id, rchan);
return 0; return 0;
} }

View File

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

View File

@ -510,6 +510,12 @@ typedef unsigned char uint8_t;
HASH_ADD(hh, head, intfield, sizeof(int), add) HASH_ADD(hh, head, intfield, sizeof(int), add)
#define HASH_REPLACE_INT(head, intfield, add, replaced) \ #define HASH_REPLACE_INT(head, intfield, add, replaced) \
HASH_REPLACE(hh, head, intfield, sizeof(int), 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) \ #define HASH_FIND_PTR(head, findptr, out) \
HASH_FIND(hh, head, findptr, sizeof(void *), out) HASH_FIND(hh, head, findptr, sizeof(void *), out)
#define HASH_ADD_PTR(head, ptrfield, add) \ #define HASH_ADD_PTR(head, ptrfield, add) \

View File

@ -1,5 +1,7 @@
#define _GNU_SOURCE #define _GNU_SOURCE
#include "unittest.h"
#include "emu/pv/prv.h" #include "emu/pv/prv.h"
#include "common.h" #include "common.h"
@ -108,6 +110,32 @@ test_duplicate(const char *path)
err("test duplicate OK\n"); 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) int main(void)
{ {
/* Create temporary trace file */ /* Create temporary trace file */
@ -118,6 +146,7 @@ int main(void)
test_emit(fname); test_emit(fname);
test_duplicate(fname); test_duplicate(fname);
test_same_type(fname);
close(fd); close(fd);