Skip to content

Convert resource to object in ext/sysvsem #5508

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,11 @@ PHP 8.0 UPGRADE NOTES
explicit setlocale() call is now always required if you wish to change any
locale component from the default.

- Sysvsem:
. sem_get() will now return an Sysvsem object rather than a resource.
Return value checks using is_resource() should be replaced with checks
for `false`.

- tidy:
. The $use_include_path parameter, which was not used internally, has been
removed from tidy_repair_string().
Expand Down
12 changes: 1 addition & 11 deletions ext/sysvsem/php_sysvsem.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,15 @@ extern zend_module_entry sysvsem_module_entry;

PHP_MINIT_FUNCTION(sysvsem);
PHP_MINFO_FUNCTION(sysvsem);
PHP_FUNCTION(sem_get);
PHP_FUNCTION(sem_acquire);
PHP_FUNCTION(sem_release);
PHP_FUNCTION(sem_remove);

typedef struct {
int le_sem;
} sysvsem_module;

typedef struct {
int id; /* For error reporting. */
int key; /* For error reporting. */
int semid; /* Returned by semget(). */
int count; /* Acquire count for auto-release. */
int auto_release; /* flag that says to auto-release. */
zend_object std;
} sysvsem_sem;

extern sysvsem_module php_sysvsem_module;

#else

#define sysvsem_module_ptr NULL
Expand Down
89 changes: 60 additions & 29 deletions ext/sysvsem/sysvsem.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "sysvsem_arginfo.h"
#include "php_sysvsem.h"
#include "ext/standard/info.h"
#include "Zend/zend_interfaces.h"

#if !HAVE_SEMUN

Expand Down Expand Up @@ -74,9 +75,6 @@ zend_module_entry sysvsem_module_entry = {
ZEND_GET_MODULE(sysvsem)
#endif


THREAD_LS sysvsem_module php_sysvsem_module;

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

/* {{{ release_sysvsem_sem
*/
static void release_sysvsem_sem(zend_resource *rsrc)
/* Sysvsem class */

zend_class_entry *sysvsem_ce;
static zend_object_handlers sysvsem_object_handlers;

static inline sysvsem_sem *sysvsem_from_obj(zend_object *obj) {
return (sysvsem_sem *)((char *)(obj) - XtOffsetOf(sysvsem_sem, std));
}

#define Z_SYSVSEM_P(zv) sysvsem_from_obj(Z_OBJ_P(zv))

static zend_object *sysvsem_create_object(zend_class_entry *class_type) {
sysvsem_sem *intern = zend_object_alloc(sizeof(sysvsem_sem), class_type);

zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);
intern->std.handlers = &sysvsem_object_handlers;

return &intern->std;
}

static zend_function *sysvsem_get_constructor(zend_object *object) {
zend_throw_error(NULL, "Cannot directly construct Sysvsem, use sem_get() instead");
return NULL;
}

static void sysvsem_free_obj(zend_object *object)
{
sysvsem_sem *sem_ptr = (sysvsem_sem *)rsrc->ptr;
sysvsem_sem *sem_ptr = sysvsem_from_obj(object);
struct sembuf sop[2];
int opcount = 1;
/*
Expand Down Expand Up @@ -130,15 +152,29 @@ static void release_sysvsem_sem(zend_resource *rsrc)
}

semop(sem_ptr->semid, sop, opcount);
efree(sem_ptr);

zend_object_std_dtor(&sem_ptr->std);
}
/* }}} */

/* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(sysvsem)
{
php_sysvsem_module.le_sem = zend_register_list_destructors_ex(release_sysvsem_sem, NULL, "sysvsem", module_number);
zend_class_entry ce;
INIT_CLASS_ENTRY(ce, "Sysvsem", class_Sysvsem_methods);
sysvsem_ce = zend_register_internal_class(&ce);
sysvsem_ce->ce_flags |= ZEND_ACC_FINAL;
sysvsem_ce->create_object = sysvsem_create_object;
sysvsem_ce->serialize = zend_class_serialize_deny;
sysvsem_ce->unserialize = zend_class_unserialize_deny;

memcpy(&sysvsem_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
sysvsem_object_handlers.offset = XtOffsetOf(sysvsem_sem, std);
sysvsem_object_handlers.free_obj = sysvsem_free_obj;
sysvsem_object_handlers.get_constructor = sysvsem_get_constructor;
sysvsem_object_handlers.clone_obj = NULL;

return SUCCESS;
}
/* }}} */
Expand All @@ -159,7 +195,7 @@ PHP_MINFO_FUNCTION(sysvsem)
#undef SETVAL_WANTS_PTR
#endif

/* {{{ proto resource sem_get(int key [, int max_acquire [, int perm [, int auto_release]])
/* {{{ proto Sysvsem sem_get(int key [, int max_acquire [, int perm [, int auto_release]])
Return an id for the semaphore with the given key, and allow max_acquire (default 1) processes to acquire it simultaneously */
PHP_FUNCTION(sem_get)
{
Expand Down Expand Up @@ -259,14 +295,13 @@ PHP_FUNCTION(sem_get)
}
}

sem_ptr = (sysvsem_sem *) emalloc(sizeof(sysvsem_sem));
object_init_ex(return_value, sysvsem_ce);

sem_ptr = Z_SYSVSEM_P(return_value);
sem_ptr->key = key;
sem_ptr->semid = semid;
sem_ptr->count = 0;
sem_ptr->auto_release = auto_release;

