Skip to content

Commit eab54d2

Browse files
committed
Convert resource to object in ext/sysvsem
Closes GH-5508
1 parent 776b1ae commit eab54d2

File tree

7 files changed

+122
-97
lines changed

7 files changed

+122
-97
lines changed

UPGRADING

+5
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,11 @@ PHP 8.0 UPGRADE NOTES
416416
explicit setlocale() call is now always required if you wish to change any
417417
locale component from the default.
418418

419+
- Sysvsem:
420+
. sem_get() will now return an Sysvsem object rather than a resource.
421+
Return value checks using is_resource() should be replaced with checks
422+
for `false`.
423+
419424
- tidy:
420425
. The $use_include_path parameter, which was not used internally, has been
421426
removed from tidy_repair_string().

ext/sysvsem/php_sysvsem.h

+1-11
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,15 @@ extern zend_module_entry sysvsem_module_entry;
2727

2828
PHP_MINIT_FUNCTION(sysvsem);
2929
PHP_MINFO_FUNCTION(sysvsem);
30-
PHP_FUNCTION(sem_get);
31-
PHP_FUNCTION(sem_acquire);
32-
PHP_FUNCTION(sem_release);
33-
PHP_FUNCTION(sem_remove);
3430

3531
typedef struct {
36-
int le_sem;
37-
} sysvsem_module;
38-
39-
typedef struct {
40-
int id; /* For error reporting. */
4132
int key; /* For error reporting. */
4233
int semid; /* Returned by semget(). */
4334
int count; /* Acquire count for auto-release. */
4435
int auto_release; /* flag that says to auto-release. */
36+
zend_object std;
4537
} sysvsem_sem;
4638

47-
extern sysvsem_module php_sysvsem_module;
48-
4939
#else
5040

5141
#define sysvsem_module_ptr NULL

ext/sysvsem/sysvsem.c

+60-29
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "sysvsem_arginfo.h"
4040
#include "php_sysvsem.h"
4141
#include "ext/standard/info.h"
42+
#include "Zend/zend_interfaces.h"
4243

4344
#if !HAVE_SEMUN
4445

