KiCad PCB EDA Suite
Loading...
Searching...
No Matches
DB_WORKER_THREAD Class Reference

Runs one job at a time on its own thread so that a call stuck in filesystem I/O, which nothing can interrupt, cannot hold up the caller past a bound. More...

#include <db_worker_thread.h>

Public Types

enum class  OUTCOME {
  OK , TIMED_OUT , TOO_LATE , REFUSED ,
  UNAVAILABLE
}
 Why the last Run or RunCleanup returned without a result. More...
 

Public Member Functions

 DB_WORKER_THREAD (std::string aSourceKey, std::function< bool()> aThreadInit=nullptr, std::function< void()> aThreadExit=nullptr, bool aPumpMessages=false, std::function< void()> aOnAbandon=nullptr)
 
 ~DB_WORKER_THREAD ()
 Waits up to the shutdown bound for a running job, then abandons it.
 
 DB_WORKER_THREAD (const DB_WORKER_THREAD &)=delete
 
DB_WORKER_THREAD & operator= (const DB_WORKER_THREAD &)=delete
 
template<typename R>
std::optional< R > Run (std::function< R(DB_JOB_CONTEXT &)> aJob, std::chrono::milliseconds aBound, const DB_ROW_SINK *aSink)
 Runs aJob on the worker thread and waits for it.
 
bool RunCleanup (std::function< void()> aCleanup, std::chrono::milliseconds aBound)
 Runs aCleanup on a worker thread for work that must not happen on the caller, such as closing a connection.
 
bool IsHealthy () const
 
bool HasLiveThread () const
 
OUTCOME LastOutcome () const
 
void SetShutdownBound (std::chrono::milliseconds aBound)
 Sets how long the destructor waits for a running job before abandoning it.
 

Static Public Member Functions

static bool OnWorkerThread ()
 
static std::string SourceKeyFor (const std::string &aPath)
 
static std::string SourceKeyFor (const std::string &aPath, bool aWindowsPath)
 As SourceKeyFor, for a path whose separators and prefixes follow Windows rules or not; relative paths stay so.
 
static std::string NormalizePath (const std::string &aPath, bool aWindowsPath)
 Rewrites the spellings of one file that Windows treats alike into one form, without touching the file system: backslashes become slashes, and \?
 
static std::chrono::milliseconds CallerBound (int aTimeoutSeconds)
 

Static Public Attributes

static constexpr size_t MAX_ABANDONED = 2
 

Private Member Functions

bool runJob (std::function< void(DB_JOB_CONTEXT &)> aJob, std::chrono::milliseconds aBound, const DB_ROW_SINK *aSink, bool aCleanup)
 

Private Attributes

std::string m_key
 
bool m_pumpMessages
 
std::chrono::milliseconds m_shutdownBound { std::chrono::seconds( 30 ) }
 
std::shared_ptr< OUTCOME > m_outcome = std::make_shared<OUTCOME>( OUTCOME::OK )
 
std::shared_ptr< DB_WORKER_STATE > m_state
 

Detailed Description

Runs one job at a time on its own thread so that a call stuck in filesystem I/O, which nothing can interrupt, cannot hold up the caller past a bound.

A job that makes no progress for its bound is abandoned. The thread keeps the job and everything it owns until the blocked call returns, publishes nothing further and then exits. The next Run starts a fresh thread. At most MAX_ABANDONED abandoned threads may be outstanding per source key, process wide, so that repeated timeouts against a dead share cannot pile up threads. A job holds a slot of that allowance from the moment it is accepted until its thread returns, so concurrent callers cannot overshoot the cap.

This class depends on the standard library and the database settings, with the message dispatch on Windows. A worker serves one calling thread at a time.

Definition at line 92 of file db_worker_thread.h.

Member Enumeration Documentation

◆ OUTCOME

enum class DB_WORKER_THREAD::OUTCOME
strong

Why the last Run or RunCleanup returned without a result.

Enumerator
OK 
TIMED_OUT 

no progress within the bound, so the job was abandoned

TOO_LATE 

a slot freed with under half the bound left, so nothing was started

REFUSED 

two abandoned jobs hold the source, or no slot freed within the bound

UNAVAILABLE 

the worker thread could not start

Definition at line 114 of file db_worker_thread.h.

Constructor & Destructor Documentation

◆ DB_WORKER_THREAD() [1/2]

DB_WORKER_THREAD::DB_WORKER_THREAD ( std::string aSourceKey,
std::function< bool()> aThreadInit = nullptr,
std::function< void()> aThreadExit = nullptr,
bool aPumpMessages = false,
std::function< void()> aOnAbandon = nullptr )
Parameters
aSourceKeynames the source the jobs touch; workers with equal keys share the abandoned cap
aThreadInitruns on the worker thread before its first job; false marks the worker unusable
aThreadExitruns on the worker thread after its last job, and only if aThreadInit succeeded
aPumpMessageson Windows, the worker dispatches its thread's window messages while it waits for a job and while it waits for the caller to take rows, as a COM apartment needs; ignored elsewhere
aOnAbandonruns on the owner's thread each time a worker blocked in a job is detached

Definition at line 426 of file db_worker_thread.cpp.

References m_key, m_pumpMessages, m_state, and move.

Referenced by DB_WORKER_THREAD(), and operator=().

◆ ~DB_WORKER_THREAD()

DB_WORKER_THREAD::~DB_WORKER_THREAD ( )

Waits up to the shutdown bound for a running job, then abandons it.

Definition at line 439 of file db_worker_thread.cpp.

References m_shutdownBound, and m_state.

◆ DB_WORKER_THREAD() [2/2]

DB_WORKER_THREAD::DB_WORKER_THREAD ( const DB_WORKER_THREAD & )
delete

References DB_WORKER_THREAD().

Member Function Documentation

◆ CallerBound()

std::chrono::milliseconds DB_WORKER_THREAD::CallerBound ( int aTimeoutSeconds)
static
Returns
the longest a caller waits on a source with the given timeout: the timeout plus 10 s, or 30 s for 0

Definition at line 531 of file db_worker_thread.cpp.

References DatabaseFileWaitSeconds().

Referenced by SQLITE_BACKEND::callerBound(), ACE_BACKEND::closeSpentSessions(), ACE_BACKEND::freshSession(), ACE_BACKEND::newOp(), ACE_BACKEND::readPass(), ACE_BACKEND::readVerified(), SQLITE_BACKEND::SQLITE_BACKEND(), and ODBC_BACKEND::takeAccessDriverLock().

◆ HasLiveThread()

bool DB_WORKER_THREAD::HasLiveThread ( ) const
Returns
true only while a worker thread exists that has neither been abandoned nor failed to start

Definition at line 523 of file db_worker_thread.cpp.

References m_state.

◆ IsHealthy()

bool DB_WORKER_THREAD::IsHealthy ( ) const
Returns
false if the last Run was abandoned or the worker thread could not start

Definition at line 515 of file db_worker_thread.cpp.

References m_state.

◆ LastOutcome()

OUTCOME DB_WORKER_THREAD::LastOutcome ( ) const
inline

Definition at line 170 of file db_worker_thread.h.

References m_outcome.

◆ NormalizePath()

std::string DB_WORKER_THREAD::NormalizePath ( const std::string & aPath,
bool aWindowsPath )
static

Rewrites the spellings of one file that Windows treats alike into one form, without touching the file system: backslashes become slashes, and \?

\C:\ and \?\UNC\server\ lose the long-path prefix. The source key and the URI builder share this so they agree on which paths are one file.

Definition at line 537 of file db_worker_thread.cpp.

References path.

Referenced by SQLITE_BACKEND::FileUri(), SQLITE_BACKEND::IsUncPath(), and SourceKeyFor().

◆ OnWorkerThread()

bool DB_WORKER_THREAD::OnWorkerThread ( )
static
Returns
true on a thread started by a DB_WORKER_THREAD

Definition at line 654 of file db_worker_thread.cpp.

Referenced by SQLITE_DB::~SQLITE_DB().

◆ operator=()

DB_WORKER_THREAD & DB_WORKER_THREAD::operator= ( const DB_WORKER_THREAD & )
delete

