Passed
Pull Request — 0.6.x (#217)
by Shinji
01:38
created

PhpReaderTraceLoop::run()   A

Complexity

Conditions 4
Paths 1

Size

Total Lines 37
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 4
eloc 24
nc 1
nop 3
dl 0
loc 37
rs 9.536
c 1
b 1
f 0
1
<?php
2
3
/**
4
 * This file is part of the sj-i/php-profiler package.
5
 *
6
 * (c) sji <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace PhpProfiler\Inspector\Daemon\Reader\Worker;
15
16
use Generator;
17
use PhpProfiler\Inspector\Daemon\Dispatcher\TargetProcessDescriptor;
18
use PhpProfiler\Inspector\Daemon\Reader\Protocol\Message\TraceMessage;
19
use PhpProfiler\Inspector\Settings\GetTraceSettings\GetTraceSettings;
20
use PhpProfiler\Inspector\Settings\TraceLoopSettings\TraceLoopSettings;
21
use PhpProfiler\Lib\PhpProcessReader\PhpMemoryReader\CallTraceReader;
22
use PhpProfiler\Lib\PhpProcessReader\TraceCache;
23
use PhpProfiler\Lib\Process\ProcessStopper\ProcessStopper;
24
25
use function is_null;
26
use function PhpProfiler\Lib\Defer\defer;
27
28
final class PhpReaderTraceLoop implements PhpReaderTraceLoopInterface
29
{
30
    public function __construct(
31
        private CallTraceReader $executor_globals_reader,
32
        private ReaderLoopProvider $reader_loop_provider,
33
        private ProcessStopper $process_stopper,
34
    ) {
35
    }
36
37
    /**
38
     * @return Generator<TraceMessage>
39
     * @throws \PhpProfiler\Lib\Elf\Parser\ElfParserException
40
     * @throws \PhpProfiler\Lib\Elf\Process\ProcessSymbolReaderException
41
     * @throws \PhpProfiler\Lib\Elf\Tls\TlsFinderException
42
     * @throws \PhpProfiler\Lib\Process\MemoryReader\MemoryReaderException
43
     */
44
    public function run(
45
        TraceLoopSettings $loop_settings,
46
        TargetProcessDescriptor $target_process_descriptor,
47
        GetTraceSettings $get_trace_settings
48
    ): Generator {
49
        $trace_cache = new TraceCache();
50
        $loop = $this->reader_loop_provider->getMainLoop(
51
            function () use (
52
                $get_trace_settings,
53
                $target_process_descriptor,
54
                $loop_settings,
55
                $trace_cache,
56
            ): Generator {
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected ')', expecting T_VARIABLE on line 56 at column 12
Loading history...
57
                if ($loop_settings->stop_process and $this->process_stopper->stop($target_process_descriptor->pid)) {
58
                    defer($_, fn () => $this->process_stopper->resume($target_process_descriptor->pid));
59
                }
60
                $call_trace = $this->executor_globals_reader->readCallTrace(
61
                    $target_process_descriptor->pid,
62
                    $target_process_descriptor->php_version,
63
                    $target_process_descriptor->eg_address,
64
                    $target_process_descriptor->sg_address,
65
                    $get_trace_settings->depth,
66
                    $trace_cache
67
                );
68
                if (is_null($call_trace)) {
69
                    return;
70
                }
71
                yield new TraceMessage($call_trace);
72
            },
73
            $loop_settings
74
        );
75
        /** @var Generator<TraceMessage> */
76
        $loop_process = $loop->invoke();
77
        yield from $loop_process;
78
    }
79
}
80