mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2025-05-11 10:25:47 +02:00
fix: ub in RegisterOnChange and regression tests for big values (#3336)
* fix replication test flag name for big values * fix a bug that triggers ub when RegisterOnChange is called on flows that iterate over the callbacks and preempt * add a stress test for big value serialization Signed-off-by: kostas <kostas@dragonflydb.io>
This commit is contained in:
parent
cad62679a4
commit
8a2d6ad1f4
3 changed files with 45 additions and 4 deletions
|
@ -13,6 +13,7 @@
|
|||
#include "server/conn_context.h"
|
||||
#include "server/table.h"
|
||||
#include "util/fibers/fibers.h"
|
||||
#include "util/fibers/synchronization.h"
|
||||
|
||||
namespace dfly {
|
||||
|
||||
|
@ -524,6 +525,36 @@ class DbSlice {
|
|||
void CallChangeCallbacks(DbIndex id, const ChangeReq& cr) const;
|
||||
|
||||
private:
|
||||
class LocalBlockingCounter {
|
||||
public:
|
||||
void lock() {
|
||||
++mutating;
|
||||
}
|
||||
|
||||
void unlock() {
|
||||
--mutating;
|
||||
if (mutating == 0) {
|
||||
cond_var.notify_one();
|
||||
}
|
||||
}
|
||||
|
||||
void Wait() {
|
||||
util::fb2::NoOpLock noop_lk_;
|
||||
cond_var.wait(noop_lk_, [this]() { return mutating == 0; });
|
||||
}
|
||||
|
||||
private:
|
||||
util::fb2::CondVarAny cond_var;
|
||||
size_t mutating = 0;
|
||||
};
|
||||
|
||||
// We need this because registered callbacks might yield. If RegisterOnChange
|
||||
// gets called after we preempt while iterating over the registered callbacks
|
||||
// (let's say in FlushChangeToEarlierCallbacks) we will get UB, because we pushed
|
||||
// into a vector which might get resized, invalidating the iterators that are being
|
||||
// used by the preempted FlushChangeToEarlierCallbacks. LocalBlockingCounter
|
||||
// protects us against this case.
|
||||
mutable LocalBlockingCounter block_counter_;
|
||||
ShardId shard_id_;
|
||||
uint8_t caching_mode_ : 1;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue