Skip to content

Commit

Permalink
handle the case of concurrent appends to a file
Browse files Browse the repository at this point in the history
  • Loading branch information
frs69wq committed Jun 13, 2024
1 parent 9778eee commit 35ec227
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/File.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,13 @@ namespace simgrid::fsmod {
int File::write_init_checks(sg_size_t num_bytes) {
static int sequence_number = -1;
int my_sequence_number;

if (access_mode_ != "w" && access_mode_ != "a")
throw std::invalid_argument("Invalid access mode. Cannot write in 'r' mode'");

if (access_mode_ == "a" && current_position_ < metadata_->get_future_size())
current_position_ = metadata_->get_future_size();

//TODO: Would be good to move some of the code below to FileMetadata, but that requires
// that FileMetadata know the partition....

Expand Down
32 changes: 31 additions & 1 deletion test/one_disk_storage_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
#include <gtest/gtest.h>
#include <iostream>

#include <simgrid/s4u/Engine.hpp>
#include <simgrid/s4u/ActivitySet.hpp>
#include <simgrid/s4u/Actor.hpp>
#include <simgrid/s4u/Engine.hpp>

#include "fsmod/PathUtil.hpp"
#include "fsmod/FileSystem.hpp"
Expand Down Expand Up @@ -161,6 +162,35 @@ TEST_F(OneDiskStorageTest, SingleAsyncWrite) {
});
}

TEST_F(OneDiskStorageTest, DoubleAsyncAppend) {
DO_TEST_WITH_FORK([this]() {
xbt_log_control_set("root.thresh:info");
this->setup_platform();
sg4::Actor::create("TestActor", host_, [this]() {
std::shared_ptr<sgfs::File> file;
sg4::ActivitySet pending_writes;
XBT_INFO("Create an empty file at /dev/a/foo.txt");
ASSERT_NO_THROW(fs_->create_file("/dev/a/foo.txt", "0B"));
XBT_INFO("Open File '/dev/a/foo.txt' in append mode");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "a"));
XBT_INFO("Asynchronously write 2MB at /dev/a/foo.txt");
ASSERT_NO_THROW(pending_writes.push(file->write_async("2MB")));
XBT_INFO("Sleep for .1 second");
ASSERT_NO_THROW(sg4::this_actor::sleep_for(0.1));
XBT_INFO("Asynchronously write another 2MB at /dev/a/foo.txt");
ASSERT_NO_THROW(pending_writes.push(file->write_async("2MB")));
XBT_INFO("Wait for completion of both write operations");
ASSERT_NO_THROW(pending_writes.wait_all());
XBT_INFO("Close the file");
ASSERT_NO_THROW(fs_->close(file));
XBT_INFO("Check the file size, should be 4MB");
ASSERT_EQ(fs_->file_size("/dev/a/foo.txt"), 4*1000*1000);
});
// Run the simulation
ASSERT_NO_THROW(sg4::Engine::get_instance()->run());
});
}

TEST_F(OneDiskStorageTest, SingleAppendWrite) {
DO_TEST_WITH_FORK([this]() {
this->setup_platform();
Expand Down

0 comments on commit 35ec227

Please sign in to comment.