ForkingIterator::rewind()   B
last analyzed

Complexity

Conditions 7
Paths 10

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 8.5866
c 0
b 0
f 0
cc 7
nc 10
nop 0
1
<?php
2
3
namespace itertools;
4
5
use UnexpectedValueException;
6
use IteratorIterator;
7
use ArrayIterator;
8
9
10
class ForkingIterator extends IteratorIterator
11
{
12
	const IS_CHILD = 0;
13
	const ENABLED = true;
14
	const DISABLED = false;
15
16
	protected $isChild = false;
17
	protected $childCount = 0;
18
	protected $forkingEnabled;
19
	protected $maxChildren;
20
21
	public function __construct($innerIterator, $options = array())
22
	{
23
		parent::__construct(IterUtil::asTraversable($innerIterator));
24
		$this->forkingEnabled = array_key_exists('forkingEnabled', $options) ? $options['forkingEnabled'] : self::ENABLED;
25
		$this->maxChildren = array_key_exists('maxChildren', $options) ? $options['maxChildren'] : 8;
26
	}
27
28
	public static function supportsFork()
29
	{
30
		return function_exists('pcntl_fork');
31
	}
32
33
	public function isForkingEnabled()
34
	{
35
		return $this->forkingEnabled && self::supportsFork();
36
	}
37
38
	protected function fork()
39
	{
40
		$pid = pcntl_fork();
41
		if($pid == -1) {
42
			throw new UnexpectedValueException('Could not fork');
43
		}
44
		if($pid == self::IS_CHILD) {
45
			$this->isChild = true;
46
		}
47
		$this->childCount += 1;
48
		return $pid;
49
	}
50
51
	protected function wait()
52
	{
53
		pcntl_wait($status);
0 ignored issues
show
Bug introduced by
The variable $status does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
54
		$this->childCount -= 1;
55
		return $status;
56
	}
57
58
	public function rewind()
59
	{
60
		if(!$this->isForkingEnabled()) {
61
			return parent::rewind();
62
		}
63
64
		parent::rewind();
65
		$status = 0;
66
		do {
67
			if($this->fork() == self::IS_CHILD) {
68
				return;
69
			}
70
			while($this->childCount >= $this->maxChildren) {
71
				$status |= $this->wait();
72
			}
73
			parent::next();
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (next() instead of rewind()). Are you sure this is correct? If so, you might want to change this to $this->next().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
74
		} while(parent::valid());
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (valid() instead of rewind()). Are you sure this is correct? If so, you might want to change this to $this->valid().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
75
76
		while($this->childCount > 0) {
77
			$status |= $this->wait();
78
		}
79
		if($status !== 0) {
80
			throw new UnexpectedValueException('Child exited with non zero status');
81
		}
82
	}
83
84
	public function valid()
85
	{
86
		if(!$this->isForkingEnabled()) {
87
			return parent::valid();
88
		}
89
		if(!$this->isChild) {
90
			return false;
91
		}
92
		return parent::valid();
93
	}
94
95
	public function next()
96
	{
97
		if(!$this->isForkingEnabled()) {
98
			return parent::next();
99
		}
100
		exit;
101
	}
102
}
103
104