-
Notifications
You must be signed in to change notification settings - Fork 196
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
chore(state-machine): Panic in the case of non-handled non-deferred e… #1464
base: feature-c++-client
Are you sure you want to change the base?
chore(state-machine): Panic in the case of non-handled non-deferred e… #1464
Conversation
@oleorhagen, Let me know if you want to start the integration pipeline by mentioning me and the command "start pipeline". my commands and optionsYou can trigger a pipeline on multiple prs with: - mentioning me and `start pipeline --pr mender/127 --pr mender-connect/255` You can start a fast pipeline, disabling full integration tests with:
You can trigger GitHub->GitLab branch sync with:
You can cherry pick to a given branch or branches with:
|
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.
Good safeguard!
|
||
// Check if there are any non-deferred events in the queue - then fail if | ||
queue<EventType> queue_copy = event_queue_; | ||
while (not queue_copy.empty()) { |
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.
It's expected to have non-deferred events here, because this is after the handlers have run. I think the check needs to be between the if (!to_run.empty()) {
block and the one above it.
There is also a much easier way to check this. When we are doing event_queue_.push(event)
above, also increment a deferred_count
counter. If deferred_count < event_queue_.size()
, then the check is positive.
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.
Oh! Very good idea!
I had a suspicion you would come up with something smarter than me here 😆
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.
Alright, new try. I am still using my original approach, but moved it to before we run the machine loop.
Ur approach, although clever, did not work when initializing (since we add the start events to the to_run queue, and I didn't feel like special casing it.
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 can be easily fixed too. Just keep a counter for the run_queue
as well, but don't increment it during the initialization step, only when adding events in the "normal" flow. Then the check becomes deferred_count < added_to_run_queue
. I think it's better than copying the whole queue on every state transition.
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.
True, I did dabble with the idea. But decided it's not really better. This implementation reads pretty straight forward, and does not have to touch the other pieces of code, and handle special cases.
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.
Copying the queue should just be a couple of elements
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.
Ok then, I'll let it go! 🙂
8966992
to
5f8c974
Compare
DBusError dbus_error; | ||
dbus_error_init(&dbus_error); | ||
dbus_conn_.reset(dbus_bus_get_private(DBUS_BUS_SYSTEM, &dbus_error)); | ||
std::unique_ptr<DBusError, void (*)(DBusError *)> dbus_error {new DBusError, dbus_error_free}; |
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 support the incentive, but I suspect you have in fact have introduced a memory leak here. There are two levels of resources here, the DBusError
struct itself, and the content it contains. dbus_error_free
only frees the latter.
I can see two ways to solve it:
- Use a lambda with both
dbus_error_free
anddelete dbus_error
in it. - Don't use
new DBusError
, but keep the variable on the stack instead, as before, and use&dbus_error
as the argument when constructing the smart pointer (with a different name), together withdbus_error_free
. Theunique_ptr
now doesn't own the pointer itself, but it owns the contents.
Same for the other commit.
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.
Oh shite. True. Rookie mistake!
|
||
// Check if there are any non-deferred events in the queue - then fail if | ||
queue<EventType> queue_copy = event_queue_; | ||
while (not queue_copy.empty()) { |
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 can be easily fixed too. Just keep a counter for the run_queue
as well, but don't increment it during the initialization step, only when adding events in the "normal" flow. Then the check becomes deferred_count < added_to_run_queue
. I think it's better than copying the whole queue on every state transition.
Just makes it more future proof, as we don't have to remember free it in our exit paths anylonger. Signed-off-by: Ole Petter <[email protected]>
This just makes this consistent with the rest of our codebase. Signed-off-by: Ole Petter <[email protected]>
Signed-off-by: Ole Petter <[email protected]>
Simply split out and name the logical parts. Signed-off-by: Ole Petter <[email protected]>
…vents This adds a sanity check to verify that there are no non-deferred events left in the event queue after the run_queue has been populated. If there was, then we would have undefined behaviour in the state-machine, and as such the best thing we can do in this instance is to panic. This is a serious logic error in our code, and as such such cause a hard-fault. Signed-off-by: Ole Petter <[email protected]>
5f8c974
to
9cad8e7
Compare
+ dbus_error.name + "]"); | ||
dbus_error_free(&dbus_error); | ||
string("Failed to get connection to system bus: ") + dbus_error.get()->message + "[" | ||
+ dbus_error.get()->name + "]"); |
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.
.get()
should only be used when it's required to, here it can be omitted.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
No description provided.