Skip to content

Commit e534ab2

Browse files
committed
Convert resource to object in Sysvshm extension
1 parent dd9d0a9 commit e534ab2

File tree

11 files changed

+148
-123
lines changed

11 files changed

+148
-123
lines changed

UPGRADING

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,12 @@ PHP 8.0 UPGRADE NOTES
421421
Return value checks using is_resource() should be replaced with checks
422422
for `false`.
423423

424+
- Sysvshm:
425+
. shm_attach() will now return an Sysvshm object rather than a resource.
426+
Return value checks using is_resource() should be replaced with checks
427+
for `false`. The shm_detach() function no longer has an effect, instead
428+
the Sysvshm instance is automatically destroyed if it is no longer referenced.
429+
424430
- tidy:
425431
. The $use_include_path parameter, which was not used internally, has been
426432
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.\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.
103103
Success acquire semaphore.
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 & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,7 @@ 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 {
44-
int le_shm;
4542
zend_long init_mem;
4643
} sysvshm_module;
4744

@@ -64,6 +61,7 @@ typedef struct {
6461
key_t key; /* key set by user */
6562
zend_long id; /* returned by shmget */
6663
sysvshm_chunk_head *ptr; /* memory address of shared memory */
64+
zend_object std;
6765
} sysvshm_shm;
6866

6967
PHP_MINIT_FUNCTION(sysvshm);

ext/sysvshm/sysvshm.c

Lines changed: 79 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,44 @@
2929
#include "ext/standard/info.h"
3030
#include "ext/standard/php_var.h"
3131
#include "zend_smart_str.h"
32+
#include "Zend/zend_interfaces.h"
3233
#include "php_ini.h"
3334

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

5490
#undef shm_ptr /* undefine AIX-specific macro */
5591

56-
#define SHM_FETCH_RESOURCE(shm_ptr, z_ptr) do { \
57-
if ((shm_ptr = (sysvshm_shm *)zend_fetch_resource(Z_RES_P(z_ptr), PHP_SHM_RSRC_NAME, php_sysvshm.le_shm)) == NULL) { \
58-
RETURN_THROWS(); \
59-
} \
60-
} while (0)
61-
6292
THREAD_LS sysvshm_module php_sysvshm;
6393

6494
static int php_put_shm_data(sysvshm_chunk_head *ptr, zend_long key, const char *data, zend_long len);
6595
static zend_long php_check_shm_data(sysvshm_chunk_head *ptr, zend_long key);
6696
static int php_remove_shm_data(sysvshm_chunk_head *ptr, zend_long shm_varpos);
6797

68-
/* {{{ php_release_sysvshm
69-
*/
70-
static void php_release_sysvshm(zend_resource *rsrc)
71-
{
72-
sysvshm_shm *shm_ptr = (sysvshm_shm *) rsrc->ptr;
73-
shmdt((void *) shm_ptr->ptr);
74-
efree(shm_ptr);
75-
}
76-
/* }}} */
77-
7898
/* {{{ PHP_MINIT_FUNCTION
7999
*/
80100
PHP_MINIT_FUNCTION(sysvshm)
81101
{
82-
php_sysvshm.le_shm = zend_register_list_destructors_ex(php_release_sysvshm, NULL, PHP_SHM_RSRC_NAME, module_number);
102+
zend_class_entry ce;
103+
INIT_CLASS_ENTRY(ce, "Sysvshm", class_Sysvshm_methods);
104+
sysvshm_ce = zend_register_internal_class(&ce);
105+
sysvshm_ce->ce_flags |= ZEND_ACC_FINAL;
106+
sysvshm_ce->create_object = sysvshm_create_object;
107+
sysvshm_ce->serialize = zend_class_serialize_deny;
108+
sysvshm_ce->unserialize = zend_class_unserialize_deny;
109+
110+
memcpy(&sysvshm_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
111+
sysvshm_object_handlers.offset = XtOffsetOf(sysvshm_shm, std);
112+
sysvshm_object_handlers.free_obj = sysvshm_free_obj;
113+
sysvshm_object_handlers.get_constructor = sysvshm_get_constructor;
114+
sysvshm_object_handlers.clone_obj = NULL;
83115

84116
if (cfg_get_long("sysvshm.init_mem", &php_sysvshm.init_mem) == FAILURE) {
85117
php_sysvshm.init_mem=10000;
@@ -116,25 +148,25 @@ PHP_FUNCTION(shm_attach)
116148
RETURN_FALSE;
117149
}
118150

119-
shm_list_ptr = (sysvshm_shm *) emalloc(sizeof(sysvshm_shm));
151+
object_init_ex(return_value, sysvshm_ce);
120152

121153
/* get the id from a specified key or create new shared memory */
122154
if ((shm_id = shmget(shm_key, 0, 0)) < 0) {
123155
if (shm_size < (zend_long)sizeof(sysvshm_chunk_head)) {
124156
php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": memorysize too small", shm_key);
125-
efree(shm_list_ptr);
157+
zval_ptr_dtor(return_value);
126158
RETURN_FALSE;
127159
}
128160
if ((shm_id = shmget(shm_key, shm_size, shm_flag | IPC_CREAT | IPC_EXCL)) < 0) {
129161
php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": %s", shm_key, strerror(errno));
130-
efree(shm_list_ptr);
162+
zval_ptr_dtor(return_value);
131163
RETURN_FALSE;
132164
}
133165
}
134166

