Skip to content

Commit 3f38bbc

Browse files
committed
Build-To-Use: 4.2.0-7
CBL-8578: Fixed dumb bug in RingBuffer causing BT TLS streams to fail. (#2516) CBL-8580: Use AtomicRetained in Replicator::Subreplicators (#2517) CBL-8516: Add a timeout to C4WebSocket::waitForTLSHandshake() (#2514) EE: CBL-8516: Don't let MeshManager hang waiting for TLS handshake (#147) (#156) CBL-8512: Re-add a suspended Bonjour peer if it's rediscovered (#154) CBL-8510: Fix connect timeout check in LiteCoreBTCentral (#153) CBL-8514: Improved TLSCodec error handling (#145) (#155)
2 parents 24f6385 + 15fdef8 commit 3f38bbc

9 files changed

Lines changed: 59 additions & 35 deletions

File tree

.github/workflows/warn_release.yml

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
on:
22
workflow_call: # So it can be used by our other repos
3-
pull_request: # And also be used for itself
4-
branches: ['release/**']
5-
workflow_dispatch: # manual trigger via GitHub UI
3+
pull_request: # And also be used for itself
4+
types: [opened]
5+
branches: ["release/**"]
6+
paths:
7+
- "C/**"
8+
- "Crypto/**"
9+
- "LiteCore/**"
10+
- "MSVC/**"
11+
- "Networking/**"
12+
- "Replicator/**"
13+
- "REST/**"
14+
- "vendor/fleece"
15+
16+
workflow_dispatch: # manual trigger via GitHub UI
617

718
jobs:
819
warn-release:
@@ -23,6 +34,7 @@ jobs:
2334
2435
- [ ] A response to a customer ask
2536
- [ ] A change per our security policy
26-
- [ ] A non-functional change (i.e. changes needed for building an older version)
37+
- [ ] A non-functional change (e.g. changes needed for building an older version)
38+
- [ ] A bug fix for a x.y.0 release
2739
- [ ] A change that has been granted an exception (please comment)`
2840
})

LiteCore/Support/RingBuffer.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ namespace litecore {
5858
if ( end >= _capacity ) end -= _capacity;
5959
size_t n1 = std::min(n, _capacity - end);
6060
::memcpy(&_buffer[end], data.buf, n1);
61-
if ( n1 > n ) ::memcpy(&_buffer[0], &data[n1], n - n1);
61+
if ( n1 < n ) ::memcpy(&_buffer[0], &data[n1], n - n1);
6262
_size += n;
6363
return n;
6464
}

LiteCore/tests/N1QLParserTest.cc

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -600,16 +600,20 @@ TEST_CASE_METHOD(N1QLParserTest, "N1QL Performance", "[Query][N1QL][C]") {
600600

601601
SECTION("Very Long Query") {
602602
// 3b1fe0d6fe46a5a4e1655dbe6f42e89154a189dd, this query takes 4 seconds
603-
n1ql = "SELECT doc.* FROM _ doc WHERE "
604-
"doc.type = 'Model' AND "
605-
"doc.s NOT IN ('A', 'B', 'V') AND "
606-
"((doc.model.total.totalA "
607-
"- ifnull(doc.model.totalA.totalB, 0)) "
608-
"> 0 OR doc.t = false) AND "
609-
"(doc.q IS NULL OR "
610-
"ifnull(doc.q.e, 'e') = 'e' AND "
611-
"ifnull(doc.q.m, 0) == 0)";
603+
n1ql = "SELECT doc.* FROM _ doc WHERE "
604+
"doc.type = 'Model' AND "
605+
"doc.s NOT IN ('A', 'B', 'V') AND "
606+
"((doc.model.total.totalA "
607+
"- ifnull(doc.model.totalA.totalB, 0)) "
608+
"> 0 OR doc.t = false) AND "
609+
"(doc.q IS NULL OR "
610+
"ifnull(doc.q.e, 'e') = 'e' AND "
611+
"ifnull(doc.q.m, 0) == 0)";
612+
#ifdef _MSC_VER
613+
checkBound = 10.0;
614+
#else
612615
checkBound = 1.0;
616+
#endif
613617
}
614618

615619
Stopwatch sw;

Networking/WebSockets/c4WebSocket.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,10 @@ namespace litecore::repl {
134134
catchAndWarn() return false;
135135
}
136136

137-
bool C4WebSocket::waitForTLSHandshake() {
137+
bool C4WebSocket::waitForTLSHandshake(unsigned timeoutSecs) {
138138
unique_lock lock(_mutex);
139-
_tlsHandshakeCondition.wait(lock, [this] { return _peerCertData != nullslice || _closed; });
139+
_tlsHandshakeCondition.wait_for(lock, chrono::seconds(timeoutSecs),
140+
[this] { return _peerCertData != nullslice || _closed; });
140141
return _peerCertData != nullslice && !_closed;
141142
}
142143

Networking/WebSockets/c4WebSocket.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ namespace litecore::repl {
4747
void closeWithException();
4848

4949
/** Blocks until the TLS handshake completes or the socket closes. Returns true on success. */
50-
[[nodiscard]] bool waitForTLSHandshake();
50+
[[nodiscard]] bool waitForTLSHandshake(unsigned timeoutSecs);
5151

5252
// WebSocket public API:
5353
void connect() override;

Replicator/Replicator.cc

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,13 @@ namespace litecore::repl {
252252

253253
// Called after the checkpoint is established.
254254
void Replicator::startReplicating(CollectionIndex coll) {
255-
if ( _options->push(coll) > kC4Passive ) _subRepls[coll].pusher->start();
256-
if ( _options->pull(coll) > kC4Passive )
257-
_subRepls[coll].puller->start(_subRepls[coll].checkpointer->remoteMinSequence());
255+
if ( _options->push(coll) > kC4Passive ) {
256+
if ( auto pusher = _subRepls[coll].pusher.get() ) pusher->start();
257+
}
258+
if ( _options->pull(coll) > kC4Passive ) {
259+
if ( auto puller = _subRepls[coll].puller.get() )
260+
puller->start(_subRepls[coll].checkpointer->remoteMinSequence());
261+
}
258262
}
259263

260264
pair<int, websocket::Headers> Replicator::httpResponse() const {
@@ -379,9 +383,9 @@ namespace litecore::repl {
379383

380384
CollectionIndex coll = task->collectionIndex();
381385
if ( coll != kNotCollectionIndex ) {
382-
if ( task == _subRepls[coll].pusher ) {
386+
if ( auto pusher = _subRepls[coll].pusher.get(); pusher == task ) {
383387
updatePushStatus(coll, taskStatus);
384-
} else if ( task == _subRepls[coll].puller ) {
388+
} else if ( auto puller = _subRepls[coll].puller.get(); puller == task ) {
385389
updatePullStatus(coll, taskStatus);
386390
}
387391
}
@@ -656,8 +660,8 @@ namespace litecore::repl {
656660
// Clear connection() and notify the other agents to do the same:
657661
_connectionClosed();
658662
for ( auto& sub : _subRepls ) {
659-
if ( sub.pusher ) sub.pusher->connectionClosed();
660-
if ( sub.puller ) sub.puller->connectionClosed();
663+
if ( auto pusher = sub.pusher.get() ) pusher->connectionClosed();
664+
if ( auto puller = sub.puller.get() ) puller->connectionClosed();
661665
}
662666

663667
if ( status.isNormal() && closedByPeer && _options->isActive() ) {
@@ -718,9 +722,10 @@ namespace litecore::repl {
718722
cLogInfo(coll, "No local checkpoint '%.*s'", SPLAT(sub.checkpointer->initialCheckpointID()));
719723
// If pulling into an empty db with no checkpoint, it's safe to skip deleted
720724
// revisions as an optimization.
721-
if ( _options->pull(coll) > kC4Passive && sub.puller
725+
if ( auto puller = sub.puller.get();
726+
puller && _options->pull(coll) > kC4Passive
722727
&& _db->useCollection(sub.collectionSpec)->getLastSequence() == 0_seq )
723-
sub.puller->setSkipDeleted();
728+
puller->setSkipDeleted();
724729
}
725730
return true;
726731
} catch ( ... ) {
@@ -767,8 +772,9 @@ namespace litecore::repl {
767772

768773
if ( !refresh && sub.hadLocalCheckpoint ) {
769774
// Compare checkpoints, reset if mismatched:
770-
bool valid = sub.checkpointer->validateWith(remoteCheckpoint);
771-
if ( !valid && sub.pusher ) sub.pusher->checkpointIsInvalid();
775+
if ( !sub.checkpointer->validateWith(remoteCheckpoint) ) {
776+
if ( auto pusher = sub.pusher.get() ) pusher->checkpointIsInvalid();
777+
}
772778

773779
if ( !refresh ) {
774780
// Now we have the checkpoints! Time to start replicating:
@@ -898,8 +904,9 @@ namespace litecore::repl {
898904

899905
if ( _subRepls[i].hadLocalCheckpoint ) {
900906
// Compare checkpoints, reset if mismatched:
901-
bool valid = _subRepls[i].checkpointer->validateWith(remoteCheckpoints[i]);
902-
if ( !valid && _subRepls[i].pusher ) _subRepls[i].pusher->checkpointIsInvalid();
907+
if ( !_subRepls[i].checkpointer->validateWith(remoteCheckpoints[i]) ) {
908+
if ( auto pusher = _subRepls[i].pusher.get() ) pusher->checkpointIsInvalid();
909+
}
903910
}
904911
// Now we have the checkpoints! Time to start replicating:
905912
startReplicating(i);

Replicator/Replicator.hh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111
//
1212

1313
#pragma once
14+
#include "AtomicRetained.hh"
1415
#include "Worker.hh"
1516
#include "Checkpointer.hh"
1617
#include "BLIPConnection.hh"
1718
#include "Batcher.hh"
1819
#include "Stopwatch.hh"
1920
#include "c4DatabaseTypes.h"
2021
#include <access_lock.hh>
21-
#include <array>
2222
#include <optional>
2323
#include <utility>
2424

@@ -232,8 +232,8 @@ namespace litecore::repl {
232232
// Member variables:
233233

234234
struct SubReplicator {
235-
Retained<Pusher> pusher;
236-
Retained<Puller> puller;
235+
AtomicRetained<Pusher> pusher;
236+
AtomicRetained<Puller> puller;
237237
Status pushStatus; // Current status of Pusher
238238
Status pullStatus; // Current status of Puller
239239
unique_ptr<Checkpointer> checkpointer; // Object that manages checkpoints

licenses/BSL-Couchbase.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ COUCHBASE BUSINESS SOURCE LICENSE AGREEMENT
22

33
Business Source License 1.1
44
Licensor: Couchbase, Inc.
5-
Licensed Work: Couchbase Lite Version 4.1
5+
Licensed Work: Couchbase Lite Version 4.2
66
The Licensed Work is © 2021-Present Couchbase, Inc.
77

88
Additional Use Grant: You may make production use of the Licensed Work, provided

0 commit comments

Comments
 (0)