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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user