1 /* 2 * Copyright 2021, Andrew Lindesay <apl@lindesay.co.nz>. 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "AbstractProcessNode.h" 8 9 #include <unistd.h> 10 11 #include "AbstractProcess.h" 12 #include "Logger.h" 13 14 15 #define SPIN_UNTIL_STARTED_DELAY_MI 250 * 1000 16 // quarter of a second 17 18 #define TIMEOUT_UNTIL_STARTED_SECS 10 19 #define TIMEOUT_UNTIL_STOPPED_SECS 10 20 21 22 AbstractProcessNode::AbstractProcessNode(AbstractProcess* process) 23 : 24 fProcess(process) 25 { 26 } 27 28 29 AbstractProcessNode::~AbstractProcessNode() 30 { 31 delete fProcess; 32 } 33 34 35 AbstractProcess* 36 AbstractProcessNode::Process() const 37 { 38 return fProcess; 39 } 40 41 42 /*! This method will spin-lock the thread until the process is in one of the 43 states defined by the mask. 44 */ 45 46 status_t 47 AbstractProcessNode::_SpinUntilProcessState( 48 uint32 desiredStatesMask, uint32 timeoutSeconds) 49 { 50 bigtime_t start = system_time(); 51 bigtime_t timeoutMicroSeconds = timeoutSeconds * 1000 * 1000; 52 53 while (true) { 54 if ((Process()->ProcessState() & desiredStatesMask) != 0) 55 return B_OK; 56 57 usleep(SPIN_UNTIL_STARTED_DELAY_MI); 58 59 if (system_time() - start > timeoutMicroSeconds) { 60 HDERROR("[Node<%s>] timeout waiting for process state", 61 Process()->Name()); 62 return B_ERROR; 63 } 64 } 65 } 66 67 68 void 69 AbstractProcessNode::AddPredecessor(AbstractProcessNode *node) 70 { 71 fPredecessorNodes.AddItem(node); 72 node->_AddSuccessor(this); 73 } 74 75 76 int32 77 AbstractProcessNode::CountPredecessors() const 78 { 79 return fPredecessorNodes.CountItems(); 80 } 81 82 83 AbstractProcessNode* 84 AbstractProcessNode::PredecessorAt(int32 index) const 85 { 86 return fPredecessorNodes.ItemAt(index); 87 } 88 89 90 bool 91 AbstractProcessNode::AllPredecessorsComplete() const 92 { 93 for (int32 i = 0; i < CountPredecessors(); i++) { 94 if (PredecessorAt(i)->Process()->ProcessState() != PROCESS_COMPLETE) 95 return false; 96 } 97 98 return true; 99 } 100 101 102 void 103 AbstractProcessNode::_AddSuccessor(AbstractProcessNode* node) 104 { 105 fSuccessorNodes.AddItem(node); 106 } 107 108 109 int32 110 AbstractProcessNode::CountSuccessors() const 111 { 112 return fSuccessorNodes.CountItems(); 113 } 114 115 116 AbstractProcessNode* 117 AbstractProcessNode::SuccessorAt(int32 index) const 118 { 119 return fSuccessorNodes.ItemAt(index); 120 } 121 122