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:
parent
1c90947f82
commit
b98ccfe3ad
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) \
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user