Skip to content

Commit a4bd83b

Browse files
committed
Convert resource to object in Sysvshm extension
1 parent 707cb18 commit a4bd83b

File tree

8 files changed

+135
-96
lines changed

8 files changed

+135
-96
lines changed

UPGRADING

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,12 @@ PHP 8.0 UPGRADE NOTES
398398
are now silently ignored. Previously, such properties would have been
399399
serialized as if they had the value NULL.
400400

401+
- Sysvshm:
402+
. shm_attach() will now return an Sysvshm object rather than a resource.
403+
Return value checks using is_resource() should be replaced with checks
404+
for `false`. The shm_detach() function no longer has an effect, instead
405+
the Sysvshm instance is automatically destroyed if it is no longer referenced.
406+
401407
- tidy:
402408
. The $use_include_path parameter, which was not used internally, has been
403409
removed from tidy_repair_string().

ext/sysvshm/php_sysvshm.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ extern zend_module_entry sysvshm_module_entry;
3838
# include <sys/shm.h>
3939
#endif
4040

41-
#define PHP_SHM_RSRC_NAME "sysvshm"
42-
4341
typedef struct {
4442
int le_shm;
4543
zend_long init_mem;
@@ -64,6 +62,7 @@ typedef struct {
6462
key_t key; /* key set by user */
6563
zend_long id; /* returned by shmget */
6664
sysvshm_chunk_head *ptr; /* memory address of shared memory */
65+
zend_object std;
6766
} sysvshm_shm;
6867

6968
PHP_MINIT_FUNCTION(sysvshm);

ext/sysvshm/sysvshm.c

Lines changed: 79 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,44 @@
3535
#include "ext/standard/info.h"
3636
#include "ext/standard/php_var.h"
3737
#include "zend_smart_str.h"
38+
#include "Zend/zend_interfaces.h"
3839
#include "php_ini.h"
3940

41+
/* Sysvshm class */
42+
43+
zend_class_entry *sysvshm_ce;
44+
static zend_object_handlers sysvshm_object_handlers;
45+
46+
static inline sysvshm_shm *sysvshm_from_obj(zend_object *obj) {
47+
return (sysvshm_shm *)((char *)(obj) - XtOffsetOf(sysvshm_shm, std));
48+
}
49+
50+
#define Z_SYSVSHM_P(zv) sysvshm_from_obj(Z_OBJ_P(zv))
51+
52+
static zend_object *sysvshm_create_object(zend_class_entry *class_type) {
53+
sysvshm_shm *intern = zend_object_alloc(sizeof(sysvshm_shm), class_type);
54+
55+
zend_object_std_init(&intern->std, class_type);
56+
object_properties_init(&intern->std, class_type);
57+
intern->std.handlers = &sysvshm_object_handlers;
58+
59+
return &intern->std;
60+
}
61+
62+
static zend_function *sysvshm_get_constructor(zend_object *object) {
63+
zend_throw_error(NULL, "Cannot directly construct Sysvshm, use shm_attach() instead");
64+
return NULL;
65+
}
66+
67+
static void sysvshm_free_obj(zend_object *object)
68+
{
69+
sysvshm_shm *sysvshm = sysvshm_from_obj(object);
70+
71+
shmdt((void *) sysvshm->ptr);
72+
73+
zend_object_std_dtor(&sysvshm->std);
74+
}
75+
4076
/* {{{ sysvshm_module_entry
4177
*/
4278
zend_module_entry sysvshm_module_entry = {
@@ -59,33 +95,29 @@ ZEND_GET_MODULE(sysvshm)
5995

6096
#undef shm_ptr /* undefine AIX-specific macro */
6197

62-
#define SHM_FETCH_RESOURCE(shm_ptr, z_ptr) do { \
63-
if ((shm_ptr = (sysvshm_shm *)zend_fetch_resource(Z_RES_P(z_ptr), PHP_SHM_RSRC_NAME, php_sysvshm.le_shm)) == NULL) { \
64-
RETURN_THROWS(); \
65-
} \
66-
} while (0)
67-
6898
THREAD_LS sysvshm_module php_sysvshm;
6999

70100
static int php_put_shm_data(sysvshm_chunk_head *ptr, zend_long key, const char *data, zend_long len);
71101
static zend_long php_check_shm_data(sysvshm_chunk_head *ptr, zend_long key);
72102
static int php_remove_shm_data(sysvshm_chunk_head *ptr, zend_long shm_varpos);
73103

74-
/* {{{ php_release_sysvshm
75-
*/
76-
static void php_release_sysvshm(zend_resource *rsrc)
77-
{
78-
sysvshm_shm *shm_ptr = (sysvshm_shm *) rsrc->ptr;
79-
shmdt((void *) shm_ptr->ptr);
80-
efree(shm_ptr);
81-
}
82-
/* }}} */
83-
84104
/* {{{ PHP_MINIT_FUNCTION
85105
*/
86106
PHP_MINIT_FUNCTION(sysvshm)
87107
{
88-
php_sysvshm.le_shm = zend_register_list_destructors_ex(php_release_sysvshm, NULL, PHP_SHM_RSRC_NAME, module_number);
108+
zend_class_entry ce;
109+
INIT_CLASS_ENTRY(ce, "Sysvshm", class_Sysvshm_methods);
110+
sysvshm_ce = zend_register_internal_class(&ce);
111+
sysvshm_ce->ce_flags |= ZEND_ACC_FINAL;
112+
sysvshm_ce->create_object = sysvshm_create_object;
113+
sysvshm_ce->serialize = zend_class_serialize_deny;
114+
sysvshm_ce->unserialize = zend_class_unserialize_deny;
115+
116+
memcpy(&sysvshm_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
117+
sysvshm_object_handlers.offset = XtOffsetOf(sysvshm_shm, std);
118+
sysvshm_object_handlers.free_obj = sysvshm_free_obj;
119+
sysvshm_object_handlers.get_constructor = sysvshm_get_constructor;
120+
sysvshm_object_handlers.clone_obj = NULL;
89121

90122
if (cfg_get_long("sysvshm.init_mem", &php_sysvshm.init_mem) == FAILURE) {
91123
php_sysvshm.init_mem=10000;
@@ -122,25 +154,25 @@ PHP_FUNCTION(shm_attach)
122154
RETURN_FALSE;
123155
}
124156

125-
shm_list_ptr = (sysvshm_shm *) emalloc(sizeof(sysvshm_shm));
157+
object_init_ex(return_value, sysvshm_ce);
126158

127159
/* get the id from a specified key or create new shared memory */
128160
if ((shm_id = shmget(shm_key, 0, 0)) < 0) {
129161
if (shm_size < (zend_long)sizeof(sysvshm_chunk_head)) {
130162
php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": memorysize too small", shm_key);
131-
efree(shm_list_ptr);
163+
zval_ptr_dtor(return_value);
132164
RETURN_FALSE;
133165
}
134166
if ((shm_id = shmget(shm_key, shm_size, shm_flag | IPC_CREAT | IPC_EXCL)) < 0) {
135167
php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": %s", shm_key, strerror(errno));
136-
efree(shm_list_ptr);
168+
zval_ptr_dtor(return_value);
137169
RETURN_FALSE;
138170
}
139171
}
140172

141173
if ((shm_ptr = shmat(shm_id, NULL, 0)) == (void *) -1) {
142174
php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": %s", shm_key, strerror(errno));
143-
efree(shm_list_ptr);
175+
zval_ptr_dtor(return_value);
144176
RETURN_FALSE;
145177
}
146178

