xref: /haiku/src/apps/haikudepot/process/ThreadedProcessNode.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 "ThreadedProcessNode.h"
8 
9 #include <unistd.h>
10 
11 #include "AbstractProcess.h"
12 #include "Logger.h"
13 
14 
15 #define TIMEOUT_UNTIL_STARTED_SECS 10
16 #define TIMEOUT_UNTIL_STOPPED_SECS 10
17 
18 
19 ThreadedProcessNode::ThreadedProcessNode(AbstractProcess* process)
20 	:
21 	AbstractProcessNode(process),
22 	fWorker(B_BAD_THREAD_ID)
23 
24 {
25 }
26 
27 
28 ThreadedProcessNode::~ThreadedProcessNode()
29 {
30 }
31 
32 
33 /*! Considered to be protected from concurrent access by the ProcessCoordinator
34 */
35 
36 status_t
37 ThreadedProcessNode::StartProcess()
38 {
39 	if (fWorker != B_BAD_THREAD_ID)
40 		return B_BUSY;
41 
42 	HDINFO("[Node<%s>] initiating threaded", Process()->Name());
43 
44 	fWorker = spawn_thread(&_StartProcess, Process()->Name(),
45 		B_NORMAL_PRIORITY, Process());
46 
47 	if (fWorker >= 0) {
48 		resume_thread(fWorker);
49 		return _SpinUntilProcessState(PROCESS_RUNNING | PROCESS_COMPLETE,
50 			TIMEOUT_UNTIL_STARTED_SECS);
51 	}
52 
53 	return B_ERROR;
54 }
55 
56 
57 /*! Considered to be protected from concurrent access by the ProcessCoordinator
58 */
59 
60 status_t
61 ThreadedProcessNode::StopProcess()
62 {
63 	Process()->SetListener(NULL);
64 	status_t stopResult = Process()->Stop();
65 	status_t waitResult = _SpinUntilProcessState(PROCESS_COMPLETE,
66 		TIMEOUT_UNTIL_STOPPED_SECS);
67 
68 	// if the thread is still running then it will be necessary to tear it
69 	// down.
70 
71 	if (waitResult != B_OK) {
72 		HDINFO("[%s] process did not stop within timeout - will be stopped "
73 			"uncleanly", Process()->Name());
74 		kill_thread(fWorker);
75 	}
76 
77 	if (stopResult != B_OK)
78 		return stopResult;
79 
80 	if (waitResult != B_OK)
81 		return waitResult;
82 
83 	return B_OK;
84 }
85 
86 
87 /*! This method is the initial function that is invoked on starting a new
88 	thread.  It will start a process that is part of the bulk-load.
89  */
90 
91 /*static*/ status_t
92 ThreadedProcessNode::_StartProcess(void* cookie)
93 {
94 	AbstractProcess* process = static_cast<AbstractProcess*>(cookie);
95 	bigtime_t start = system_time();
96 
97 	HDINFO("[Node<%s>] starting process in thread", process->Name());
98 	process->Run();
99 	HDINFO("[Node<%s>] finished process in thread %f seconds", process->Name(),
100 		(system_time() - start) / 1000000.0);
101 
102 	return B_OK;
103 }
104