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().
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
#include "sysvsem_arginfo.h"
#include "php_sysvsem.h"
#include "ext/standard/info.h"
+#include "Zend/zend_interfaces.h"
#if !HAVE_SEMUN
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
#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;
/*
}
semop(sem_ptr->semid, sop, opcount);
- efree(sem_ptr);
+
+ zend_object_std_dtor(&sem_ptr->std);
}
/* }}} */
*/
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;
}
/* }}} */
#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)
{
}
}
- 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);
}
/* }}} */
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;
}
}
/* }}} */
-/* {{{ 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)
{
}
/* }}} */
-/* {{{ proto bool sem_release(resource id)
+/* {{{ proto bool sem_release(Sysvsem id)
Releases the semaphore with the given id */
PHP_FUNCTION(sem_release)
{
}
/* }}} */
-/* {{{ proto bool sem_remove(resource id)
+/* {{{ proto bool sem_remove(Sysvsem id)
Removes semaphore from Unix systems */
/*
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;
#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;
}
#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;
}
/** @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 {}
/* 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_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
ZEND_FE(sem_remove, arginfo_sem_remove)
ZEND_FE_END
};
+
+
+static const zend_function_entry class_Sysvsem_methods[] = {
+ ZEND_FE_END
+};
// Get semaphore for parent
$p_sem_id = sem_get($P_SEMKEY, 1);
if ($p_sem_id === FALSE) {
- echo "P: failed to parent get semaphore\n";
+ echo "P: failed to parent get semaphore.\n";
exit;
}
-echo "P: got semaphore $p_sem_id.\n";
+echo "P: got semaphore.\n";
// Get semaphore for child
$c_sem_id = sem_get($C_SEMKEY, 1);
if ($c_sem_id === FALSE) {
- echo "P: failed to child get semaphore\n";
+ echo "P: failed to child get semaphore.\n";
exit;
}
// Acquire semaphore for parent
if (!sem_acquire($p_sem_id)) {
- echo "P: fail to acquire semaphore $p_sem_id.\n";
+ echo "P: fail to acquire semaphore.\n";
sem_remove($p_sem_id);
exit;
}
-echo "P: acquired semaphore $p_sem_id.\n";
+echo "P: acquired semaphore.\n";
// Acquire semaphore for child
if (!sem_acquire($c_sem_id)) {
- echo "P: fail to acquire semaphore $c_sem_id.\n";
+ echo "P: failed to acquire semaphore.\n";
sem_remove($c_sem_id);
exit;
}
-echo "P: acquired semaphore $c_sem_id\n";
+echo "P: acquired semaphore.\n";
// Fork process
$pid = pcntl_fork();
if ($pid) {
register_shutdown_function(function () use ($p_sem_id) {
- echo "P: removing semaphore $p_sem_id.\n";
+ echo "P: removing semaphore.\n";
sem_remove($p_sem_id);
});
/* Wait for the child semaphore to be released to
to release the parent semaphore */
if (!sem_acquire($c_sem_id)) {
- echo "P: failed to acquire semaphore $c_sem_id.\n";
+ echo "P: failed to acquire semaphore.\n";
exit;
}
the child continue execution */
sem_release($c_sem_id);
- echo "P: releasing semaphore $p_sem_id.\n";
+ echo "P: releasing semaphore.\n";
if (!sem_release($p_sem_id)) {
- echo "P: failed to release semaphore\n";
+ echo "P: failed to release semaphore.\n";
}
$status = null;
} else {
register_shutdown_function(function () use ($c_sem_id) {
- echo "C: removing semaphore $c_sem_id.\n";
+ echo "C: removing semaphore.\n";
sem_remove($c_sem_id);
});
echo "C: child process running.\n";
// Have the semaphore after process forked
- echo "C: got semaphore $p_sem_id and $c_sem_id.\n";
+ echo "C: got semaphores.\n";
// This should fail to get to the semaphore and not wait
if (sem_acquire($p_sem_id, true)) {
- echo "C: test failed, Child was able to acquire semaphore $p_sem_id.\n";
+ echo "C: test failed, Child was able to acquire semaphore.\n";
exit;
}
// The child process did not wait to acquire the semaphore
- echo "C: failed to acquire semaphore $p_sem_id.\n";
+ echo "C: failed to acquire semaphore.\n";
- echo "C: releasing semaphore $c_sem_id\n";
+ echo "C: releasing semaphore.\n";
if (!sem_release($c_sem_id)) {
- echo "C: Failed to release semaphore\n";
+ echo "C: failed to release semaphore.\n";
}
// Acquire semaphore with waiting
if (!sem_acquire($p_sem_id)) {
- echo "C: fail to acquire semaphore $p_sem_id.\n";
+ echo "C: fail to acquire semaphore.\n";
exit;
}
- echo "C: success acquired semaphore $p_sem_id.\n";
+ echo "C: success acquired semaphore.\n";
- echo "C: releasing semaphore $p_sem_id.\n";
+ echo "C: releasing semaphore.\n";
sem_release($p_sem_id);
}
?>
--EXPECTF--
P: parent process running.
-P: got semaphore Resource id #%i.
-P: acquired semaphore Resource id #%i.
-P: acquired semaphore Resource id #%i
+P: got semaphore.
+P: acquired semaphore.
+P: acquired semaphore.
C: child process running.
-C: got semaphore Resource id #%i and Resource id #%i.
-C: failed to acquire semaphore Resource id #%i.
-C: releasing semaphore Resource id #%i
-P: releasing semaphore Resource id #%i.
-C: success acquired semaphore Resource id #%i.
-C: releasing semaphore Resource id #%i.
-C: removing semaphore Resource id #%i.
-P: removing semaphore Resource id #%i.
+C: got semaphores.
+C: failed to acquire semaphore.
+C: releasing semaphore.
+P: releasing semaphore.
+C: success acquired semaphore.
+C: releasing semaphore.
+C: removing semaphore.
+P: removing semaphore.
echo "Fail to get semaphore";
exit;
}
-echo "Got semaphore $sem_id.\n";
+echo "Got semaphore.\n";
// Accuire semaphore
if (! sem_acquire($sem_id)) {
- echo "Fail to acquire semaphore $sem_id.\n";
+ echo "Fail to acquire semaphore.\n";
sem_remove($sem_id);
exit;
}
-echo "Success acquire semaphore $sem_id.\n";
+echo "Success acquire semaphore.\n";
$shm_id = shm_attach($SHMKEY, $MEMSIZE);
if ($shm_id === FALSE) {
}
// Release semaphore
if (!sem_release($sem_id)) {
- echo "Fail to release $sem_id semaphore.\n";
+ echo "Fail to release semaphore.\n";
} else {
- echo "Semaphore $sem_id released.\n";
+ echo "Semaphore released.\n";
}
// remove shared memory segmant from SysV
if (sem_remove($sem_id)) {
echo "semaphore removed successfully from SysV.\n";
} else {
- echo "Fail to remove $sem_id semaphore from SysV.\n";
+ echo "Fail to remove semaphore from SysV.\n";
}
echo "End.\n";
/* NOTE: assigned semids differ depending on the kernel, since
?>
--EXPECTF--
Start.
-Got semaphore Resource id #%i.
-Success acquire semaphore Resource id #%i.
+Got semaphore.
+Success acquire semaphore.
Success to attach shared memory : %s.
Write var1 to shared memory.
Write var2 to shared memory.
Read var1=Variable 1.
Read var2=Variable 2.
-Semaphore Resource id #%s released.
+Semaphore released.
Shared memory successfully removed from SysV.
semaphore removed successfully from SysV.
End.