]> granicus.if.org Git - php/commitdiff
Convert resource to object in ext/sysvsem
authorMáté Kocsis <kocsismate@woohoolabs.com>
Fri, 1 May 2020 12:00:19 +0000 (14:00 +0200)
committerMáté Kocsis <kocsismate@woohoolabs.com>
Wed, 6 May 2020 13:42:41 +0000 (15:42 +0200)
Closes GH-5508

UPGRADING
ext/sysvsem/php_sysvsem.h
ext/sysvsem/sysvsem.c
ext/sysvsem/sysvsem.stub.php
ext/sysvsem/sysvsem_arginfo.h
ext/sysvsem/tests/nowait.phpt
ext/sysvsem/tests/sysv.phpt

index 1066d016ff63ebf66a5d1e692f2b64a029330736..00f7b88f1b34eea6ecd9864785dbed779af6fb6d 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -416,6 +416,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().
index 980ddbe0213162a31b007874701c46e85c275ebb..f4708942f787bbec59ad5d7a3a8449ae39e94c69 100644 (file)
@@ -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
index b5e8adb91fe6b4eae0f06630ac30e3f592cfbc0a..b9f1e626a7b9f4f3208b01897d1d3be6f040f510 100644 (file)
@@ -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
 
@@ -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
@@ -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;
 /*
@@ -130,7 +152,8 @@ static void release_sysvsem_sem(zend_resource *rsrc)
        }
 
        semop(sem_ptr->semid, sop, opcount);
-       efree(sem_ptr);
+
+       zend_object_std_dtor(&sem_ptr->std);
 }
 /* }}} */
 
@@ -138,7 +161,20 @@ static void release_sysvsem_sem(zend_resource *rsrc)
  */
 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;
 }
 /* }}} */
@@ -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)
 {
@@ -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);
 }
 /* }}} */
 
@@ -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;
        }
 
@@ -316,7 +349,7 @@ 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)
 {
@@ -324,7 +357,7 @@ 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)
 {
@@ -332,7 +365,7 @@ PHP_FUNCTION(sem_release)
 }
 /* }}} */
 
-/* {{{ proto bool sem_remove(resource id)
+/* {{{ proto bool sem_remove(Sysvsem id)
    Removes semaphore from Unix systems */
 
 /*
@@ -349,13 +382,11 @@ 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;
@@ -363,7 +394,7 @@ PHP_FUNCTION(sem_remove)
 #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;
        }
 
@@ -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;
        }
 
index 152689a79514541ca5751b00b8eda8f7611b3c78..e6fe1b4b7d8cfb67fea1b5d152b18f4b1b70e2a0 100644 (file)
@@ -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 {}
index 2edb26534fc68ebc01d06013228a32c871189046..83948fed3f7894157d95f97e2e5a145dc1d817e4 100644 (file)
@@ -1,6 +1,6 @@
 /* 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")
@@ -8,12 +8,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_sem_get, 0, 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
@@ -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
+};
index 147b8da335f560928a3c3ed80f978fa843749675..892a3757b5dad5d80f7259abe3463cdd2fc0c5e3 100644 (file)
@@ -18,42 +18,42 @@ pcntl_signal(SIGCHLD, SIG_IGN);
 // 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);
     });
 
@@ -63,7 +63,7 @@ if ($pid) {
     /* 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;
     }
 
@@ -72,9 +72,9 @@ if ($pid) {
        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;
@@ -83,52 +83,52 @@ if ($pid) {
 } 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.
index 08cb63f839098991674c37ac385391efa28867d5..aa2e7d10411c71cc9f8f90c3873c0ebac2ec0b89 100644 (file)
@@ -19,15 +19,15 @@ if ($sem_id === FALSE) {
     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) {
@@ -72,9 +72,9 @@ if ($var1 === 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
@@ -88,7 +88,7 @@ if (shm_remove ($shm_id)) {
 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
@@ -99,14 +99,14 @@ echo "End.\n";
 ?>
 --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.