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;
|
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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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) \
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user