Skip to content

Commit de2a941

Browse files
committed
libstore: fix data race in getFileTransfer() singleton replacement
Multiple threads could simultaneously observe that the singleton FileTransfer instance has quit and attempt to replace it without synchronization. This caused undefined behavior as multiple threads would write to the same static std::shared_ptr concurrently. Fixed by adding a mutex to ensure only one thread can replace the singleton instance, using double-checked locking pattern to minimize performance impact.
1 parent b5f765b commit de2a941

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

src/libstore/filetransfer.cc

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <random>
2929
#include <thread>
3030
#include <regex>
31+
#include <mutex>
3132

3233
using namespace std::string_literals;
3334

@@ -844,9 +845,17 @@ ref<curlFileTransfer> makeCurlFileTransfer()
844845
ref<FileTransfer> getFileTransfer()
845846
{
846847
static ref<curlFileTransfer> fileTransfer = makeCurlFileTransfer();
847-
848-
if (fileTransfer->state_.lock()->quit)
849-
fileTransfer = makeCurlFileTransfer();
848+
static std::mutex fileTransferMutex;
849+
850+
// Check if the current instance has quit
851+
if (fileTransfer->state_.lock()->quit) {
852+
// Only one thread should replace the singleton
853+
std::lock_guard<std::mutex> guard(fileTransferMutex);
854+
// Double-check after acquiring the lock
855+
if (fileTransfer->state_.lock()->quit) {
856+
fileTransfer = makeCurlFileTransfer();
857+
}
858+
}
850859

851860
return fileTransfer;
852861
}

0 commit comments

Comments
 (0)