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:
Kostas Kyrimis 2024-07-19 10:03:17 +03:00 committed by GitHub
parent cad62679a4
commit 8a2d6ad1f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 45 additions and 4 deletions

View file

@ -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;