@@ -154,40 +186,40 @@ PHP_FUNCTION(shm_attach)
154186
chunk_ptr->free = shm_size-chunk_ptr->end;
155187
}
156188

189+
shm_list_ptr = Z_SYSVSHM_P(return_value);
190+
157191
shm_list_ptr->key = shm_key;
158192
shm_list_ptr->id = shm_id;
159193
shm_list_ptr->ptr = chunk_ptr;
160-
161-
RETURN_RES(zend_register_resource(shm_list_ptr, php_sysvshm.le_shm));
162194
}
163195
/* }}} */
164196

165-
/* {{{ proto bool shm_detach(resource shm_identifier)
197+
/* {{{ proto bool shm_detach(Sysvshm shm_identifier)
166198
Disconnects from shared memory segment */
167199
PHP_FUNCTION(shm_detach)
168200
{
169201
zval *shm_id;
170-
sysvshm_shm *shm_list_ptr;
171202

172-
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "r", &shm_id)) {
203+
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "O", &shm_id, sysvshm_ce)) {
173204
RETURN_THROWS();
174205
}
175-
SHM_FETCH_RESOURCE(shm_list_ptr, shm_id);
176-
RETURN_BOOL(SUCCESS == zend_list_close(Z_RES_P(shm_id)));
206+
207+
RETURN_TRUE;
177208
}
178209
/* }}} */
179210

180-
/* {{{ proto bool shm_remove(resource shm_identifier)
211+
/* {{{ proto bool shm_remove(Sysvshm shm_identifier)
181212
Removes shared memory from Unix systems */
182213
PHP_FUNCTION(shm_remove)
183214
{
184215
zval *shm_id;
185216
sysvshm_shm *shm_list_ptr;
186217

187-
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "r", &shm_id)) {
218+
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "O", &shm_id, sysvshm_ce)) {
188219
RETURN_THROWS();
189220
}
190-
SHM_FETCH_RESOURCE(shm_list_ptr, shm_id);
221+
222+
shm_list_ptr = Z_SYSVSHM_P(shm_id);
191223

192224
if (shmctl(shm_list_ptr->id, IPC_RMID, NULL) < 0) {
193225
php_error_docref(NULL, E_WARNING, "Failed for key 0x%x, id " ZEND_LONG_FMT ": %s", shm_list_ptr->key, Z_LVAL_P(shm_id), strerror(errno));
@@ -198,7 +230,7 @@ PHP_FUNCTION(shm_remove)
198230
}
199231
/* }}} */
200232

201-
/* {{{ proto bool shm_put_var(resource shm_identifier, int variable_key, mixed variable)
233+
/* {{{ proto bool shm_put_var(Sysvshm shm_identifier, int variable_key, mixed variable)
202234
Inserts or updates a variable in shared memory */
203235
PHP_FUNCTION(shm_put_var)
204236
{
@@ -209,7 +241,7 @@ PHP_FUNCTION(shm_put_var)
209241
smart_str shm_var = {0};
210242
php_serialize_data_t var_hash;
211243

212-
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rlz", &shm_id, &shm_key, &arg_var)) {
244+
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "Olz", &shm_id, sysvshm_ce, &shm_key, &arg_var)) {
213245
RETURN_THROWS();
214246
}
215247

@@ -218,11 +250,7 @@ PHP_FUNCTION(shm_put_var)
218250
php_var_serialize(&shm_var, arg_var, &var_hash);
219251
PHP_VAR_SERIALIZE_DESTROY(var_hash);
220252

221-
shm_list_ptr = zend_fetch_resource(Z_RES_P(shm_id), PHP_SHM_RSRC_NAME, php_sysvshm.le_shm);
222-
if (!shm_list_ptr) {
223-
smart_str_free(&shm_var);
224-
RETURN_THROWS();
225-
}
253+
shm_list_ptr = Z_SYSVSHM_P(shm_id);
226254

227255
/* insert serialized variable into shared memory */
228256
ret = php_put_shm_data(shm_list_ptr->ptr, shm_key, shm_var.s? ZSTR_VAL(shm_var.s) : NULL, shm_var.s? ZSTR_LEN(shm_var.s) : 0);
@@ -238,7 +266,7 @@ PHP_FUNCTION(shm_put_var)
238266
}
239267
/* }}} */
240268

241-
/* {{{ proto mixed shm_get_var(resource id, int variable_key)
269+
/* {{{ proto mixed shm_get_var(Sysvshm id, int variable_key)
242270
Returns a variable from shared memory */
243271
PHP_FUNCTION(shm_get_var)
244272
{
@@ -250,10 +278,11 @@ PHP_FUNCTION(shm_get_var)
250278
sysvshm_chunk *shm_var;
251279
php_unserialize_data_t var_hash;
252280

253-
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &shm_id, &shm_key)) {
281+
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &shm_id, sysvshm_ce, &shm_key)) {
254282
RETURN_THROWS();
255283
}
256-
SHM_FETCH_RESOURCE(shm_list_ptr, shm_id);
284+
285+
shm_list_ptr = Z_SYSVSHM_P(shm_id);
257286

258287
/* setup string-variable and serialize */
259288
/* get serialized variable from shared memory */
@@ -275,34 +304,37 @@ PHP_FUNCTION(shm_get_var)
275304
}
276305
/* }}} */
277306

278-
/* {{{ proto bool shm_has_var(resource id, int variable_key)
307+
/* {{{ proto bool shm_has_var(Sysvshm id, int variable_key)
279308
Checks whether a specific entry exists */
280309
PHP_FUNCTION(shm_has_var)
281310
{
282311
zval *shm_id;
283312
zend_long shm_key;
284313
sysvshm_shm *shm_list_ptr;
285314

286-
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &shm_id, &shm_key)) {
315+
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &shm_id, sysvshm_ce, &shm_key)) {
287316
RETURN_THROWS();
288317
}
289-
SHM_FETCH_RESOURCE(shm_list_ptr, shm_id);
318+
319+
shm_list_ptr = Z_SYSVSHM_P(shm_id);
320+
290321
RETURN_BOOL(php_check_shm_data(shm_list_ptr->ptr, shm_key) >= 0);
291322
}
292323
/* }}} */
293324

294-
/* {{{ proto bool shm_remove_var(resource id, int variable_key)
325+
/* {{{ proto bool shm_remove_var(Sysvshm id, int variable_key)
295326
Removes variable from shared memory */
296327
PHP_FUNCTION(shm_remove_var)
297328
{
298329
zval *shm_id;
299330
zend_long shm_key, shm_varpos;
300331
sysvshm_shm *shm_list_ptr;
301332

302-
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &shm_id, &shm_key)) {
333+
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &shm_id, sysvshm_ce, &shm_key)) {
303334
RETURN_THROWS();
304335
}
305-
SHM_FETCH_RESOURCE(shm_list_ptr, shm_id);
336+
337+
shm_list_ptr = Z_SYSVSHM_P(shm_id);
306338

307339
shm_varpos = php_check_shm_data((shm_list_ptr->ptr), shm_key);
308340

ext/sysvshm/sysvshm.stub.php

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,22 @@
22

33
/** @generate-function-entries */
44

5-
/** @return resource|false */
6-
function shm_attach(int $key, int $memsize = UNKNOWN, int $perm = 0666) {}
7-
8-
/**
9-
* @param resource $shm_identifier
10-
*/
11-
function shm_detach($shm_identifier): bool {}
12-
13-
/**
14-
* @param resource $id
15-
*/
16-
function shm_has_var($id, int $variable_key): bool {}
17-
18-
/**
19-
* @param resource $shm_identifier
20-
*/
21-
function shm_remove($shm_identifier): bool {}
22-
23-
/**
24-
* @param resource $shm_identifier
25-
*/
26-
function shm_put_var($shm_identifier, int $variable_key, $variable): bool {}
27-
28-
/**
29-
* @param resource $id
30-
* @return mixed
31-
*/
32-
function shm_get_var($id, int $variable_key) {}
33-
34-
/**
35-
* @param resource $id
36-
*/
37-
function shm_remove_var($id, int $variable_key): bool {}
5+
final class Sysvshm
6+
{
7+
}
8+
9+
/** @return Sysvshm|false */
10+
function shm_attach(int $key, int $memsize = UNKNOWN, int $perm = 0666): Sysvshm|false {}
11+
12+
function shm_detach(Sysvshm $shm_identifier): bool {}
13+
14+
function shm_has_var(Sysvshm $id, int $variable_key): bool {}
15+
16+
function shm_remove(Sysvshm $shm_identifier): bool {}
17+
18+
function shm_put_var(Sysvshm $shm_identifier, int $variable_key, $variable): bool {}
19+
20+
/** @return mixed */
21+
function shm_get_var(Sysvshm $id, int $variable_key) {}
22+
23+
function shm_remove_var(Sysvshm $id, int $variable_key): bool {}

0 commit comments

Comments
 (0)