* Copyright 2021-2022, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include "AbstractProcessNode.h"
#include <unistd.h>
#include "AbstractProcess.h"
#include "Logger.h"
#define SPIN_DELAY_MI 500 * 1000
#define TIMEOUT_UNTIL_STARTED_SECS 10
#define TIMEOUT_UNTIL_STOPPED_SECS 10
AbstractProcessNode::AbstractProcessNode(AbstractProcess* process)
:
fLock(),
fListener(NULL),
fProcess(process)
{
}
AbstractProcessNode::~AbstractProcessNode()
{
delete fProcess;
}
AbstractProcess*
AbstractProcessNode::Process() const
{
return fProcess;
}
bool
AbstractProcessNode::IsRunning()
{
return Process()->ProcessState() == PROCESS_RUNNING;
}
void
AbstractProcessNode::SetListener(ProcessListener* listener)
{
if (fListener != listener) {
AutoLocker<BLocker> locker(&fLock);
fListener = listener;
}
}
states defined by the mask.
*/
status_t
AbstractProcessNode::_SpinUntilProcessState(
uint32 desiredStatesMask, int32 timeoutSeconds)
{
bigtime_t start = system_time();
while (true) {
if ((Process()->ProcessState() & desiredStatesMask) != 0)
return B_OK;
usleep(SPIN_DELAY_MI);
int32 secondElapsed = static_cast<int32>(
(system_time() - start) / (1000 * 1000));
if (timeoutSeconds > 0 && secondElapsed > timeoutSeconds) {
HDERROR("[Node<%s>] timeout waiting for process state after %"
B_PRIi32 " seconds", Process()->Name(), secondElapsed);
return B_ERROR;
}
}
}
void
AbstractProcessNode::AddPredecessor(AbstractProcessNode *node)
{
fPredecessorNodes.AddItem(node);
node->_AddSuccessor(this);
}
int32
AbstractProcessNode::CountPredecessors() const
{
return fPredecessorNodes.CountItems();
}
AbstractProcessNode*
AbstractProcessNode::PredecessorAt(int32 index) const
{
return fPredecessorNodes.ItemAt(index);
}
bool
AbstractProcessNode::AllPredecessorsComplete() const
{
for (int32 i = 0; i < CountPredecessors(); i++) {
if (PredecessorAt(i)->Process()->ProcessState() != PROCESS_COMPLETE)
return false;
}
return true;
}
void
AbstractProcessNode::_AddSuccessor(AbstractProcessNode* node)
{
fSuccessorNodes.AddItem(node);
}
int32
AbstractProcessNode::CountSuccessors() const
{
return fSuccessorNodes.CountItems();
}
AbstractProcessNode*
AbstractProcessNode::SuccessorAt(int32 index) const
{
return fSuccessorNodes.ItemAt(index);
}
BString
AbstractProcessNode::LogReport()
{
return Process()->LogReport();
}