References DB_WORKER_THREAD().

◆ Run()

template<typename R>
std::optional< R > DB_WORKER_THREAD::Run ( std::function< R(DB_JOB_CONTEXT &)> aJob,
std::chrono::milliseconds aBound,
const DB_ROW_SINK * aSink )
inline

Runs aJob on the worker thread and waits for it.

Rows the job emits reach aSink on the calling thread, in order. A sink that throws stops the job; the exception is dropped and Run returns what the job returned. An exception thrown by the job is rethrown on the calling thread.

Parameters
aBoundthe longest the caller waits without progress, counted from the call so waiting for a slot uses it up. Each batch handed to aSink starts the wait again, and time spent inside aSink is not counted.
aSinkreceives the emitted rows; may be null if the job emits none
Returns
the job's result, or nullopt if the bound expired and the job was abandoned, the worker could not start, or too many earlier jobs for this source are still stuck

Definition at line 139 of file db_worker_thread.h.

References result, and runJob().

◆ RunCleanup()

bool DB_WORKER_THREAD::RunCleanup ( std::function< void()> aCleanup,
std::chrono::milliseconds aBound )

Runs aCleanup on a worker thread for work that must not happen on the caller, such as closing a connection.

It skips the per-source admission cap so teardown still works when earlier jobs are stuck, and the wait is bounded like Run. What aCleanup owns is released on the worker even if the wait expires.

Returns
false if the bound expired or the worker could not start

Definition at line 660 of file db_worker_thread.cpp.

References runJob().

◆ runJob()

bool DB_WORKER_THREAD::runJob ( std::function< void(DB_JOB_CONTEXT &)> aJob,
std::chrono::milliseconds aBound,
const DB_ROW_SINK * aSink,
bool aCleanup )
private

◆ SetShutdownBound()

void DB_WORKER_THREAD::SetShutdownBound ( std::chrono::milliseconds aBound)
inline

Sets how long the destructor waits for a running job before abandoning it.

Definition at line 176 of file db_worker_thread.h.

References m_shutdownBound.

◆ SourceKeyFor() [1/2]

std::string DB_WORKER_THREAD::SourceKeyFor ( const std::string & aPath)
static
Returns
the key naming the file at aPath, which does not touch the file system

Definition at line 632 of file db_worker_thread.cpp.

References path, SourceKeyFor(), and text.

Referenced by SourceKeyFor().

◆ SourceKeyFor() [2/2]

std::string DB_WORKER_THREAD::SourceKeyFor ( const std::string & aPath,
bool aWindowsPath )
static

As SourceKeyFor, for a path whose separators and prefixes follow Windows rules or not; relative paths stay so.

Definition at line 561 of file db_worker_thread.cpp.

References end, NormalizePath(), and path.

Member Data Documentation

◆ m_key

std::string DB_WORKER_THREAD::m_key
private

Definition at line 198 of file db_worker_thread.h.

Referenced by DB_WORKER_THREAD(), and runJob().

◆ m_outcome

std::shared_ptr<OUTCOME> DB_WORKER_THREAD::m_outcome = std::make_shared<OUTCOME>( OUTCOME::OK )
private

Definition at line 202 of file db_worker_thread.h.

Referenced by LastOutcome(), and runJob().

◆ m_pumpMessages

bool DB_WORKER_THREAD::m_pumpMessages
private

Definition at line 199 of file db_worker_thread.h.

Referenced by DB_WORKER_THREAD(), and runJob().

◆ m_shutdownBound

std::chrono::milliseconds DB_WORKER_THREAD::m_shutdownBound { std::chrono::seconds( 30 ) }
private

Definition at line 201 of file db_worker_thread.h.

Referenced by SetShutdownBound(), and ~DB_WORKER_THREAD().

◆ m_state

std::shared_ptr<DB_WORKER_STATE> DB_WORKER_THREAD::m_state
private

◆ MAX_ABANDONED

size_t DB_WORKER_THREAD::MAX_ABANDONED = 2
staticconstexpr

Definition at line 95 of file db_worker_thread.h.


The documentation for this class was generated from the following files: