-
Notifications
You must be signed in to change notification settings - Fork 3.8k
callback support for checktime timer expiry #7803
Changes from 1 commit
357e30c
c072a01
f959c5a
c79c769
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,8 @@ | |
#include <fc/time.hpp> | ||
#include <fc/fwd.hpp> | ||
|
||
#include <eosio/chain/exceptions.hpp> | ||
|
||
#include <signal.h> | ||
|
||
namespace eosio { namespace chain { | ||
|
@@ -13,12 +15,29 @@ struct platform_timer { | |
void start(fc::time_point tp); | ||
void stop(); | ||
|
||
/* Sets a callback for when timer expires. Be aware this could might fire from a signal handling context and/or | ||
on any particular thread. Only a single callback can be registered at once; trying to register more will | ||
result in an exception. Setting to nullptr is allowed as a "no callback" hint */ | ||
void set_expiry_callback(void(*func)(void*), void* user) { | ||
EOS_ASSERT(!(func && _expiration_callback), misc_exception, "Setting a platform_timer callback when one already exists"); | ||
_expiration_callback = func; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm worried that there is more than just the one "Race" that you mentioned in the PR here. Given
I think I understand in that in the current use case where T2 is practically going to be nullptr that boils down to: so, 2 out of 6 of those are crashes, 1 out of 6 calls We can improve this dramatically if we can guarantee that the pair is atomically set and queried. Does the signal handling context allow us to use atomic primitives like CAS? Or can we double buffer the function+data pair with some sort of data barrier and then "swap" the active buffer with a single index update? |
||
_expiration_callback_data = user; | ||
} | ||
|
||
volatile sig_atomic_t expired = 1; | ||
|
||
private: | ||
struct impl; | ||
constexpr static size_t fwd_size = 8; | ||
fc::fwd<impl,fwd_size> my; | ||
|
||
void call_expiration_callback() { | ||
if(_expiration_callback) | ||
_expiration_callback(_expiration_callback_data); | ||
} | ||
|
||
void(*_expiration_callback)(void*) = nullptr; | ||
void* _expiration_callback_data; | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see a "carries a dependency" relationship here between This https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html indicates There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://en.cppreference.com/w/cpp/atomic/memory_order
|
||
|
||
}} |
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 remain consistent with the name of the member variable and the
call_expiration_callback
method this should probably be renamed toset_expiration_callback