@@ -74,9 +75,6 @@ zend_module_entry sysvsem_module_entry = {
7475
ZEND_GET_MODULE(sysvsem)
7576
#endif
7677

77-
78-
THREAD_LS sysvsem_module php_sysvsem_module;
79-
8078
/* Semaphore functions using System V semaphores. Each semaphore
8179
* actually consists of three semaphores allocated as a unit under the
8280
* same key. Semaphore 0 (SYSVSEM_SEM) is the actual semaphore, it is
@@ -96,11 +94,35 @@ THREAD_LS sysvsem_module php_sysvsem_module;
9694
#define SYSVSEM_USAGE 1
9795
#define SYSVSEM_SETVAL 2
9896

99-
/* {{{ release_sysvsem_sem
100-
*/
101-
static void release_sysvsem_sem(zend_resource *rsrc)
97+
/* Sysvsem class */
98+
99+
zend_class_entry *sysvsem_ce;
100+
static zend_object_handlers sysvsem_object_handlers;
101+
102+
static inline sysvsem_sem *sysvsem_from_obj(zend_object *obj) {
103+
return (sysvsem_sem *)((char *)(obj) - XtOffsetOf(sysvsem_sem, std));
104+
}
105+
106+
#define Z_SYSVSEM_P(zv) sysvsem_from_obj(Z_OBJ_P(zv))
107+
108+
static zend_object *sysvsem_create_object(zend_class_entry *class_type) {
109+
sysvsem_sem *intern = zend_object_alloc(sizeof(sysvsem_sem), class_type);
110+
111+
zend_object_std_init(&intern->std, class_type);
112+
object_properties_init(&intern->std, class_type);
113+
intern->std.handlers = &sysvsem_object_handlers;
114+
115+
return &intern->std;
116+
}
117+
118+
static zend_function *sysvsem_get_constructor(zend_object *object) {
119+
zend_throw_error(NULL, "Cannot directly construct Sysvsem, use sem_get() instead");
120+
return NULL;
121+
}
122+
123+
static void sysvsem_free_obj(zend_object *object)
102124
{
103-
sysvsem_sem *sem_ptr = (sysvsem_sem *)rsrc->ptr;
125+
sysvsem_sem *sem_ptr = sysvsem_from_obj(object);
104126
struct sembuf sop[2];
105127
int opcount = 1;
106128
/*
@@ -130,15 +152,29 @@ static void release_sysvsem_sem(zend_resource *rsrc)
130152
}
131153

132154
semop(sem_ptr->semid, sop, opcount);
133-
efree(sem_ptr);
155+
156+
zend_object_std_dtor(&sem_ptr->std);
134157
}
135158
/* }}} */
136159

137160
/* {{{ PHP_MINIT_FUNCTION
138161
*/
139162
PHP_MINIT_FUNCTION(sysvsem)
140163
{
141-
php_sysvsem_module.le_sem = zend_register_list_destructors_ex(release_sysvsem_sem, NULL, "sysvsem", module_number);
164+
zend_class_entry ce;
165+
INIT_CLASS_ENTRY(ce, "Sysvsem", class_Sysvsem_methods);
166+
sysvsem_ce = zend_register_internal_class(&ce);
167+
sysvsem_ce->ce_flags |= ZEND_ACC_FINAL;
168+
sysvsem_ce->create_object = sysvsem_create_object;
169+
sysvsem_ce->serialize = zend_class_serialize_deny;
170+
sysvsem_ce->unserialize = zend_class_unserialize_deny;
171+
172+
memcpy(&sysvsem_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
173+
sysvsem_object_handlers.offset = XtOffsetOf(sysvsem_sem, std);
174+
sysvsem_object_handlers.free_obj = sysvsem_free_obj;
175+
sysvsem_object_handlers.get_constructor = sysvsem_get_constructor;
176+
sysvsem_object_handlers.clone_obj = NULL;
177+
142178
return SUCCESS;
143179
}
144180
/* }}} */
@@ -159,7 +195,7 @@ PHP_MINFO_FUNCTION(sysvsem)
159195
#undef SETVAL_WANTS_PTR
160196
#endif
161197

162-
/* {{{ proto resource sem_get(int key [, int max_acquire [, int perm [, int auto_release]])
198+
/* {{{ proto Sysvsem sem_get(int key [, int max_acquire [, int perm [, int auto_release]])
163199
Return an id for the semaphore with the given key, and allow max_acquire (default 1) processes to acquire it simultaneously */
164200
PHP_FUNCTION(sem_get)
165201
{
@@ -259,14 +295,13 @@ PHP_FUNCTION(sem_get)
259295
}
260296
}
261297

262-
sem_ptr = (sysvsem_sem *) emalloc(sizeof(sysvsem_sem));
298+
object_init_ex(return_value, sysvsem_ce);
299+
300+
sem_ptr = Z_SYSVSEM_P(return_value);
263301
sem_ptr->key = key;
264302
sem_ptr->semid = semid;
265303
sem_ptr->count = 0;
266304
sem_ptr->auto_release = auto_release;
267-
268-
RETVAL_RES(zend_register_resource(sem_ptr, php_sysvsem_module.le_sem));
269-
sem_ptr->id = Z_RES_HANDLE_P(return_value);
270305
}
271306
/* }}} */
272307

@@ -280,21 +315,19 @@ static void php_sysvsem_semop(INTERNAL_FUNCTION_PARAMETERS, int acquire)
280315
struct sembuf sop;
281316

282317
if (acquire) {
283-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|b", &arg_id, &nowait) == FAILURE) {
318+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|b", &arg_id, sysvsem_ce, &nowait) == FAILURE) {
284319
RETURN_THROWS();
285320
}
286321
} else {
287-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg_id) == FAILURE) {
322+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &arg_id, sysvsem_ce) == FAILURE) {
288323
RETURN_THROWS();
289324
}
290325
}
291326

292-
if ((sem_ptr = (sysvsem_sem *)zend_fetch_resource(Z_RES_P(arg_id), "SysV semaphore", php_sysvsem_module.le_sem)) == NULL) {
293-
RETURN_THROWS();
294-
}
327+
sem_ptr = Z_SYSVSEM_P(arg_id);
295328

296329
if (!acquire && sem_ptr->count == 0) {
297-
php_error_docref(NULL, E_WARNING, "SysV semaphore " ZEND_LONG_FMT " (key 0x%x) is not currently acquired", Z_LVAL_P(arg_id), sem_ptr->key);
330+
php_error_docref(NULL, E_WARNING, "SysV semaphore for key 0x%x is not currently acquired", sem_ptr->key);
298331
RETURN_FALSE;
299332
}
300333

@@ -316,23 +349,23 @@ static void php_sysvsem_semop(INTERNAL_FUNCTION_PARAMETERS, int acquire)
316349
}
317350
/* }}} */
318351

