Completed
Pull Request — master (#229)
by Дмитрий
04:18
created

ShmEntity::read()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 24
Code Lines 17

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 24
rs 8.5125
cc 6
eloc 17
nc 8
nop 2
1
<?php
2
namespace PHPDaemon\Utils;
3
4
use PHPDaemon\Core\Daemon;
5
6
/**
7
 * ShmEntity
8
 * @package PHPDaemon\Utils
9
 * @author  Vasily Zorin <[email protected]>
10
 */
11
class ShmEntity {
12
	use \PHPDaemon\Traits\ClassWatchdog;
13
	use \PHPDaemon\Traits\StaticObjectWatchdog;
14
15
	/**
16
	 * @var string Path
17
	 */
18
	protected $path;
19
20
	/**
21
	 * @var array Segments
22
	 */
23
	protected $segments = [];
24
25
	/**
26
	 * @var integer Segment size
27
	 */
28
	protected $segsize = 1024;
29
30
	/**
31
	 * @var string Name
32
	 */
33
	protected $name;
34
35
	/**
36
	 * @var integer Key
37
	 */
38
	protected $key;
39
40
	/**
41
	 * Constructor
42
	 * @param string  $path    Path
43
	 * @param integer $segsize Segment size
44
	 * @param string  $name    Name
45
	 * @param boolean $create  Create
46
	 */
47
	public function __construct($path, $segsize, $name, $create = false) {
48
		$this->path    = $path;
49
		$this->segsize = $segsize;
50
		$this->name    = $name;
51
		if ($create && !touch($this->path)) {
52
			Daemon::log('Couldn\'t touch IPC file \'' . $this->path . '\'.');
53
			exit(0);
54
		}
55
56
		if (!is_file($this->path) || ($this->key = ftok($this->path, 't')) === false) {
57
			Daemon::log('Couldn\'t ftok() IPC file \'' . $this->path . '\'.');
58
			exit(0);
59
		}
60
		if (!$this->open(0, $create) && $create) {
61
			Daemon::log('Couldn\'t open IPC-' . $this->name . '  shared memory segment (key=' . $this->key . ', segsize=' . $this->segsize . ', uid=' . posix_getuid() . ', path = ' . $this->path . ').');
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 194 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
62
			exit(0);
63
		}
64
	}
65
66
	/**
67
	 * Opens segment of shared memory
68
	 * @param  integer $segno  Segment number
69
	 * @param  boolean $create Create
70
	 * @return integer         Segment number
71
	 */
72
	public function open($segno = 0, $create = false) {
73
		if (isset($this->segments[$segno])) {
74
			return $this->segments[$segno];
75
		}
76
		$key = $this->key + $segno;
77
		if (!$create) {
78
			$shm = @shmop_open($key, 'w', 0, 0);
79
		}
80
		else {
81
			$shm = @shmop_open($key, 'w', 0, 0);
82
83
			if ($shm) {
84
				shmop_delete($shm);
85
				shmop_close($shm);
86
			}
87
88
			$shm = shmop_open($key, 'c', 0755, $this->segsize);
89
		}
90
		if (!$shm) {
91
			return false;
92
		}
93
		$this->segments[$segno] = $shm;
94
		return $shm;
95
	}
96
97
	/**
98
	 * Get open segments
99
	 * @return array
100
	 */
101
	public function getSegments() {
102
		return $this->segments;
103
	}
104
105
	/**
106
	 * Open all segments
107
	 * @return void
108
	 */
109
	public function openall() {
110
		do {
111
			$r = $this->open(sizeof($this->segments));
112
		} while ($r);
113
	}
114
115
	/**
116
	 * Write to shared memory
117
	 * @param  string  $data   Data
118
	 * @param  integer $offset Offset
119
	 * @return boolean         Success
120
	 */
121
	public function write($data, $offset) {
122
		$segno = floor($offset / $this->segsize);
123
		if (!isset($this->segments[$segno])) {
124
			if (!$this->open($segno, true)) {
125
				return false;
126
			}
127
		}
128
		$sOffset = $offset % $this->segsize;
129
		$d = $this->segsize - ($sOffset +mb_orig_strlen$data));
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_VARIABLE
Loading history...
130
		if ($d < 0) {
131
			$this->write(mb_orig_substr($data, $d), ($segno+1) * $this->segsize);
132
			$data = mb_orig_substr($data, 0, $d);
133
		}
134
		//Daemon::log('writing to #'.$offset.' (segno '.$segno.')');
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
135
		shmop_write($this->segments[$segno], $data, $sOffset);
136
		return true;
137
	}
138
139
	/**
140
	 * Read from shared memory
141
	 * @param  integer $offset Offset
142
	 * @param  integer $length Length
143
	 * @return string          Data
144
	 */
145
	public function read($offset, $length = 1) {
146
		$ret = '';
147
		$segno = floor($offset / $this->segsize);
148
		$sOffset = $offset % $this->segsize;
149
		for (;;++$segno) {
150
			if (!isset($this->segments[$segno])) {
151
				if (!$this->open($segno)) {
152
					goto ret;
153
				}
154
			}
155
			$read = shmop_read($this->segments[$segno], $sOffset, min($length -mb_orig_strlen$ret), $this->segsize));
156
			//Daemon::log('read '.strlen($read).' from segno #'.$segno);
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
157
			$ret .= $read;
158
			if (strlen($ret) >= $length) {
159
				goto ret;
160
			}
161
			$sOffset = 0;
162
		}
163
		ret: 
164
		if ($ret === '') {
165
			return false;
166
		}
167
		return $ret;
168
	}
169
170
	/**
171
	 * Deletes all segments
172
	 * @return void
173
	 */
174
	public function delete() {
175
		foreach ($this->segments as $shm) {
176
			shmop_delete($shm);
177
		}
178
	}
179
}
180
181