Hi!

I'm writting an application that uses shared memory and semaphores in PHP
and C/C++. PHP script writes data in memory and the C program read it. I
have no problems with the PHP script, but I can not acquire semaphores with
C/C++.

So, I wrote a sample program to test the semaphores. It's supposed to
acquire the semaphore and keep it blocked, but it does not. I have no
previous experience in Unix programming and I based my code in  php source
code (sysvsem.c). I appreciate you if you can help me to solve my problem.


This is the sample program:

//
// gcc recolector.c -o recolector
//

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>

#include "structure.h"
#include "mysql.h"

//

#define PERMS S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH

//  Los 3 semáforos que PHP utiliza.

#define SYSVSEM_SEM     0   //  Semáforo actual
#define SYSVSEM_USAGE   1
#define SYSVSEM_SETVAL  2

union semun {
        int val;                    /* value for SETVAL */
        struct semid_ds *buf;       /* buffer for IPC_STAT, IPC_SET */
        unsigned short int *array;  /* array for GETALL, SETALL */
        struct seminfo *__buf;      /* buffer for IPC_INFO */
};


void main( void ) {

    int shmid;
    key_t key = 4096;
    char *shm, *s;



    if ( ( shmid = shmget(key, 27, 0666) ) < 0 ) {

       perror("shmget");
       exit(1);

    }

    //  Get/create the semaphore

    int semid = semget( key, 3, PERMS | IPC_CREAT );

    if ( semid == -1 ) {

      perror("No pudo crear el semáforo");
   exit(1);

    }

 struct sembuf sop[3];

 /* 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 ) {

          printf( "semop() failed acquiring SYSVSEM_SETVAL for key 0x%x:
%s", key, strerror(errno));
          exit(1);

       }

    }


 union semun un;

 int count = semctl(semid, SYSVSEM_USAGE, GETVAL, un );

 if ( count == -1 ) {

       printf( "semctl() failed acquiring SYSVSEM_USAGE for key 0x%x: %s",
key, strerror(errno));
       exit(1);
    }

 if (count == 1) {

       union semun semarg;

       semarg.val = 1;

       if (semctl(semid, SYSVSEM_SEM, SETVAL, semarg) == -1) {

          printf( "semctl(SETVAL) failed for key %0x%x: %s", key,
strerror(errno));
    exit(1);
       }

 }

 /* 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) {

          printf( "semop() failed releasing SYSVSEM" );
          exit(1);
       }
    }

//    sem_ptr = (sysvsem_sem *) emalloc(sizeof(sysvsem_sem));
//    sem_ptr->key   = key;


 //

 sop[0].sem_num = SYSVSEM_SEM;
    sop[0].sem_op  = -1;
    sop[0].sem_flg = SEM_UNDO;

    while ( semop( semid, sop, 1 ) == -1) {

       if (errno != EINTR) {

       printf( "semop(acquire) failed for key 0x%x: %sx: %s", key,
strerror(errno) );
          exit(1);
       }

    }



 //

    if ((shm = (char *) shmat(shmid, NULL, 0)) == (char *) -1) {

       perror("shmat");
       exit(1);

    }

 //  Ciclo principal
/*
 while ( true ) {

       for (s = shm; *s != NULL; s++)

          putchar(*s);

       putchar('\n');

    usleep(1000000L);

 }
*/
    exit(0);
}

Thanks

Jorge Machin


-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to