xref: /haiku/src/apps/haikudepot/process/AbstractProcessNode.cpp (revision abba71575e34f84c3d75be9d29d6e6caa6c033db)
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