RETVAL_RES(zend_register_resource(sem_ptr, php_sysvsem_module.le_sem));
sem_ptr->id = Z_RES_HANDLE_P(return_value);
}
/* }}} */

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

if (acquire) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|b", &arg_id, &nowait) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|b", &arg_id, sysvsem_ce, &nowait) == FAILURE) {
RETURN_THROWS();
}
} else {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg_id) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &arg_id, sysvsem_ce) == FAILURE) {
RETURN_THROWS();
}
}

if ((sem_ptr = (sysvsem_sem *)zend_fetch_resource(Z_RES_P(arg_id), "SysV semaphore", php_sysvsem_module.le_sem)) == NULL) {
RETURN_THROWS();
}
sem_ptr = Z_SYSVSEM_P(arg_id);

if (!acquire && sem_ptr->count == 0) {
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);
php_error_docref(NULL, E_WARNING, "SysV semaphore for key 0x%x is not currently acquired", sem_ptr->key);
RETURN_FALSE;
}

Expand All @@ -316,23 +349,23 @@ static void php_sysvsem_semop(INTERNAL_FUNCTION_PARAMETERS, int acquire)
}
/* }}} */

/* {{{ proto bool sem_acquire(resource id)
/* {{{ proto bool sem_acquire(Sysvsem id)
Acquires the semaphore with the given id, blocking if necessary */
PHP_FUNCTION(sem_acquire)
{
php_sysvsem_semop(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
}
/* }}} */

/* {{{ proto bool sem_release(resource id)
/* {{{ proto bool sem_release(Sysvsem id)
Releases the semaphore with the given id */
PHP_FUNCTION(sem_release)
{
php_sysvsem_semop(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
}
/* }}} */

/* {{{ proto bool sem_remove(resource id)
/* {{{ proto bool sem_remove(Sysvsem id)
Removes semaphore from Unix systems */

/*
Expand All @@ -349,21 +382,19 @@ PHP_FUNCTION(sem_remove)
struct semid_ds buf;
#endif

if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg_id) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &arg_id, sysvsem_ce) == FAILURE) {
RETURN_THROWS();
}

if ((sem_ptr = (sysvsem_sem *)zend_fetch_resource(Z_RES_P(arg_id), "SysV semaphore", php_sysvsem_module.le_sem)) == NULL) {
RETURN_THROWS();
}
sem_ptr = Z_SYSVSEM_P(arg_id);

#if HAVE_SEMUN
un.buf = &buf;
if (semctl(sem_ptr->semid, 0, IPC_STAT, un) < 0) {
#else
if (semctl(sem_ptr->semid, 0, IPC_STAT, NULL) < 0) {
#endif
php_error_docref(NULL, E_WARNING, "SysV semaphore " ZEND_LONG_FMT " does not (any longer) exist", Z_LVAL_P(arg_id));
php_error_docref(NULL, E_WARNING, "SysV semaphore for key 0x%x does not (any longer) exist", sem_ptr->key);
RETURN_FALSE;
}

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

Expand Down
22 changes: 8 additions & 14 deletions ext/sysvsem/sysvsem.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,17 @@

/** @generate-function-entries */

final class Sysvsem
{
}

/**
* @todo use bool for $auto_release
* @return resource|false
*/
function sem_get(int $key, int $max_acquire = 1, int $perm = 0666, int $auto_release = 1) {}
function sem_get(int $key, int $max_acquire = 1, int $perm = 0666, int $auto_release = 1): Sysvsem|false {}

/**
* @param resource $sem_identifier
*/
function sem_acquire($sem_identifier, bool $nowait = false): bool {}
function sem_acquire(Sysvsem $sem_identifier, bool $nowait = false): bool {}

/**
* @param resource $sem_identifier
*/
function sem_release($sem_identifier): bool {}
function sem_release(Sysvsem $sem_identifier): bool {}

/**
* @param resource $sem_identifier
*/
function sem_remove($sem_identifier): bool {}
function sem_remove(Sysvsem $sem_identifier): bool {}
11 changes: 8 additions & 3 deletions ext/sysvsem/sysvsem_arginfo.h
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
/* This is a generated file, edit the .stub.php file instead. */

ZEND_BEGIN_ARG_INFO_EX(arginfo_sem_get, 0, 0, 1)
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_sem_get, 0, 1, Sysvsem, MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, key, IS_LONG, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, max_acquire, IS_LONG, 0, "1")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, perm, IS_LONG, 0, "0666")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, auto_release, IS_LONG, 0, "1")
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sem_acquire, 0, 1, _IS_BOOL, 0)
ZEND_ARG_INFO(0, sem_identifier)
ZEND_ARG_OBJ_INFO(0, sem_identifier, Sysvsem, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, nowait, _IS_BOOL, 0, "false")
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sem_release, 0, 1, _IS_BOOL, 0)
ZEND_ARG_INFO(0, sem_identifier)
ZEND_ARG_OBJ_INFO(0, sem_identifier, Sysvsem, 0)
ZEND_END_ARG_INFO()

#define arginfo_sem_remove arginfo_sem_release
Expand All @@ -32,3 +32,8 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(sem_remove, arginfo_sem_remove)
ZEND_FE_END
};


static const zend_function_entry class_Sysvsem_methods[] = {
ZEND_FE_END
};
Loading