135167
if ((shm_ptr = shmat(shm_id, NULL, 0)) == (void *) -1) {
136168
php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": %s", shm_key, strerror(errno));
137-
efree(shm_list_ptr);
169+
zval_ptr_dtor(return_value);
138170
RETURN_FALSE;
139171
}
140172

@@ -148,40 +180,40 @@ PHP_FUNCTION(shm_attach)
148180
chunk_ptr->free = shm_size-chunk_ptr->end;
149181
}
150182

183+
shm_list_ptr = Z_SYSVSHM_P(return_value);
184+
151185
shm_list_ptr->key = shm_key;
152186
shm_list_ptr->id = shm_id;
153187
shm_list_ptr->ptr = chunk_ptr;
154-
155-
RETURN_RES(zend_register_resource(shm_list_ptr, php_sysvshm.le_shm));
156188
}
157189
/* }}} */
158190

159-
/* {{{ proto bool shm_detach(resource shm_identifier)
191+
/* {{{ proto bool shm_detach(Sysvshm shm_identifier)
160192
Disconnects from shared memory segment */
161193
PHP_FUNCTION(shm_detach)
162194
{
163195
zval *shm_id;
164-
sysvshm_shm *shm_list_ptr;
165196

166-
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "r", &shm_id)) {
197+
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "O", &shm_id, sysvshm_ce)) {
167198
RETURN_THROWS();
168199
}
169-
SHM_FETCH_RESOURCE(shm_list_ptr, shm_id);
170-
RETURN_BOOL(SUCCESS == zend_list_close(Z_RES_P(shm_id)));
200+
201+
RETURN_TRUE;
171202
}
172203
/* }}} */
173204

174-
/* {{{ proto bool shm_remove(resource shm_identifier)
205+
/* {{{ proto bool shm_remove(Sysvshm shm_identifier)
175206
Removes shared memory from Unix systems */
176207
PHP_FUNCTION(shm_remove)
177208
{
178209
zval *shm_id;
179210
sysvshm_shm *shm_list_ptr;
180211

181-
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "r", &shm_id)) {
212+
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "O", &shm_id, sysvshm_ce)) {
182213
RETURN_THROWS();
183214
}
184-
SHM_FETCH_RESOURCE(shm_list_ptr, shm_id);
215+
216+
shm_list_ptr = Z_SYSVSHM_P(shm_id);
185217

186218
if (shmctl(shm_list_ptr->id, IPC_RMID, NULL) < 0) {
187219
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));
@@ -192,7 +224,7 @@ PHP_FUNCTION(shm_remove)
192224
}
193225
/* }}} */
194226

