Edit report at https://bugs.php.net/bug.php?id=61608&edit=1

 ID:                 61608
 Comment by:         trex_daemon at yahoo dot com
 Reported by:        stephane dot anthoine at gmail dot com
 Summary:            sem_get problem
 Status:             Open
 Type:               Bug
 Package:            Semaphore related
 Operating System:   linux 2.6.32
 PHP Version:        5.4.0
 Block user comment: N
 Private report:     N

 New Comment:

Actually I have the same problem.
A C process creates the semaphore (with full access: 0666) and then the PHP 
cannot access the semaphore with the same ID. Is there any news on this ?


Previous Comments:
------------------------------------------------------------------------
[2012-04-11 16:26:26] zhanglijiu at gmail dot com

what OS do you use? there is the sem_get system function:


PHP_FUNCTION(sem_get)
{
        long key, max_acquire = 1, perm = 0666, auto_release = 1;
        int semid;
        struct sembuf sop[3];
        int count;
        sysvsem_sem *sem_ptr;

        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, 
"l|lll", 
&key, &max_acquire, &perm, &auto_release)) {
                RETURN_FALSE;
        }

        /* Get/create the semaphore.  Note that we rely on the semaphores
         * being zeroed when they are created.  Despite the fact that
         * the(?)  Linux semget() man page says they are not initialized,
         * the kernel versions 2.0.x and 2.1.z do in fact zero them.
         */

        semid = semget(key, 3, perm|IPC_CREAT);
        if (semid == -1) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed for key 
0x%lx: %s", key, strerror(errno));
                RETURN_FALSE;
        }

        /* Find out how many processes are using this semaphore.  Note
         * that on Linux (at least) there is a race condition here because
         * semaphore undo on process exit is not atomic, so we could
         * acquire SYSVSEM_SETVAL before a crashed process has decremented
         * SYSVSEM_USAGE in which case count will be greater than it
         * should be and we won't set max_acquire.  Fortunately this
         * doesn't actually matter in practice.
         */

        /* Wait for sem 1 to be zero . . . */

        sop[0].sem_num = SYSVSEM_SETVAL;
        sop[0].sem_op  = 0;
        sop[0].sem_flg = 0;

        /* . . . and increment it so it becomes non-zero . . . */

        sop[1].sem_num = SYSVSEM_SETVAL;
        sop[1].sem_op  = 1;
        sop[1].sem_flg = SEM_UNDO;

        /* . . . and increment the usage count. */

        sop[2].sem_num = SYSVSEM_USAGE;
        sop[2].sem_op  = 1;
        sop[2].sem_flg = SEM_UNDO;
        while (semop(semid, sop, 3) == -1) {
                if (errno != EINTR) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed 
acquiring SYSVSEM_SETVAL for key 0x%lx: %s", key, strerror(errno));
                        break;
                }
        }

        /* Get the usage count. */
        count = semctl(semid, SYSVSEM_USAGE, GETVAL, NULL);
        if (count == -1) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed for key 
0x%lx: %s", key, strerror(errno));
        }

        /* If we are the only user, then take this opportunity to set the max. 
*/

        if (count == 1) {
#if HAVE_SEMUN
                /* This is correct for Linux which has union semun. */
                union semun semarg;
                semarg.val = max_acquire;
                if (semctl(semid, SYSVSEM_SEM, SETVAL, semarg) == -1) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed for 
key 0x%lx: %s", key, strerror(errno));
                }
#elif defined(SETVAL_WANTS_PTR)
                /* This is correct for Solaris 2.6 which does not have union 
semun. */
                if (semctl(semid, SYSVSEM_SEM, SETVAL, &max_acquire) == -1) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed for 
key 0x%lx: %s", key, strerror(errno));
                }
#else
                /* This works for i.e. AIX */
                if (semctl(semid, SYSVSEM_SEM, SETVAL, max_acquire) == -1) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed for 
key 0x%lx: %s", key, strerror(errno));
                }
#endif
        }

        /* Set semaphore 1 back to zero. */

        sop[0].sem_num = SYSVSEM_SETVAL;
        sop[0].sem_op  = -1;
        sop[0].sem_flg = SEM_UNDO;
        while (semop(semid, sop, 1) == -1) {
                if (errno != EINTR) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed 
releasing SYSVSEM_SETVAL for key 0x%lx: %s", key, strerror(errno));
                        break;
                }
        }

        sem_ptr = (sysvsem_sem *) emalloc(sizeof(sysvsem_sem));
        sem_ptr->key   = key;
        sem_ptr->semid = semid;
        sem_ptr->count = 0;
        sem_ptr->auto_release = auto_release;

        sem_ptr->id = ZEND_REGISTER_RESOURCE(return_value, sem_ptr, 
php_sysvsem_module.le_sem);
}

------------------------------------------------------------------------
[2012-04-03 14:39:15] stephane dot anthoine at gmail dot com

Description:
------------
---
>From manual page: 
>http://www.php.net/function.sem-get#refsect1-function.sem-get-
description
---
The sem_get function don't work if the semaphore already exist : by example 
created by an other application (made in C code). 
--> No sem_id returned.

If the php code is executed before this external application, the creation and 
sharing runs correctly....

sem_get seems able to make a new semaphore.... but not take back the Id of an 
existing semaphore.


Test script:
---------------
// On demande l’accès
$sem_id = sem_get(0x4d2, 1, 0666, 1);     <--- Return nothing              

// l'accès au block mémoire est autorisé
if(sem_acquire ($sem_id)) {                    
    $shm_id = shmop_open(0x4d2, "c", 0666, 200);
    if(!$shm_id) {
        echo "Impossible de creer la memoire partagee" . "<br />";
        // on libère l'accès 
        sem_remove($sem_id);
        exit;
    }
..... 

Expected result:
----------------
Be able to get back the sem_id of an exiting semaphore



------------------------------------------------------------------------



-- 
Edit this bug report at https://bugs.php.net/bug.php?id=61608&edit=1

Reply via email to