Project

General

Profile

Download (3.28 KB) Statistics
| Branch: | Revision:
2c54c4c3 david.sorber
/********************************************************************
* CONFIDENTIAL - All source code is the propriety and confidential *
* information of David Sorber. *
* *
* Copyright 2024 David Sorber *
* Unpublished -- all rights reserved under the copyright laws *
* of the United States. *
********************************************************************/
#include <chrono>
#include <system_error>

#include <sys/stat.h>

#include "CopyManager.h"


DBS::CopyManager::CopyManager(CopyManagerOptions& options)
: r_options(options),
m_terminate(false),
p_mainThread(nullptr)
{
}

DBS::CopyManager::~CopyManager()
{
// Add processor thread terminators
for (uint32_t idx = 0; idx < r_options.getNumProcThreads(); ++idx)
{
m_entryQueue.push_back(ENTRY_TERMINATOR);
}

// Join and delete thread terminators
for (auto& thread : m_procThreads)
{
thread->join();
delete thread;
}
m_procThreads.clear();

// Cleanup the main thread
if (p_mainThread != nullptr)
{
if (p_mainThread->joinable())
{
p_mainThread->join();
}
delete p_mainThread;
p_mainThread = nullptr;
}
}

int DBS::CopyManager::run()
{
// Spawn processor threads
for (uint32_t idx = 0; idx < r_options.getNumProcThreads(); ++idx)
{
m_procThreads.push_back(
new std::thread(&CopyManager::processThreadBody, this));
}

// Spawn the main thread
p_mainThread = new std::thread(&CopyManager::mainThreadBody, this);


p_mainThread->join();

return 0;
}

void DBS::CopyManager::mainThreadBody()
{
const std::string& srcPath(r_options.getSrcPath());
for (const auto& dirEntry : sfs::recursive_directory_iterator(srcPath))
{
// Flow control
while (m_entryQueue.size() >= r_options.getFlowControlThreshold())
{
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}

// std::cout << "PATH: " << dirEntry << std::endl;
m_entryQueue.push_back(dirEntry);
}

// Add processor thread terminators
for (uint32_t idx = 0; idx < r_options.getNumProcThreads(); ++idx)
{
m_entryQueue.push_back(ENTRY_TERMINATOR);
}
}


void DBS::CopyManager::processThreadBody()
{
sfs::directory_entry entry;
struct stat statBuf{};
int rc = 0;
std::error_code errorCode;

while (true)
{
// Grab entry from queue
entry = m_entryQueue.pop_front();
if (entry == ENTRY_TERMINATOR)
{
break;
}

if (entry.is_directory())
{
// Directory entry
const char* dirPath = entry.path().string().c_str();
rc = stat(dirPath, &statBuf);

if (! sfs::create_directories(entry.path(), errorCode))
{
// TODO: log it
}
}
else if (entry.is_regular_file())
{
// Regular file entry
}
else
{
// Unsupported entry type
// TODO: log it?
}


std::cout << "PATH: " << entry << std::endl;
}
}