319-
/* {{{ proto bool sem_acquire(resource id)
352+
/* {{{ proto bool sem_acquire(Sysvsem id)
320353
Acquires the semaphore with the given id, blocking if necessary */
321354
PHP_FUNCTION(sem_acquire)
322355
{
323356
php_sysvsem_semop(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
324357
}
325358
/* }}} */
326359

327-
/* {{{ proto bool sem_release(resource id)
360+
/* {{{ proto bool sem_release(Sysvsem id)
328361
Releases the semaphore with the given id */
329362
PHP_FUNCTION(sem_release)
330363
{
331364
php_sysvsem_semop(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
332365
}
333366
/* }}} */
334367

335-
/* {{{ proto bool sem_remove(resource id)
368+
/* {{{ proto bool sem_remove(Sysvsem id)
336369
Removes semaphore from Unix systems */
337370

338371
/*
@@ -349,21 +382,19 @@ PHP_FUNCTION(sem_remove)
349382
struct semid_ds buf;
350383
#endif
351384

352-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg_id) == FAILURE) {
385+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &arg_id, sysvsem_ce) == FAILURE) {
353386
RETURN_THROWS();
354387
}
355388

356-
if ((sem_ptr = (sysvsem_sem *)zend_fetch_resource(Z_RES_P(arg_id), "SysV semaphore", php_sysvsem_module.le_sem)) == NULL) {
357-
RETURN_THROWS();
358-
}
389+
sem_ptr = Z_SYSVSEM_P(arg_id);
359390

360391
#if HAVE_SEMUN
361392
un.buf = &buf;
362393
if (semctl(sem_ptr->semid, 0, IPC_STAT, un) < 0) {
363394
#else
364395
if (semctl(sem_ptr->semid, 0, IPC_STAT, NULL) < 0) {
365396
#endif
366-
php_error_docref(NULL, E_WARNING, "SysV semaphore " ZEND_LONG_FMT " does not (any longer) exist", Z_LVAL_P(arg_id));
397+
php_error_docref(NULL, E_WARNING, "SysV semaphore for key 0x%x does not (any longer) exist", sem_ptr->key);
367398
RETURN_FALSE;
368399
}
369400

@@ -372,7 +403,7 @@ PHP_FUNCTION(sem_remove)
372403
#else
373404
if (semctl(sem_ptr->semid, 0, IPC_RMID, NULL) < 0) {
374405
#endif
375-
php_error_docref(NULL, E_WARNING, "Failed for SysV semaphore " ZEND_LONG_FMT ": %s", Z_LVAL_P(arg_id), strerror(errno));
406+
php_error_docref(NULL, E_WARNING, "Failed for SysV semaphore for key 0x%x: %s", sem_ptr->key, strerror(errno));
376407
RETURN_FALSE;
377408
}
378409

ext/sysvsem/sysvsem.stub.php

+8-14
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,17 @@
22

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

5+
final class Sysvsem
6+
{
7+
}
8+
59
/**
610
* @todo use bool for $auto_release
7-
* @return resource|false
811
*/
9-
function sem_get(int $key, int $max_acquire = 1, int $perm = 0666, int $auto_release = 1) {}
12+
function sem_get(int $key, int $max_acquire = 1, int $perm = 0666, int $auto_release = 1): Sysvsem|false {}
1013

11-
/**
12-
* @param resource $sem_identifier
13-
*/
14-
function sem_acquire($sem_identifier, bool $nowait = false): bool {}
14+
function sem_acquire(Sysvsem $sem_identifier, bool $nowait = false): bool {}
1515

16-
/**
17-
* @param resource $sem_identifier
18-
*/
19-
function sem_release($sem_identifier): bool {}
16+
function sem_release(Sysvsem $sem_identifier): bool {}
2017

21-
/**
22-
* @param resource $sem_identifier
23-
*/
24-
function sem_remove($sem_identifier): bool {}
18+
function sem_remove(Sysvsem $sem_identifier): bool {}

ext/sysvsem/sysvsem_arginfo.h

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
/* This is a generated file, edit the .stub.php file instead. */
22

3-
ZEND_BEGIN_ARG_INFO_EX(arginfo_sem_get, 0, 0, 1)
3+
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_sem_get, 0, 1, Sysvsem, MAY_BE_FALSE)
44
ZEND_ARG_TYPE_INFO(0, key, IS_LONG, 0)
55
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, max_acquire, IS_LONG, 0, "1")
66
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, perm, IS_LONG, 0, "0666")
77
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, auto_release, IS_LONG, 0, "1")
88
ZEND_END_ARG_INFO()
99

1010
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sem_acquire, 0, 1, _IS_BOOL, 0)
11-
ZEND_ARG_INFO(0, sem_identifier)
11+
ZEND_ARG_OBJ_INFO(0, sem_identifier, Sysvsem, 0)
1212
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, nowait, _IS_BOOL, 0, "false")
1313
ZEND_END_ARG_INFO()
1414

1515
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sem_release, 0, 1, _IS_BOOL, 0)
16-
ZEND_ARG_INFO(0, sem_identifier)
16+
ZEND_ARG_OBJ_INFO(0, sem_identifier, Sysvsem, 0)
1717
ZEND_END_ARG_INFO()
1818

1919
#define arginfo_sem_remove arginfo_sem_release
@@ -32,3 +32,8 @@ static const zend_function_entry ext_functions[] = {
3232
ZEND_FE(sem_remove, arginfo_sem_remove)
3333
ZEND_FE_END
3434
};
35+
36+
37+
static const zend_function_entry class_Sysvsem_methods[] = {
38+
ZEND_FE_END
39+
};

0 commit comments

Comments
 (0)