195-
/* {{{ proto bool shm_put_var(resource shm_identifier, int variable_key, mixed variable)
227+
/* {{{ proto bool shm_put_var(Sysvshm shm_identifier, int variable_key, mixed variable)
196228
Inserts or updates a variable in shared memory */
197229
PHP_FUNCTION(shm_put_var)
198230
{
@@ -203,7 +235,7 @@ PHP_FUNCTION(shm_put_var)
203235
smart_str shm_var = {0};
204236
php_serialize_data_t var_hash;
205237

206-
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rlz", &shm_id, &shm_key, &arg_var)) {
238+
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "Olz", &shm_id, sysvshm_ce, &shm_key, &arg_var)) {
207239
RETURN_THROWS();
208240
}
209241

@@ -212,11 +244,7 @@ PHP_FUNCTION(shm_put_var)
212244
php_var_serialize(&shm_var, arg_var, &var_hash);
213245
PHP_VAR_SERIALIZE_DESTROY(var_hash);
214246

215-
shm_list_ptr = zend_fetch_resource(Z_RES_P(shm_id), PHP_SHM_RSRC_NAME, php_sysvshm.le_shm);
216-
if (!shm_list_ptr) {
217-
smart_str_free(&shm_var);
218-
RETURN_THROWS();
219-
}
247+
shm_list_ptr = Z_SYSVSHM_P(shm_id);
220248

221249
/* insert serialized variable into shared memory */
222250
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);
@@ -232,7 +260,7 @@ PHP_FUNCTION(shm_put_var)
232260
}
233261
/* }}} */
234262

235-
/* {{{ proto mixed shm_get_var(resource id, int variable_key)
263+
/* {{{ proto mixed shm_get_var(Sysvshm id, int variable_key)
236264
Returns a variable from shared memory */
237265
PHP_FUNCTION(shm_get_var)
238266
{
@@ -244,10 +272,11 @@ PHP_FUNCTION(shm_get_var)
244272
sysvshm_chunk *shm_var;
245273
php_unserialize_data_t var_hash;
246274

247-
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &shm_id, &shm_key)) {
275+
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &shm_id, sysvshm_ce, &shm_key)) {
248276
RETURN_THROWS();
249277
}
250-
SHM_FETCH_RESOURCE(shm_list_ptr, shm_id);
278+
279+
shm_list_ptr = Z_SYSVSHM_P(shm_id);
251280

252281
/* setup string-variable and serialize */
253282
/* get serialized variable from shared memory */
@@ -269,34 +298,37 @@ PHP_FUNCTION(shm_get_var)
269298
}
270299
/* }}} */
271300

272-
/* {{{ proto bool shm_has_var(resource id, int variable_key)
301+
/* {{{ proto bool shm_has_var(Sysvshm id, int variable_key)
273302
Checks whether a specific entry exists */
274303
PHP_FUNCTION(shm_has_var)
275304
{
276305
zval *shm_id;
277306
zend_long shm_key;
278307
sysvshm_shm *shm_list_ptr;
279308

280-
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &shm_id, &shm_key)) {
309+
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &shm_id, sysvshm_ce, &shm_key)) {
281310
RETURN_THROWS();
282311
}
283-
SHM_FETCH_RESOURCE(shm_list_ptr, shm_id);
312+
313+
shm_list_ptr = Z_SYSVSHM_P(shm_id);
314+
284315
RETURN_BOOL(php_check_shm_data(shm_list_ptr->ptr, shm_key) >= 0);
285316
}
286317
/* }}} */
287318

288-
/* {{{ proto bool shm_remove_var(resource id, int variable_key)
319+
/* {{{ proto bool shm_remove_var(Sysvshm id, int variable_key)
289320
Removes variable from shared memory */
290321
PHP_FUNCTION(shm_remove_var)
291322
{
292323
zval *shm_id;
293324
zend_long shm_key, shm_varpos;
294325
sysvshm_shm *shm_list_ptr;
295326

296-
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &shm_id, &shm_key)) {
327+
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &shm_id, sysvshm_ce, &shm_key)) {
297328
RETURN_THROWS();
298329
}
299-
SHM_FETCH_RESOURCE(shm_list_ptr, shm_id);
330+
331+
shm_list_ptr = Z_SYSVSHM_P(shm_id);
300332

301333
shm_varpos = php_check_shm_data((shm_list_ptr->ptr), shm_key);
302334

0 commit comments

Comments
 (0)