New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sys/tsrb: bug fix for tsrb_get_one() #11624
Conversation
@@ -32,7 +32,7 @@ static char _pop(tsrb_t *rb) | |||
int tsrb_get_one(tsrb_t *rb) | |||
{ | |||
if (!tsrb_empty(rb)) { | |||
return _pop(rb); | |||
return (unsigned char)_pop(rb); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me the problem lies in mixing error return codes with values. A better solution would be to change the signature of the function into: int tsrb_get_one(tsrb_t *rb, char *dst)
. Also the same problem is otherwise with tsrb_get()
below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree with changing the signature of the API-facing tsrb_get_one()
/ tsrb_get()
. Rather, _pop()
's return value should just be cast to unsigned char
. Since sizeof(unsigned char) < sizeof(int)
on all of our platforms, this is acceptable and does not mix error return codes with values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this still looks wrong to me bc it uses char
not unsigned char
when adding stuff also the buffer is char
. It just does not look really (type) safe to me - I would use uint8_t
to make it explicit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO casting to unsigned char is the best option here. It is what getchar is doing, so can be called ideomatic C.
Also we might get away with calling this a bugfix, as the documentation clearly states that it returns the byte as >= 0
. Now that I think of it, the cast must have been my initial intention anyways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this still looks wrong to me bc it uses
char
notunsigned char
when adding stuff also the buffer ischar
. It just does not look really (type) safe to me - I would useuint8_t
to make it explicit.
In my opinion, we should focus on fixing the bug first, than we can discuss API changes for type safeness. The bug is fixable without an API change, so we should do that first, then do an API change if necessary. This not only makes the merge of this bug fix faster, but also allows for a better understanding of the thought process of the API change when looking at the code's history.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@smlng are you fine with this fix for now, and we revisit the API later?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, but it should not be that much later.
Another idea for a fix:
Documentation states, that this assumes a single producer and consumer scenario, right? So actually there is no need to return -1
on error but rather change the function to char tsrb_get_one()
and the consumer MUST call tsrb_empty
before access on its own otherwise the consumer might get an old/invalid value. This works because there is only one consumer hence there can be no other consumer manipulating the reads
.
Still it might be sensible to change every char
to unsigned char
anyway.
(reminder to self: there should be a unittest for |
Did it in #11632. |
This problem also popped up in #9869. |
The problem now is, that it might fix for |
I guess long-term we need to do an API change, but I'd vote rather for going from |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK for this change however, though the values are not comparable directly now, it fixes that a valid output (\xff
) is interpreted as an error.
Contribution description
Fixes bug for getting 0xFF byte from ring buffer.
When we want to get such byte as char (signed type), it returns -1 (means buffer is empty).
Testing procedure
Put 0xFF byte to buffer and try to get it with tsrb_get_one()