add doxygen via opencode

This commit is contained in:
2026-02-27 23:42:09 +03:00
parent 1739836a18
commit b53ef184dc
63 changed files with 3374 additions and 681 deletions

View File

@@ -1,9 +1,12 @@
/*! \file piblockingqueue.h
* \ingroup Thread
* \~\brief
* \~english Queue with blocking
* \~russian Блокирующая очередь
*/
//! \file piblockingqueue.h
//! \ingroup Thread
//! \brief
//! \~english Queue with blocking
//! \~russian Блокирующая очередь
//!
//! \details
//! \~english Thread-safe queue that supports blocking operations - waits for space when storing and waits for element when retrieving.
//! \~russian Потокобезопасная очередь с поддержкой блокирующих операций - ожидает место при добавлении и ожидает элемент при получении.
/*
PIP - Platform Independent Primitives
@@ -33,12 +36,13 @@
* \brief A Queue that supports operations that wait for the queue to become non-empty when retrieving an element, and
* wait for space to become available in the queue when storing an element.
*/
//! \~english Thread-safe blocking queue template class
//! \~russian Шаблонный класс потокобезопасной блокирующей очереди
template<typename T>
class PIBlockingQueue: private PIQueue<T> {
public:
/**
* \brief Constructor
*/
//! \~english Constructs queue with specified capacity
//! \~russian Создает очередь с указанной емкостью
explicit inline PIBlockingQueue(size_t capacity = SIZE_MAX,
PIConditionVariable * cond_var_add = new PIConditionVariable(),
PIConditionVariable * cond_var_rem = new PIConditionVariable())
@@ -46,9 +50,8 @@ public:
, cond_var_rem(cond_var_rem)
, max_size(capacity) {}
/**
* \brief Copy constructor. Initialize queue with copy of other queue elements. Not thread-safe for other queue.
*/
//! \~english Copy constructor from PIDeque
//! \~russian Конструктор копирования из PIDeque
explicit inline PIBlockingQueue(const PIDeque<T> & other)
: cond_var_add(new PIConditionVariable())
, cond_var_rem(new PIConditionVariable()) {
@@ -58,9 +61,8 @@ public:
mutex.unlock();
}
/**
* \brief Thread-safe copy constructor. Initialize queue with copy of other queue elements.
*/
//! \~english Thread-safe copy constructor from another PIBlockingQueue
//! \~russian Потокобезопасный конструктор копирования из другой PIBlockingQueue
inline PIBlockingQueue(PIBlockingQueue<T> & other): cond_var_add(new PIConditionVariable()), cond_var_rem(new PIConditionVariable()) {
other.mutex.lock();
mutex.lock();
@@ -75,11 +77,8 @@ public:
delete cond_var_rem;
}
/**
* \brief Inserts the specified element into this queue, waiting if necessary for space to become available.
*
* @param v the element to add
*/
//! \~english Inserts element waiting for space to become available
//! \~russian Вставляет элемент, ожидая освобождения места
PIBlockingQueue<T> & put(const T & v) {
mutex.lock();
cond_var_rem->wait(mutex, [&]() { return PIDeque<T>::size() < max_size; });
@@ -91,14 +90,8 @@ public:
PIBlockingQueue<T> & enqueue(const T & v) { return put(v); }
/**
* \brief Inserts the specified element at the end of this queue if it is possible to do so immediately without
* exceeding the queue's capacity, returning true upon success and false if this queue is full.
*
* @param v the element to add
* @param timeout the timeout waiting for inserting if que is full, if timeout is null, then returns immediately
* @return true if the element was added to this queue, else false
*/
//! \~english Inserts element if possible without exceeding capacity
//! \~russian Вставляет элемент если возможно без превышения емкости
bool offer(const T & v, PISystemTime timeout = {}) {
bool isOk;
mutex.lock();
@@ -129,16 +122,8 @@ public:
T dequeue() { return take(); }
/**
* \brief Retrieves and removes the head of this queue, waiting up to the specified wait time if necessary for an
* element to become available.
*
* @param timeout how long to wait before giving up
* @param defaultVal value, which returns if the specified waiting time elapses before an element is available
* @param isOk flag, which indicates result of method execution. It will be set to false if timeout, or true if
* return value is retrieved value
* @return the head of this queue, or defaultVal if the specified waiting time elapses before an element is available
*/
//! \~english Retrieves and removes head, waiting until element becomes available
//! \~russian Извлекает и удаляет голову очереди, ожидая появления элемента
T poll(PISystemTime timeout = {}, const T & defaultVal = T(), bool * isOk = nullptr) {
T t = defaultVal;
bool isNotEmpty;
@@ -154,12 +139,8 @@ public:
return t;
}
/**
* \brief Returns the number of elements that this queue can ideally (in the absence of memory or resource
* constraints) contains. This is always equal to the initial capacity of this queue less the current size of this queue.
*
* @return the capacity
*/
//! \~english Returns queue capacity
//! \~russian Возвращает емкость очереди
size_t capacity() {
size_t c;
mutex.lock();
@@ -168,12 +149,8 @@ public:
return c;
}
/**
* \brief Returns the number of additional elements that this queue can ideally (in the absence of memory or resource
* constraints) accept. This is always equal to the initial capacity of this queue less the current size of this queue.
*
* @return the remaining capacity
*/
//! \~english Returns remaining capacity
//! \~russian Возвращает оставшуюся емкость
size_t remainingCapacity() {
mutex.lock();
size_t c = max_size - PIDeque<T>::size();
@@ -181,9 +158,8 @@ public:
return c;
}
/**
* \brief Returns the number of elements in this collection.
*/
//! \~english Returns number of elements in queue
//! \~russian Возвращает количество элементов в очереди
size_t size() {
mutex.lock();
size_t s = PIDeque<T>::size();
@@ -191,9 +167,8 @@ public:
return s;
}
/**
* \brief Removes all available elements from this queue and adds them to other given queue.
*/
//! \~english Removes all available elements and adds them to another queue
//! \~russian Удаляет все доступные элементы и добавляет их в другую очередь
size_t drainTo(PIDeque<T> & other, size_t maxCount = SIZE_MAX) {
mutex.lock();
size_t count = ((maxCount > PIDeque<T>::size()) ? PIDeque<T>::size() : maxCount);
@@ -203,9 +178,8 @@ public:
return count;
}
/**
* \brief Removes all available elements from this queue and adds them to other given queue.
*/
//! \~english Removes all available elements and adds them to another blocking queue
//! \~russian Удаляет все доступные элементы и добавляет их в другую блокирующую очередь
size_t drainTo(PIBlockingQueue<T> & other, size_t maxCount = SIZE_MAX) {
mutex.lock();
other.mutex.lock();

View File

@@ -1,9 +1,12 @@
/*! \file piconditionvar.h
* \ingroup Thread
* \~\brief
* \~english Conditional variable
* \~russian Conditional variable
*/
//! \file piconditionvar.h
//! \ingroup Thread
//! \brief
//! \~english Conditional variable
//! \~russian Условная переменная
//!
//! \details
//! \~english Object able to block the calling thread until notified to resume.
//! \~russian Объект, способный заблокировать вызывающий поток до уведомления о продолжении.
/*
PIP - Platform Independent Primitives
@@ -36,27 +39,39 @@
* It uses a PIMutex to lock the thread when one of its wait functions is called. The thread remains
* blocked until woken up by another thread that calls a notification function on the same PIConditionVariable object.
*/
//! \~english Condition variable for thread synchronization
//! \~russian Условная переменная для синхронизации потоков
class PIP_EXPORT PIConditionVariable {
public:
NO_COPY_CLASS(PIConditionVariable);
//! \~english Constructs condition variable
//! \~russian Создает условную переменную
explicit PIConditionVariable();
//! \~english Destroys condition variable
//! \~russian Уничтожает условную переменную
virtual ~PIConditionVariable();
/**
* \brief Unblocks one of the threads currently waiting for this condition. If no threads are waiting, the function
* does nothing. If more than one, it is unspecified which of the threads is selected.
*/
//! \~english Wakes one waiting thread
//! \~russian Будит один ожидающий поток
void notifyOne();
/**
* \brief Unblocks all threads currently waiting for this condition. If no threads are waiting, the function does
* nothing.
*/
//! \~english Wakes all waiting threads
//! \~russian Будит все ожидающие потоки
void notifyAll();
/**
* \brief see wait(PIMutex &, const std::function<bool()>&)
*/
//! \~english Wait until notified
//! \~russian Ожидает уведомления
virtual void wait(PIMutex & lk);
/**
@@ -83,11 +98,15 @@ public:
* @param condition A callable object or function that takes no arguments and returns a value that can be evaluated
* as a bool. This is called repeatedly until it evaluates to true.
*/
//! \~english Wait until notified with condition predicate
//! \~russian Ожидает уведомления с условием
virtual void wait(PIMutex & lk, const std::function<bool()> & condition);
/**
* \brief see waitFor(PIMutex &, int, const std::function<bool()>&)
*/
//! \~english Wait for timeout
//! \~russian Ожидает таймаут
virtual bool waitFor(PIMutex & lk, PISystemTime timeout);
/**
@@ -115,6 +134,8 @@ public:
* as a bool. This is called repeatedly until it evaluates to true.
* @return false if timeout reached or true if wakeup condition is true
*/
//! \~english Wait for timeout or until notified with condition predicate
//! \~russian Ожидает таймаут или уведомление с условием
virtual bool waitFor(PIMutex & lk, PISystemTime timeout, const std::function<bool()> & condition);
private:

View File

@@ -1,9 +1,12 @@
/*! \file pigrabberbase.h
* \ingroup Thread
* \~\brief
* \~english Abstract class for create grabbers
* \~russian Базовый класс для создания грабберов
*/
//! \file pigrabberbase.h
//! \ingroup Thread
//! \brief
//! \~english Abstract class for creating grabbers
//! \~russian Базовый класс для создания грабберов
//!
//! \details
//! \~english Base class for thread-based data acquisition with queue support.
//! \~russian Базовый класс для получения данных в потоке с поддержкой очереди.
/*
PIP - Platform Independent Primitives
Abstract class for create grabbers
@@ -31,18 +34,33 @@
#include "pitime.h"
//! \~english Base class for data grabber threads
//! \~russian Базовый класс для потоков получения данных
template<typename T = PIByteArray>
class PIGrabberBase: public PIThread {
PIOBJECT_SUBCLASS(PIGrabberBase, PIThread);
public:
//! \~english Constructs grabber
//! \~russian Создает граббер
PIGrabberBase() {
is_opened = false;
is_recording = false;
}
//! \~english Destroys grabber
//! \~russian Уничтожает граббер
virtual ~PIGrabberBase() { stopGrabber(false); }
//! \~english Returns if grabber is opened
//! \~russian Возвращает открыт ли граббер
virtual bool isOpened() const { return is_opened; }
//! \~english Returns if grabber is recording
//! \~russian Возвращает записывает ли граббер
virtual bool isRecording() const { return is_recording; }
//! \~english Start recording to file
//! \~russian Начинает запись в файл
virtual void startRecord(const PIString & filename) {
if (!isOpened()) return;
if (isRecording()) return;
@@ -51,6 +69,8 @@ public:
is_recording = true;
rec_mutex.unlock();
}
//! \~english Stop recording
//! \~russian Останавливает запись
virtual void stopRecord() {
if (!isOpened()) return;
if (!isRecording()) return;
@@ -59,6 +79,9 @@ public:
stopRecordInternal();
rec_mutex.unlock();
}
//! \~english Returns last grabbed data
//! \~russian Возвращает последние полученные данные
T last() const {
T ret;
last_mutex.lock();
@@ -66,6 +89,9 @@ public:
last_mutex.unlock();
return ret;
}
//! \~english Returns if queue is empty
//! \~russian Возвращает пустая ли очередь
bool isEmpty() {
bool ret;
que_mutex.lock();
@@ -73,6 +99,9 @@ public:
que_mutex.unlock();
return ret;
}
//! \~english Returns queue size
//! \~russian Возвращает размер очереди
int queSize() {
int ret;
que_mutex.lock();
@@ -80,6 +109,9 @@ public:
que_mutex.unlock();
return ret;
}
//! \~english Dequeues data from queue
//! \~russian Извлекает данные из очереди
T dequeue() {
T ret;
// piCoutObj << "start";
@@ -92,6 +124,9 @@ public:
que_mutex.unlock();
return ret;
}
//! \~english Stop grabber thread
//! \~russian Останавливает поток граббера
void stopGrabber(bool wait_forever = true) {
if (isRunning()) {
stop();
@@ -104,12 +139,18 @@ public:
}
}
}
//! \~english Open grabber
//! \~russian Открывает граббер
bool open() {
bool ret = openInternal();
if (!is_opened && ret) opened();
is_opened = ret;
return ret;
}
//! \~english Close grabber
//! \~russian Закрывает граббер
void close() {
bool em = is_opened;
closeInternal();
@@ -117,12 +158,21 @@ public:
if (em) closed();
is_opened = false;
}
//! \~english Returns diagnostics
//! \~russian Возвращает диагностику
const PIDiagnostics & diag() const { return diag_; }
//! \~english Clear queue
//! \~russian Очищает очередь
void clear() {
que_mutex.lock();
que.clear();
que_mutex.unlock();
}
//! \~english Restart grabber
//! \~russian Перезапускает граббер
void restart() {
clear();
close();

View File

@@ -1,9 +1,12 @@
/*! \file pipipelinethread.h
* \ingroup Thread
* \~\brief
* \~english Class for create multihread pipeline
* \~russian Класс для создания многопоточного конвейера
*/
//! \file pipipelinethread.h
//! \ingroup Thread
//! \brief
//! \~english Class for creating multithread pipeline
//! \~russian Класс для создания многопоточного конвейера
//!
//! \details
//! \~english Pipeline thread for processing data through stages in separate threads.
//! \~russian Конвейерный поток для обработки данных через этапы в отдельных потоках.
/*
PIP - Platform Independent Primitives
Class for create multihread pipeline
@@ -31,16 +34,22 @@
#include "pithread.h"
//! \~english Pipeline thread template class
//! \~russian Шаблонный класс конвейерного потока
template<typename Tin, typename Tout>
class PIPipelineThread: public PIThread {
PIOBJECT_SUBCLASS(PIPipelineThread, PIThread);
public:
//! \~english Constructs pipeline thread
//! \~russian Создает конвейерный поток
PIPipelineThread() {
cnt = 0;
max_size = 0;
wait_next_pipe = false;
}
//! \~english Destroys pipeline thread
//! \~russian Уничтожает конвейерный поток
~PIPipelineThread() {
stop();
cv.notifyAll();
@@ -49,6 +58,8 @@ public:
terminate();
}
}
//! \~english Connect to next pipeline stage
//! \~russian Подключает к следующему этапу конвейера
template<typename T>
void connectTo(PIPipelineThread<Tout, T> * next) {
CONNECT3(void, Tout, bool, bool *, this, calculated, next, enqueue);
@@ -72,9 +83,21 @@ public:
}
mutex.unlock();
}
//! \~english Enqueue data for processing
//! \~russian Добавляет данные в очередь на обработку
void enqueue(const Tin & v, bool wait = false) { enqueue(v, wait, nullptr); }
//! \~english Returns pointer to counter
//! \~russian Возвращает указатель на счетчик
const ullong * counterPtr() const { return &cnt; }
//! \~english Returns items processed counter
//! \~russian Возвращает количество обработанных элементов
ullong counter() const { return cnt; }
//! \~english Returns if input queue is empty
//! \~russian Возвращает пустая ли входная очередь
bool isEmpty() {
bool ret;
mutex.lock();
@@ -82,6 +105,9 @@ public:
mutex.unlock();
return ret;
}
//! \~english Returns input queue size
//! \~russian Возвращает размер входной очереди
int queSize() {
int ret;
mutex.lock();
@@ -89,6 +115,9 @@ public:
mutex.unlock();
return ret;
}
//! \~english Clear input queue
//! \~russian Очищает входную очередь
void clear() {
mutex.lock();
mutex_wait.lock();
@@ -97,6 +126,9 @@ public:
mutex_wait.unlock();
mutex.unlock();
}
//! \~english Stop calculation
//! \~russian Останавливает вычисления
void stopCalc(int wait_delay = 100) {
if (isRunning()) {
stop();
@@ -108,6 +140,9 @@ public:
}
}
}
//! \~english Returns last processed result
//! \~russian Возвращает последний обработанный результат
Tout getLast() {
Tout ret;
mutex_last.lock();
@@ -116,8 +151,12 @@ public:
return ret;
}
//! \~english Returns max queue size
//! \~russian Возвращает максимальный размер очереди
uint maxQueSize() { return max_size; }
//! \~english Set max queue size
//! \~russian Устанавливает максимальный размер очереди
void setMaxQueSize(uint count) {
mutex.lock();
max_size = count;
@@ -125,10 +164,17 @@ public:
mutex.unlock();
}
//! \~english Returns if waiting for next pipeline
//! \~russian Возвращает ожидает ли следующий конвейер
bool isWaitNextPipe() { return wait_next_pipe; }
//! \~english Set waiting for next pipeline
//! \~russian Устанавливает ожидание следующего конвейера
void setWaitNextPipe(bool wait) { wait_next_pipe = wait; }
protected:
//! \~english Processing function - must be implemented
//! \~russian Функция обработки - должна быть реализована
virtual Tout calc(Tin & v, bool & ok) = 0;
uint max_size;

View File

@@ -1,26 +1,29 @@
/*! \file piprotectedvariable.h
* \ingroup Thread
* \~\brief
* \~english Thread-safe variable
* \~russian Потокобезопасная переменная
*/
//! \file piprotectedvariable.h
//! \ingroup Thread
//! \brief
//! \~english Thread-safe variable
//! \~russian Потокобезопасная переменная
//!
//! \details
//! \~english Template class for thread-safe variable access with mutex protection.
//! \~russian Шаблонный класс для потокобезопасного доступа к переменной с защитой мьютексом.
/*
PIP - Platform Independent Primitives
Thread-safe variable
Ivan Pelipenko peri4ko@yandex.ru, Stephan Fomenko, Andrey Bychkov work.a.b@yandex.ru
PIP - Platform Independent Primitives
Thread-safe variable
Ivan Pelipenko peri4ko@yandex.ru, Stephan Fomenko, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIPROTECTEDVARIABLE_H
@@ -29,25 +32,37 @@
#include "pimutex.h"
//! \~english Thread-safe variable template class
//! \~russian Шаблонный класс потокобезопасной переменной
template<typename T>
class PIP_EXPORT PIProtectedVariable {
public:
//! \~english
//! \~russian
//! \~english Pointer wrapper for thread-safe access
//! \~russian Обертка указателя для потокобезопасного доступа
class PIP_EXPORT Pointer {
friend class PIProtectedVariable<T>;
public:
//! \~english Copy constructor
//! \~russian Конструктор копирования
Pointer(const Pointer & v): pv(v.pv), counter(v.counter + 1) {}
//! \~english Destructor - unlocks mutex
//! \~russian Деструктор - разблокирует мьютекс
~Pointer() {
if (counter == 0) pv.mutex.unlock();
}
//! \~english Access member
//! \~russian Доступ к члену
T * operator->() { return &pv.var; }
//! \~english Access value
//! \~russian Доступ к значению
T & operator*() { return pv.var; }
private:
Pointer() = delete;
//! \~english Construct from PIProtectedVariable
//! \~russian Конструктор из PIProtectedVariable
Pointer(PIProtectedVariable<T> & v): pv(v) {}
PIProtectedVariable<T> & pv;

View File

@@ -1,3 +1,12 @@
//! \file pithreadpoolexecutor.h
//! \ingroup Thread
//! \brief
//! \~english Thread pool executor
//! \~russian Исполнитель пула потоков
//!
//! \details
//! \~english Executes tasks in a pool of worker threads.
//! \~russian Выполняет задачи в пуле рабочих потоков.
/*
PIP - Platform Independent Primitives
@@ -26,10 +35,16 @@
#include <atomic>
//! \~english Thread pool executor for running tasks
//! \~russian Исполнитель пула потоков для выполнения задач
class PIP_EXPORT PIThreadPoolExecutor {
public:
//! \~english Constructs executor with core pool size
//! \~russian Создает исполнитель с размером ядра пула
explicit PIThreadPoolExecutor(int corePoolSize);
//! \~english Destroys executor
//! \~russian Уничтожает исполнитель
virtual ~PIThreadPoolExecutor();
//! \brief Executes the given task sometime in the future. The task execute in an existing pooled thread. If the task
@@ -37,17 +52,27 @@ public:
//! reached.
//!
//! \param runnable not empty function for thread pool execution
//! \~english Execute task in thread pool
//! \~russian Выполняет задачу в пуле потоков
void execute(const std::function<void()> & runnable);
//! \~english Stop all threads immediately
//! \~russian Немедленно останавливает все потоки
void shutdownNow();
//! \brief Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be
//! accepted. Invocation has no additional effect if already shut down. This method does not wait for previously
//! submitted tasks to complete execution. Use awaitTermination to do that.
//! \~english Initiates orderly shutdown
//! \~russian Инициирует упорядоченное завершение
void shutdown();
//! \~english Returns if executor is shutdown
//! \~russian Возвращает остановлен ли исполнитель
bool isShutdown() const;
//! \~english Wait for termination
//! \~russian Ожидает завершения
bool awaitTermination(PISystemTime timeout);
private: