Skip to content

Commit 14ed430

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

File tree

11 files changed

+150
-122
lines changed

11 files changed

+150
-122
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/sysvsem/tests/sysv.phpt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ if (! sem_acquire($sem_id)) {
2929
}
3030
echo "Success acquire semaphore $sem_id.\n";
3131

32-
$shm_id = shm_attach($SHMKEY, $MEMSIZE);
32+
$shm_id = shm_attach($SHMKEY, $MEMSIZE);
3333
if ($shm_id === FALSE) {
3434
echo "Fail to attach shared memory.\n";
3535
sem_remove($sem_id);
3636
exit;
3737
}
38-
echo "Success to attach shared memory : $shm_id.\n";
38+
echo "Success to attach shared memory\n";
3939

4040
// Write variable 1
4141
if (!shm_put_var($shm_id, 1, "Variable 1")) {
@@ -48,7 +48,7 @@ echo "Write var1 to shared memory.\n";
4848

4949
// Write variable 2
5050
if (!shm_put_var($shm_id, 2, "Variable 2")) {
51-
echo "Fail to put var 2 on shared memory $shm_id.\n";
51+
echo "Fail to put var 2 on shared memory.\n";
5252
sem_remove($sem_id);
5353
shm_remove ($shm_id);
5454
exit;
@@ -58,15 +58,15 @@ echo "Write var2 to shared memory.\n";
5858
// Read variable 1
5959
$var1 = shm_get_var ($shm_id, 1);
6060
if ($var1 === FALSE) {
61-
echo "Fail to retrieve Var 1 from Shared memory $shm_id, return value=$var1.\n";
61+
echo "Fail to retrieve Var 1 from Shared memory, return value=$var1.\n";
6262
} else {
6363
echo "Read var1=$var1.\n";
6464
}
6565

6666
// Read variable 1
6767
$var2 = shm_get_var ($shm_id, 2);
6868
if ($var1 === FALSE) {
69-
echo "Fail to retrieve Var 2 from Shared memory $shm_id, return value=$var2.\n";
69+
echo "Fail to retrieve Var 2 from Shared memory, return value=$var2.\n";
7070
} else {
7171
echo "Read var2=$var2.\n";
7272
}
@@ -81,7 +81,7 @@ if (!sem_release($sem_id)) {
8181
if (shm_remove ($shm_id)) {
8282
echo "Shared memory successfully removed from SysV.\n";
8383
} else {
84-
echo "Fail to remove $shm_id shared memory from SysV.\n";
84+
echo "Fail to remove shared memory from SysV.\n";
8585
}
8686

8787
// Remove semaphore
@@ -101,7 +101,7 @@ echo "End.\n";
101101
Start.
102102
Got semaphore Resource id #%i.
103103
Success acquire semaphore Resource id #%i.
104-
Success to attach shared memory : %s.
104+
Success to attach shared memory.
105105
Write var1 to shared memory.
106106
Write var2 to shared memory.
107107
Read var1=Variable 1.

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

0 commit comments

Comments
 (0)