The problem:
So I'm pretty new to CPP and i was trying to implement a simple comparison code using some atomicity concepts.
The problem is that I'm not getting a desired result, that is: even after the compare_exchange_strong function updates the value of the atomic variable (std::atomic
), it returns false.
Below is the program code:
CPP:
Action::Action(Type type, Transfer *transfer)
: transfer(transfer),
type(type) {
Internal = 0;
InternalHigh = -1;
Offset = OffsetHigh = 0;
hEvent = NULL;
status = Action::Status::PENDING;
}
BOOL CancelTimeout(OnTimeoutCallback* rt)
{
auto expected = App::Action::Status::PENDING;
if (rt->action->status.compare_exchange_strong(expected, App::Action::Status::CANCEL))
{
CancelWaitableTimer(rt->hTimer);
return true;
}
return false;
}
HEADER:
struct Action : OVERLAPPED {
enum class Type : long {
SEND,
RECEIVE
};
enum class Status : long {
PENDING,
CANCEL,
TIMEOUT
};
atomic<Status> status;
Transfer *transfer = NULL;
Type type;
WSABUF *data = NULL;
OnTimeoutCallback *timeoutCallback;
Action(Type type, Transfer *transfer);
~Action();
}
Reviewing, the value of the variable rt->action->status
is updated to the Action::Status::CANCEL
enum, but the return of the compare_exchange_strong function is false.
See the problem in debug:
That said, the desired result is that the first breakpoint, referring to return true, would be triggered instead of return false, taking into account that it changed the value of the variable.
UPDATE: In the print I removed the first Breakpoint by accident, but I think it was understandable
Attempts already made
- Modify the structure to:
enum class Status : long
- Modify the structure to:
enum class Status : size_t
- Modify the positions of all structure items
Similar topics already searched
[but without success]
Link | Search term |
---|---|
Why does compare_exchange_strong fail with std::atomic<double>, std::atomic<float> in C++? | compare_exchange_strong fail |
cpp compare_exchange_strong fails spuriously? | compare exchange fails |
Don't really get the logic of std::atomic::compare_exchange_weak and compare_exchange_strong | std::atomic::compare_exchange_weak and compare_exchange_strong |
Does C++14 define the behavior of bitwise operators on the padding bits of unsigned int? | Padding problem compare exchange |
Among several other topics with different search words
Importante Notes
- The code is multi-threaded
- There is nowhere else in the code where the value of the atomic
variable is being updated to the enum
Action::Status::CANCEL
- I suspect it's something to do with padding (due to some Google searches), but as I'm new to CPP, I don't know how to modify my framework to solve the problem
- A new instance of the Action structure is generated at each request, and I also made sure that there is no concurrency occurring on the same pointer (Action*), because with each change, a new instance of the Action structure is generated
WAIT!
It is worth mentioning that I am using Google Translate to post this question, in case something is not right, if my question is incomplete, or is formatted in an inappropriate way, please comment so I can adjust it, thank you in advance,
Lucas P.
Updates:
I was not able to replicate the problem using a minified version of the code, that being said, I have to post the entire solution (which in turn is already quite small, as it is a project for studies):
https://drive.google.com/file/d/13fP7OUCC6GeMgUtrPHSOnSGUEBwDGqBC/view?usp=sharing