Fix UBSAN error

Since QuorumCallback<T> is a non trivial type, we need to construct it
before we interact with it

This change fixes the following UBSAN message
/Users/anoyes/workspace/foundationdb/flow/genericactors.actor.h:930:18: runtime error: member access within address 0x0001243f63d0 which does not point to an object of type 'Callback<Standalone<StringRef> >'
0x0001243f63d0: note: object has invalid vptr
This commit is contained in:
Andrew Noyes 2019-11-27 13:13:46 -08:00
parent 70dcbeb204
commit 8fc74e3182
1 changed files with 7 additions and 8 deletions

View File

@ -897,11 +897,6 @@ struct Quorum : SAV<Void> {
template <class T>
class QuorumCallback : public Callback<T> {
public:
QuorumCallback(Future<T> future, Quorum<T>* head)
: head(head)
{
future.addCallbackAndClear(this);
}
virtual void fire(const T& value) {
Callback<T>::remove();
Callback<T>::next = 0;
@ -914,7 +909,11 @@ public:
}
private:
template <class U>
friend Future<Void> quorum(std::vector<Future<U>> const& results, int n);
Quorum<T>* head;
QuorumCallback() = default;
QuorumCallback(Future<T> future, Quorum<T>* head) : head(head) { future.addCallbackAndClear(this); }
};
template <class T>
@ -925,15 +924,15 @@ Future<Void> quorum(std::vector<Future<T>> const& results, int n) {
Quorum<T>* q = new (allocateFast(size)) Quorum<T>(n, results.size());
QuorumCallback<T>* nextCallback = q->callbacks();
for (auto & r : results) {
for (auto& r : results) {
if (r.isReady()) {
new (nextCallback) QuorumCallback<T>();
nextCallback->next = 0;
if (r.isError())
q->oneError(r.getError());
else
q->oneSuccess();
}
else
} else
new (nextCallback) QuorumCallback<T>(r, q);
++nextCallback;
}