int main(){

  int id; /* Number by which the semaphore is known within a program */
  
  /* The next thing is an argument to the semctl() function. Semctl() 
     does various things to the semaphore depending on which arguments
     are passed. We will use it to make sure that the value of the 
     semaphore is initially 0. */
  
  union semun {
    int val;
    struct semid_ds *buf;
    ushort * array;
  } argument;
  
  argument.val = 1;
  
  /* Create the semaphore with external key KEY if it doesn't already 
     exists. Give permissions to the world. */
  
  id = semget(KEY, 1, 0666 | IPC_CREAT);
  
  /* Always check system returns. */
  
  if(id < 0)
    {
      fprintf(stderr, "Unable to obtain semaphore.\n");
      exit(0);
    }
  
  /* What we actually get is an array of semaphores. The second 
     argument to semget() was the array dimension - in our case
     1. */
  
  /* Set the value of the number 0 semaphore in semaphore array
     # id to the value 0. */
  
  if( semctl(id, 0, SETVAL, argument) < 0)
    {
      fprintf( stderr, "Cannot set semaphore value.\n");
    }
  else
    {
      fprintf(stderr, "Semaphore %d initialized.\n", KEY);
    }
  
  int pid=fork();
  
  if(pid){
    struct sembuf operations[1];
    int retval; /* Return value from semop() */

    /* Get the index for the semaphore with external name KEY. */
    id = semget(KEY, 1, 0666);

    if(id < 0){
      /* Semaphore does not exist. */
      
      fprintf(stderr, "Program sema cannot find semaphore, exiting.\n");
      exit(0);
    }
    operations[0].sem_num = 0;
    /* Which operation? Subtract 1 from semaphore value : */
    operations[0].sem_op = -1;
    /* Set the flag so we will wait : */   
    operations[0].sem_flg = 0;
    

    
    while(1){
      //Process 1

      //wait
      operations[0].sem_op = -1;
      retval = semop(id, operations, 1);


      //critical section
      printf("In critical section P1 ... \n");
      fflush(stdout);
      int stime=2+(rand()/(float)(RAND_MAX))*4;
      printf("Sleeping for %d secs\n",stime);
      sleep(stime);


      printf("Ending critical section P1 ... \n");
      fflush(stdout);

      operations[0].sem_op = 1;
      //signal
      retval = semop(id, operations, 1);

    }
  }else{
    //Process 2
    struct sembuf operations[1];
    int retval; /* Return value from semop() */
    /* Get the index for the semaphore with external name KEY. */
    id = semget(KEY, 1, 0666);
    if(id < 0){
      /* Semaphore does not exist. */
      
      fprintf(stderr, "Program sema cannot find semaphore, exiting.\n");
      exit(0);
    }
    operations[0].sem_num = 0;
    /* Which operation? Subtract 1 from semaphore value : */
    operations[0].sem_op = -1;
    /* Set the flag so we will wait : */   
    operations[0].sem_flg = 0;
    
    while(1){

      
      
      //wait
      operations[0].sem_op = -1;
      retval = semop(id, operations, 1);
      
      //critical section
      printf("In critical section P2 ... \n");
      fflush(stdout);
      int stime=2+(rand()/(float)(RAND_MAX))*4;
      printf("Sleeping for %d secs\n",stime);
      sleep(stime);

      printf("Ending critical section P2 ... \n");
      fflush(stdout);

      //signal
      operations[0].sem_op = 1;
      retval = semop(id, operations, 1);

    }
    
  }
  
}
int main(int argc, char* argv[]) {
    union semun arg;      /* used to set semaphore parameters */
    struct sembuf sembuf; /* used to do a wait and signal */
    int semID;            /* the shared memory id */
    int flags;            /* flags for semget() call */

    /* check command line args */
    if((argc != 2) || (argv[1][0] != 'p' && argv[1][0] != 'c')) {
        fprintf(stderr, "Usage: a.out {p|c}\n");
        fprintf(stderr, "Where:\n");
        fprintf(stderr, "\tp: Producer (Start second)\n");
        fprintf(stderr, "\tc: Consumer (start first)\n");
        exit(1);
    }

    flags = PERMS|IPC_CREAT;

    /* system calls to create the semaphore */
    semID = semget(KEY, 1, flags);  /* create 1 semaphore in set (index 0) */
    if(semID < 0) {
        perror(">>> ERROR! Consumer must be started first.");
        exit(1);
    }

    if(argv[1][0] != 'p') {
        /* initialize the semaphore */
        arg.val = 0;    /* initalize semphore to 0 */
        if(semctl(semID, 0, SETVAL, arg) < 0) {
            perror (">>> ERROR! Initialization failed.");
            exit(1);
        }
    }

    if(argv[1][0] == 'p') {
        /* Producer does a semsignal() */
        fprintf(stdout, "Producer signaling....\n");
        sembuf.sem_num = 0;     /* first sem in set */
        sembuf.sem_op = 1;      /* 1 means signal */
        sembuf.sem_flg = 0;
        if(semop(semID, &sembuf, 1) == -1) {
            perror(">>> ERROR! Signal failed.");
            exit(1);
        }
    }
    else {
        /* Consumer does a semwait() */
        fprintf(stdout, "Consumer waiting ....\n");
        sembuf.sem_num = 0;     /* first sem in set */
        sembuf.sem_op = -1;     /* -1 means wait */
        sembuf.sem_flg = 0;
        if(semop(semID, &sembuf, 1) == -1) {
            perror(">>> ERROR! Wait failed");
            exit(1);
        }

        fprintf(stdout, "Producer has signaled.\n");

        /* delete */
        if(semctl(semID, 0, IPC_RMID, arg) == -1) {
            perror(">>> ERROR! Unsuccessful delete");
            exit(1);
        }
    }

    fprintf(stdout, "Done.\n");
    return 0;
}
Beispiel #3
0
void *mm_core_create(size_t usersize, const char *file)
{
    mem_core *mc;
    void *area = ((void *)-1);
#if defined(MM_SHMT_MMPOSX) || defined(MM_SHMT_MMZERO) || defined(MM_SHMT_MMFILE) || defined(MM_SHMT_IPCSHM)
    int fdmem = -1;
#endif
    int fdsem = -1;
#if defined(MM_SEMT_IPCSEM)
    int fdsem_rd = -1;
#endif
#if defined(MM_SHMT_MMPOSX) || defined(MM_SHMT_MMFILE)
    char *fnmem;
#endif
#if defined(MM_SEMT_FLOCK) || defined(MM_SEMT_FCNTL)
    char *fnsem;
#endif
    size_t size;
#if defined(MM_SHMT_MMZERO) || defined(MM_SHMT_MMPOSX) || defined(MM_SHMT_MMFILE)
    int zero = 0;
#endif
#if defined(MM_SHMT_IPCSHM)
    struct shmid_ds shmbuf;
#endif
#if defined(MM_SHMT_MMPOSX) || defined(MM_SHMT_MMFILE)
    char shmfilename[MM_MAXPATH];
#endif
#if defined(MM_SEMT_FLOCK) || defined(MM_SEMT_FCNTL)
    char semfilename[MM_MAXPATH];
#endif
#if defined(MM_SHMT_BEOS)
    area_id temparea;
#endif
    char filename[MM_MAXPATH];

    if (usersize <= 0 || usersize > mm_core_maxsegsize()) {
        errno = EINVAL;
        return NULL;
    }
    if (file == NULL) {
        sprintf(filename, MM_CORE_DEFAULT_FILE, (int)getpid());
        file = filename;
    }

    mm_core_init();
    size = mm_core_align2page(usersize+SIZEOF_mem_core);

#if defined(MM_SHMT_MMPOSX) || defined(MM_SHMT_MMFILE)
    sprintf(shmfilename, "%s.mem", file);
    fnmem = shmfilename;
#endif
#if defined(MM_SEMT_FLOCK) || defined(MM_SEMT_FCNTL)
    sprintf(semfilename, "%s.sem", file);
    fnsem = semfilename;
#endif

#if defined(MM_SHMT_MMANON)
    if ((area = (void *)mmap(NULL, size, PROT_READ|PROT_WRITE,
                             MAP_ANON|MAP_SHARED, -1, 0)) == (void *)MAP_FAILED)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to memory map anonymous area");
#endif /* MM_SHMT_MMANON */

#if defined(MM_SHMT_BEOS)
    if ((temparea = create_area("mm", (void*)&area, B_ANY_ADDRESS,
                                size, B_LAZY_LOCK, B_READ_AREA|B_WRITE_AREA)) < 0)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to create the memory area");
#endif /* MM_SHMT_BEOS */

#if defined(MM_SHMT_MMPOSX)
    shm_unlink(fnmem); /* Ok when it fails */
    if ((fdmem = shm_open(fnmem, O_RDWR|O_CREAT|O_EXCL, MM_CORE_FILEMODE)) == -1)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to open tempfile");
    if (ftruncate(fdmem, mm_core_mapoffset+size) == -1)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to truncate tempfile");
    write(fdmem, &zero, sizeof(zero));
    if ((area = (void *)mmap(NULL, size, PROT_READ|PROT_WRITE,
                             MAP_SHARED, fdmem, mm_core_mapoffset)) == (void *)MAP_FAILED)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to memory map tempfile");
    shm_unlink(fnmem);
    close(fdmem); fdmem = -1;
    mm_core_mapoffset += size;
#endif /* MM_SHMT_MMPOSX */

#if defined(MM_SHMT_MMZERO)
    if ((fdmem = open("/dev/zero", O_RDWR, MM_CORE_FILEMODE)) == -1)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to open /dev/zero");
    if (lseek(fdmem, mm_core_mapoffset+size, SEEK_SET) == -1)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to seek in /dev/zero");
    write(fdmem, &zero, sizeof(zero));
    if ((area = (void *)mmap(NULL, size, PROT_READ|PROT_WRITE,
                             MAP_SHARED, fdmem, mm_core_mapoffset)) == (void *)MAP_FAILED)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to memory map /dev/zero");
    close(fdmem); fdmem = -1;
    mm_core_mapoffset += size;
#endif /* MM_SHMT_MMZERO */

#if defined(MM_SHMT_MMFILE)
    unlink(fnmem);
    if ((fdmem = open(fnmem, O_RDWR|O_CREAT|O_EXCL, MM_CORE_FILEMODE)) == -1)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to open memory file");
    if (ftruncate(fdmem, mm_core_mapoffset+size) == -1)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to truncate memory file");
    write(fdmem, &zero, sizeof(zero));
    if ((area = (void *)mmap(NULL, size, PROT_READ|PROT_WRITE,
                             MAP_SHARED, fdmem, mm_core_mapoffset)) == (void *)MAP_FAILED)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to memory map memory file");
    close(fdmem); fdmem = -1;
    mm_core_mapoffset += size;
#endif /* MM_SHMT_MMFILE */

#if defined(MM_SHMT_IPCSHM)
    if ((fdmem = shmget(IPC_PRIVATE, size, (SHM_R|SHM_W|IPC_CREAT))) == -1)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to acquire shared memory segment");
    if ((area = (void *)shmat(fdmem, NULL, 0)) == ((void *)-1))
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to attach shared memory");
    if (shmctl(fdmem, IPC_STAT, &shmbuf) == -1)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to get status of shared memory");
    shmbuf.shm_perm.uid = getuid();
    shmbuf.shm_perm.gid = getgid();
    if (shmctl(fdmem, IPC_SET, &shmbuf) == -1)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to set status of shared memory");
    if (shmctl(fdmem, IPC_RMID, NULL) == -1)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to remove shared memory in advance");
#endif /* MM_SHMT_IPCSHM */

#if defined(MM_SEMT_FLOCK)
    unlink(fnsem);
    if ((fdsem = open(fnsem, O_RDWR|O_CREAT|O_EXCL, MM_CORE_FILEMODE)) == -1)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to open semaphore file");
#if defined(F_SETFD) && defined(FD_CLOEXEC)
    if (fcntl(fdsem, F_SETFD, FD_CLOEXEC) == -1)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to set close-on-exec flag");
#endif
#endif /* MM_SEMT_FLOCK */

#if defined(MM_SEMT_FCNTL)
    unlink(fnsem);
    if ((fdsem = open(fnsem, O_RDWR|O_CREAT|O_EXCL, MM_CORE_FILEMODE)) == -1)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to open semaphore file");
#if defined(F_SETFD) && defined(FD_CLOEXEC)
    if (fcntl(fdsem, F_SETFD, FD_CLOEXEC) == -1)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to set close-on-exec flag");
#endif
#endif /* MM_SEMT_FCNTL */

#if defined(MM_SEMT_IPCSEM)
    fdsem = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR);
    if (fdsem == -1 && errno == EEXIST)
        fdsem = semget(IPC_PRIVATE, 1, IPC_EXCL|S_IRUSR|S_IWUSR);
    if (fdsem == -1)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to acquire semaphore");
    mm_core_semctlarg.val = 0;
    semctl(fdsem, 0, SETVAL, mm_core_semctlarg);
    fdsem_rd = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR);
    if (fdsem_rd == -1 && errno == EEXIST)
        fdsem_rd = semget(IPC_PRIVATE, 1, IPC_EXCL|S_IRUSR|S_IWUSR);
    if (fdsem_rd == -1)
        FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to acquire semaphore");
    mm_core_semctlarg.val = 0;
    semctl(fdsem_rd, 0, SETVAL, mm_core_semctlarg);
#endif /* MM_SEMT_IPCSEM */

    /*
     * Configure the memory core parameters
     */
    mc = (mem_core *)area;
    mc->mc_size     = size;
    mc->mc_usize    = usersize;
    mc->mc_pid      = getpid();
#if defined(MM_SHMT_IPCSHM)
    mc->mc_fdmem    = fdmem;
#endif
#if defined(MM_SEMT_FLOCK)
    mc->mc_fdsem[0].pid = getpid();
    mc->mc_fdsem[0].fd  = fdsem;
    mc->mc_fdsem[1].pid = 0;
    mc->mc_fdsem[1].fd  = -1;
#else
    mc->mc_fdsem = fdsem;
#endif
#if defined(MM_SEMT_BEOS)
    mc->mc_semid = create_sem(0, "mm_semid");
    mc->mc_ben = 0;
#endif
#if defined(MM_SHMT_BEOS)
    mc->mc_areaid = temparea;
#endif
#if defined(MM_SEMT_IPCSEM)
    mc->mc_fdsem_rd = fdsem_rd;
    mc->mc_readers = 0;
#endif
#if defined(MM_SHMT_MMFILE)
    memcpy(mc->mc_fnmem, fnmem, MM_MAXPATH);
#endif
#if defined(MM_SEMT_FLOCK) || defined(MM_SEMT_FCNTL)
    memcpy(mc->mc_fnsem, fnsem, MM_MAXPATH);
#endif

    /*
     * Return successfully established core
     */
    return ((void *)&(mc->mc_base.mw_cp));

    /*
     * clean-up sequence (CUS) for error situation
     */
    BEGIN_FAILURE
#if defined(MM_SHMT_MMANON) || defined(MM_SHMT_MMZERO) || defined(MM_SHMT_MMPOSX) || defined(MM_SHMT_MMFILE)
    if (area != ((void *)-1))
        munmap((caddr_t)area, size);
#endif
#if defined(MM_SHMT_IPCSHM)
    if (area != ((void *)-1))
        shmdt(area);
#endif
#if defined(MM_SHMT_MMPOSX) || defined(MM_SHMT_MMZERO) || defined(MM_SHMT_MMFILE)
    if (fdmem != -1)
        close(fdmem);
#endif
#if defined(MM_SEMT_BEOS)
    delete_sem(mc->mc_semid);
#endif
#if defined(MM_SHMT_BEOS)
    delete_area(mc->mc_areaid);
#endif
#if defined(MM_SHMT_IPCSHM)
    if (fdmem != -1)
        shmctl(fdmem, IPC_RMID, NULL);
#endif
#if defined(MM_SEMT_FLOCK) || defined(MM_SEMT_FCNTL)
    if (fdsem != -1)
        close(fdsem);
#endif
#if defined(MM_SEMT_IPCSEM)
    if (fdsem != -1)
        semctl(fdsem, 0, IPC_RMID, 0);
    if (fdsem_rd != -1)
        semctl(fdsem_rd, 0, IPC_RMID, 0);
#endif
#if defined(MM_SHMT_MMFILE)
    unlink(fnmem);
#endif
#if defined(MM_SEMT_FLOCK) || defined(MM_SEMT_FCNTL)
    unlink(fnsem);
#endif
    return NULL;
    END_FAILURE
}
Beispiel #4
0
int main (int argc, char* argv[])
{
	key_t klucz = ftok("./../..",'L');
	
	if(klucz == -1)
	{
		fprintf(stderr,"KONSUMENT: Blad tworzenia klucza dla zbioru semaforów!\n");
		exit(3);
	}
	else
		fprintf(stdout,"KONSUMENT: Wartosc wygenerowanego klucza dla zbioru semaforow: %ld\n", klucz);
	
	// przyłączanie zbioru semaforów:	
	int ilosc_sem = 4;
	int id_semafor = semget(klucz, ilosc_sem, IPC_CREAT|0600);
	if (id_semafor == -1)
	{
		fprintf(stderr,"KONSUMENT: Blad przyłączania zbioru semaforow!\n");
		exit(EXIT_FAILURE);
	}
	else
		fprintf(stdout,"KONSUMENT: Zbior semaforow przyłączony, id= %d\n", id_semafor);


	FILE* wyjscie = fopen("out.txt", "w");
	if(wyjscie == 0)
	{
		fprintf(stderr,"KONSUMENT: Blad otwierania pliku wyjsciowego!\n");
		exit(EXIT_FAILURE);
	}
	else
		fprintf(stdout, "KONSUMENT: Plik wyjsciowy otwarty!\n");
	
	// przylaczenie segmentu pamięci dzielonej
	int id_pamiec = shmget(klucz, 4, IPC_CREAT|0600);
	if (id_pamiec == -1)
	{
		fprintf(stderr, "KONSUMENT: Blad przylaczenia segmentu pamieci dzielonej!\n");
		exit(EXIT_FAILURE);
	}
	else
		fprintf(stdout, "KONSUMENT: Pomyslnie przylaczono segment pamieci dzielonej o ID: %d\n", id_pamiec);
	
	//uzyskanie adresu segmentu pamieci dzielonej	
	char* adres=(char*)shmat(id_pamiec, 0, 0);
	if (*adres==-1)
	{
		fprintf(stderr, "KONSUMENT: Blad uzyskania dostepu do segmentu pamieci dzielonej!\n");
		exit(EXIT_FAILURE);
	}
	else
		fprintf(stdout, "KONSUMENT: Pomyslnie uzyskano dostep do segmentu pamieci dzielonej: %X\n", adres);
	
	char znak;
	int status;
	
	while(1)
	{			
		opusc_semafor(id_semafor, 0);
		
		if(semctl(id_semafor, 2, GETVAL, NULL) <= 0)
			break;
		
		znak=*adres;
		
		srand(time(NULL));
		//usleep(rand() % 100);
		
		fputc(znak, wyjscie);
		
		if(ferror(wyjscie))
			fprintf(stderr, "PRODUCENT: Blad zapisu znaku do pliku wejsciowego!\n");
				
		podnies_semafor(id_semafor, 1);	
	}
	
	if(status < 0)
	{
		fprintf(stderr,"KONSUMENT: Blad pobierania wartosci semafora nr 2\n"); 
		exit(EXIT_FAILURE);
	}
		
	fprintf(stdout,"KONSUMENT: zakonczono kopiowanie znakow\n");
	podnies_semafor(id_semafor, 3);	
	//zamkniecie pliku
	if(fclose(wyjscie) == EOF) 
	{
		fprintf(stderr,"PRODUCENT: Blad zamykania pliku wyjsciowego\n"); 
		exit(EXIT_FAILURE);
	}
	else
		fprintf(stdout, "KONSUMENT: Pomyslnie zamknieto plik wyjsciowy\n");
		
	return 0;
}
Beispiel #5
0
ce_int_t ce_sem_create(ce_sem_t *sem, unsigned int semnum)
{
	int sem_id;
	key_t sem_key;
	union semun arg;
	struct sembuf	initop;
	int save_errno;
	int cnt = 0;
	
	/*get key*/
	sem_key=ftok((const char*)sem->name.data,sem->proj_id);    
	if(-1 == sem_key)
	{
		return CE_ERROR;
	}
	
	sem_id=semget(sem_key, semnum, IPC_CREAT|IPC_EXCL|0666);    
	if(sem_id != -1)
	{
		for (cnt = 0; cnt < semnum; cnt++)
		{
			/*init sem*/
			arg.val=0;
			if(semctl(sem_id,cnt,SETVAL,arg)<0)
			{
				goto err;
			}
			
			initop.sem_num=cnt;
			initop.sem_op=sem->sem_val<=0?1:sem->sem_val;
			initop.sem_flg=0;

			if(semop(sem_id,&initop,1)<0)
			{
				goto err;
			}
		}
		goto fin;
	}	
	else if(errno!=EEXIST)
	{
		
		goto err;
	}
	else //sem existed,then open it
	{
		sem_id=semget(sem_key,0,0);
		goto fin;
	}

	err:
	save_errno=errno;
	if(sem_id!=-1)
	{
		semctl(sem_id,0,IPC_RMID);
	}
	errno=save_errno;
	return CE_ERROR;
	fin:
	sem->sem_id=sem_id;
	return CE_OK;
}
Beispiel #6
0
/* Open or create a semaphore initializing it as necessary.
 */
static int
semid_get(const char *name, int nsems, int oflags, mode_t mode, int value)
{
	key_t key;
	int max;

	if (nsems > MAX_SEMNUM) {
		ERR(errno = ERANGE, "semid_get");
		return -1;
	}
	if ((key = ftok((char *)name, 1)) == (key_t)-1) {
		ERR(errno, "ftok");
		return -1;
	}

	/* This following loop ensures that we know if the semaphore was created
	 * as opposed to just opened so that it can be initialized properly. We
	 * do this by alternating between oflags 0 and IPC_CREATE|IPC_EXCL until
	 * one succeeds.
	 */ 
	for (max = MAX_TRIES; max; max--) {
		int semid;
		union semun arg;

		if ((oflags & O_EXCL) == 0) {
			if ((semid = semget(key, nsems, 0)) != -1) {
				struct semid_ds buf;

				/* This inner try-loop ensures that the semaphore is initialized before
				 * we return even if the semaphore has been created with semget but not
				 * yet initialized with semctl. See Stevens' UNPv2 p274.
				 */
				arg.buf = &buf;
				for (max = MAX_TRIES; max; max--) {
					if (semctl(semid, 0, IPC_STAT, arg) == -1) {
						ERR(errno, "semctl");
						return -1;
					}
					if (buf.sem_otime != 0) {
						return semid;
					}
					sleep(1);
				}

				ERR(errno = ETIMEDOUT, "semid_get");
				return -1;
			} else if (errno != ENOENT) {
				ERR(errno, "semget");
				return -1;
			}
		}
		if ((semid = semget(key, nsems, IPC_CREAT | IPC_EXCL | (mode & 0777))) != -1) {
			struct sembuf initop;

			if (nsems > 1) {
				unsigned short array[MAX_SEMNUM * sizeof(unsigned short)];
				int i;

				arg.array = array;
				arg.array[0] = 0; /* leave the first one 0 to be set with semop */
				for (i = 1; i < nsems; i++) {
					arg.array[i] = value;
				}
				if (semctl(semid, 0, SETALL, arg) == -1) {
					ERR(errno, "semctl");
					semctl(semid, 0, IPC_RMID);
					return -1;
				}
			} else {
				arg.val = 0;
				if (semctl(semid, 0, SETVAL, arg) == -1) {
					ERR(errno, "semctl");
					semctl(semid, 0, IPC_RMID);
					return -1;
				}
			}
                                 /* increment by value to set sem_otime nonzero */
			initop.sem_num = 0;
			initop.sem_op = value;
			initop.sem_flg = 0;
			if (semop(semid, &initop, 1) == -1) {
				ERR(errno, "semop");
				semctl(semid, 0, IPC_RMID);
				return -1;
			}

			return semid;
		} else if ((oflags & O_EXCL) || errno != EEXIST) {
			ERR(errno, "semget");
			return -1;
		}
	}

	ERR(errno = ETIMEDOUT, "semid_get");
	return -1;
}
Beispiel #7
0
/**
 * Returns a data-structure for accessing a shared-memory FIFO. Creates the
 * FIFO is it doesn't already exist.
 *
 * @retval !NULL        Pointer the data-structure for accessing the
 *                      shared-memory FIFO.
 * @retval NULL         Failure. An error message is logged.
 */
ShmHandle*
shmfifo_create(
    const int   npages,         /**< size of the FIFO in pages */
    const int   privsz,         /**< <size of the private portion of the FIFO
                                 in bytes */
    const int   nkey)           /**< Partial key associated with the FIFO  or
                                 \c -1 to obtain a private, shared-memory
                                 FIFO. */
{
    int                 shmSize = npages*getpagesize();
    int                 shmid;
    struct shmhandle*   shm = NULL;     /* default failure */
    key_t               key;

    if (nkey == -1) {
        shmid = shmget(IPC_PRIVATE, shmSize,
                IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
    }
    else {
        key = (key_t)(DVBS_ID + nkey);
        /*
         * IPC_EXCL creates an error condition if the memory already exists...
         * we can use the existing memory if the program has not changed the
         * size of the segment or the private structure size
         */
        shmid = shmget(key, shmSize,
            IPC_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
    }

    if (shmid == -1) {
        log_syserr("shmget() failure: npages=%d, nkey=%d",
            npages, nkey);
    }
    else {
        /* Temporarily attach to initialize the control structure. */
        struct shmprefix*       p = (struct shmprefix*)shmat(shmid, 0, 0);

        if (p == (void*)-1) {
            log_syserr("shmat() failure: id=%d", shmid);
        }
        else {
            int     semid;

            p->read = p->write = sizeof(struct shmprefix) + privsz;
            p->sz = shmSize;
            p->privsz = privsz;

            (void)memset((char*)p + sizeof(struct shmprefix), 0, privsz);
            (void)shmdt(p);

            p = NULL;

            /* Get semaphore */
            if (nkey == -1) {
                semid = semget(IPC_PRIVATE, SI_SEM_COUNT,
                    (IPC_CREAT | IPC_EXCL) + 0600);
            }
            else {
                /*
                 * IPC_EXCL not used in order to get existing semaphore if
                 * possible.
                 */
                semid = semget(key, SI_SEM_COUNT, IPC_CREAT + 0660);
            }

            if (semid == -1) {
                log_syserr("semget() failure");
            }
            else {
                unsigned short      values[SI_SEM_COUNT];
                union semun         arg;

                log_debug("shmfifo_create(): Got semaphore: pid=%d, semid=%d",
                    getpid(), semid);

                values[SI_LOCK] = 1;
                values[SI_WRITER] = 0;
                values[SI_READER] = 0;
                arg.array = values;

                if (semctl(semid, 0, SETALL, arg) == -1) {
                    log_syserr("semctl() failure: semid=%d",
                        semid);
                }
                else {
                    shm = shmfifo_new();

                    if (NULL != shm) {
                        shm->sid = shmid;
                        shm->privsz = privsz;
                        shm->sz = shmSize;
                        shm->semid = semid;
                    }
                }                       /* semaphore values set */
            }                           /* got semaphore set */
        }                               /* shared-memory was attached to "p" */
    }                                   /* got shared-memory segment ID */

    return shm;
}
Beispiel #8
0
	~Semid1()
	{
		if (semctl(semid,0,IPC_RMID)==-1)throw_nynn_exception(errno,NULL);
	}
/*!
    \internal

    Setup unix_key
 */
key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
{
    if (key.isEmpty()){
        errorString = QCoreApplication::tr("%1: key is empty", "QSystemSemaphore").arg(QLatin1String("QSystemSemaphore::handle:"));
        error = QSystemSemaphore::KeyError;
        return -1;
    }

    // ftok requires that an actual file exists somewhere
    if (-1 != unix_key)
        return unix_key;

    // Create the file needed for ftok
    int built = QSharedMemoryPrivate::createUnixKeyFile(fileName);
    if (-1 == built) {
        errorString = QCoreApplication::tr("%1: unable to make key", "QSystemSemaphore").arg(QLatin1String("QSystemSemaphore::handle:"));
        error = QSystemSemaphore::KeyError;
        return -1;
    }
    createdFile = (1 == built);

    // Get the unix key for the created file
    unix_key = ftok(QFile::encodeName(fileName).constData(), 'Q');
    if (-1 == unix_key) {
        errorString = QCoreApplication::tr("%1: ftok failed", "QSystemSemaphore").arg(QLatin1String("QSystemSemaphore::handle:"));
        error = QSystemSemaphore::KeyError;
        return -1;
    }

    // Get semaphore
    semaphore = semget(unix_key, 1, 0666 | IPC_CREAT | IPC_EXCL);
    if (-1 == semaphore) {
        if (errno == EEXIST)
            semaphore = semget(unix_key, 1, 0666 | IPC_CREAT);
        if (-1 == semaphore) {
            setErrorString(QLatin1String("QSystemSemaphore::handle"));
            cleanHandle();
            return -1;
        }
    } else {
        createdSemaphore = true;
        // Force cleanup of file, it is possible that it can be left over from a crash
        createdFile = true;
    }

    if (mode == QSystemSemaphore::Create) {
        createdSemaphore = true;
        createdFile = true;
    }

    // Created semaphore so initialize its value.
    if (createdSemaphore && initialValue >= 0) {
        qt_semun init_op;
        init_op.val = initialValue;
        if (-1 == semctl(semaphore, 0, SETVAL, init_op)) {
            setErrorString(QLatin1String("QSystemSemaphore::handle"));
            cleanHandle();
            return -1;
        }
    }

    return unix_key;
}
Beispiel #10
0
main()
{

    struct sembuf P,V;
    union semun arg;

    int arrayid;
    int getid;

    int *array;
    int *get;

    int sumID;
    int *sum;

    sumID=shmget(IPC_PRIVATE,sizeof(int),IPC_CREAT|0666);
    sum=(int *)shmat(sumID,0,0);
    arrayid=shmget(IPC_PRIVATE,sizeof(int)*MAXSHM,IPC_CREAT|0666);
    getid=shmget(IPC_PRIVATE,sizeof(int),IPC_CREAT|0666);

    array=(int *)shmat(arrayid,0,0);
    get=(int *)shmat(getid,0,0);
    *get=0;

    fullid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);
    emptyid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);
    mutexid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);

    arg.val=0;
    if(semctl(fullid,0,SETVAL,arg)==-1)
        perror("semctl setval error");
    arg.val=MAXSHM;
    if(semctl(emptyid,0,SETVAL,arg)==-1)
        perror("semctl setval error");
    arg.val=1;
    if(semctl(mutexid,0,SETVAL,arg)==-1)
        perror("semctl setval error");

    P.sem_num=0;
    P.sem_op=-1;
    P.sem_flg=SEM_UNDO;
    V.sem_num=0;
    V.sem_op=1;
    V.sem_flg=SEM_UNDO;

    if(fork()==0)
    {
        int i=0;
        int set=0;
        while(i<10)
        {
            semop(emptyid,&P,1);
            semop(mutexid,&P,1);
            array[set%MAXSHM]=i+1;
            printf("Productor put number: %d\n",array[set%MAXSHM]);
            set++;
            semop(mutexid,&V,1);
            semop(fullid,&V,1);
            i++;
        }
        sleep(3);
        printf("Productor is over\n");
        exit(0);
    }
    else {

        if(fork()==0)
        {
            while(1)
            {
                if(*get == 10)
                    break;
                semop(fullid,&P,1);
                semop(mutexid,&P,1);
                printf("The ComsumerA get number: %d\n",array[(*get)%MAXSHM]);
                *sum+=array[(*get)%MAXSHM];
                (*get)++;
                semop(mutexid,&V,1);
                semop(emptyid,&V,1);
                sleep(1);
            }
            printf("ComsumerA is over\n");
            exit(0);
        }
        else
        {
            if(fork()==0)
            {
                while(1)
                {
                    if(*get ==10)
                        break;
                    semop(fullid,&P,1);
                    semop(mutexid,&P,1);
                    printf("The ComsumerB get number: %d\n",array[(*get)%MAXSHM]);
                    *sum+=array[(*get)%MAXSHM];
                    (*get)++;
                    semop(mutexid,&V,1);
                    semop(emptyid,&V,1);
                    sleep(1);
                }
                printf("ComsumerB is over\n");
                exit(0);
            }
        }
    }
    wait(0);
    wait(0);
    wait(0);

    shmdt(array);
    shmctl(arrayid,IPC_RMID,0);
    shmdt(get);
    shmctl(getid,IPC_RMID,0);

    semctl(emptyid,IPC_RMID,0);
    semctl(fullid,IPC_RMID,0);
    semctl(mutexid,IPC_RMID,0);
    printf("sum : %d\n",*sum);
    exit(0);
}
Beispiel #11
0
/**
 * Get the status of semaphore
 *
 * @param semid     semaphore identifier
 * @param semno     semaphore number
 *
 * @return true for the flag on, false for the flag off
 */
bool qsem_check(int semid, int semno) {
    if (semctl(semid, semno, GETVAL, 0) == 0)
        return true;  // locked
    return false;  // unlocked
}
int main(int argc, char *argv[])
{

    //定义共享缓冲区及其信号灯
    int readbuf_id = shmget(IPC_PRIVATE, CACHE_LENGTH + sizeof(unsigned),
                            IPC_CREAT | IPC_EXCL | 0666);
    int rbuf_empty = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | 0666);
    int rbuf_max = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | 0666);
    int writebuf_id = shmget(IPC_PRIVATE, CACHE_LENGTH + sizeof(unsigned),
                             IPC_CREAT | IPC_EXCL | 0666);
    int wbuf_empty = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | 0666);
    int wbuf_max = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | 0666);

    int finish_id = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | 0666);

    int get_id = 0;
    int put_id = 0;
    int copy_id = 0;

    union semun semopts;
    FILE *out;
    FILE *in;
    int n;

    //打开源和目标文件
    if (argc != 3)
    {
        puts("arguments error");
        return 0;
    }
    if ((in = fopen(argv[1], "rb")) == NULL)
    {
        puts("can't open input file");
        return 0;
    }
    if ((out = fopen(argv[2], "wb")) == NULL)
    {
        puts("can't open output file");
        fclose(in);
        return 0;
    }

    //信号灯赋值
    semopts.val = 1;
    semctl(rbuf_empty, 0, SETVAL, semopts);
    semctl(wbuf_empty, 0, SETVAL, semopts);
    semopts.val = 0;
    semctl(rbuf_max, 0, SETVAL, semopts);
    semctl(wbuf_max, 0, SETVAL, semopts);
    semctl(finish_id, 0, SETVAL, semopts);
    /*semctl(part_over, 0, SETVAL, semopts);*/
    /*semctl(over, 0, SETVAL, semopts);*/

    // get
    if ((get_id = fork()) == 0)
    {
        unsigned char *s = shmat(readbuf_id, 0, 0);
        puts("get:start to get");
        do
        {
            P(rbuf_empty, 0);

            //加入copy
            n = fread(s + sizeof(unsigned), 1, CACHE_LENGTH, in);
            /*n = fread(s + sizeof(unsigned),  1, 2, in);*/
            printf("read: %d\n", n);
            /*putchar('\n');*/

            *(unsigned *)s = n;
            /*fwrite(s + sizeof(unsigned),  1, *(unsigned *)s, stdout);*/
            V(rbuf_max, 0);

            if (*(unsigned *)s == 0)
                break;
        } while (1);
        fclose(in);
        /*sleep(5);*/
        P(finish_id, 0);
        shmdt(s);

        //请加入保证三个进程同步结束的机制
        puts("get: get ended");
        return 0;
    }
    // copy
    if ((copy_id = fork()) == 0)
    {
        unsigned char *s1 = shmat(readbuf_id, 0, 0);
        unsigned char *s2 = shmat(writebuf_id, 0, 0);

        char buf[CACHE_LENGTH + sizeof(unsigned)];
        puts("copy: start to copy");
        do
        {
            P(rbuf_max, 0);

            //加入内容
            n = *(unsigned *)s1;
            printf("copy: %d\n", n);
            memcpy(buf, s1, CACHE_LENGTH + sizeof(unsigned));
            /*fwrite(s1 + sizeof(unsigned),  1, *(unsigned*)s1, stdout);*/

            V(rbuf_empty, 0);

            P(wbuf_empty, 0);

            //加入内容
            /**(unsigned *)s2 = n;*/
            memcpy(s2, buf, CACHE_LENGTH + sizeof(unsigned));
            printf("\ncopy: \n");
            /*fwrite(s2 + sizeof(unsigned),  1, *(unsigned*)s2, stdout);*/
            printf("\n\n");

            V(wbuf_max, 0);

            if (*(unsigned *)s2 == 0)
                break;
        } while (1);

        P(finish_id, 0);
        shmdt(s1);
        shmdt(s2);

        //请加入保证三个进程同步结束的机制
        puts("copy: copy ended");
        /*sleep(5);*/
        return 0;
    }
    // put
    if ((put_id = fork()) == 0)
    {
        unsigned char *s = shmat(writebuf_id, 0, 0);
        puts("put: start to put");
        char buf_put[CACHE_LENGTH + sizeof(unsigned)];
        do
        {
            P(wbuf_max, 0);

            //加入内容
            /*memcpy(buf_put, s, CACHE_LENGTH + sizeof(unsigned));*/
            printf("put: %d\n", *(unsigned *)s);
            /*if (*(unsigned*)s > 0)*/
            /*{*/
            fwrite(s + sizeof(unsigned), 1, *(unsigned *)s, out);
            fwrite(s + sizeof(unsigned), 1, *(unsigned *)s, stdout);
            /*}*/
            fflush(out);

            V(wbuf_empty, 0);

            if (*(unsigned *)s == 0)
            {
                V(finish_id, 0);
                break;
            }
        } while (1);
        shmdt(s);
        fclose(out);

        //请加入保证三个进程同步结束的机制

        puts("put: put ended");
        return 0;
    }

    //请加入保证三个进程同步结束的机制

    //请加入释放缓冲区和信号灯的机制
    /*int status;*/
    P(finish_id, 0);
    shmctl(readbuf_id, IPC_RMID, 0);
    shmctl(writebuf_id, IPC_RMID, 0);

    return 0;
}
Beispiel #13
0
void uv_sem_destroy(uv_sem_t* sem) {
  if (-1 == semctl(*sem, 0, IPC_RMID))
    abort();
}
Beispiel #14
0
int main (int argc, char ** argv)
{
    int semid;

    key = rand();

#ifndef DO_BENCH
    printf("Semaphore key: 0x%8x\n", key);
#endif

    /* server run first and client run later */
    if (argc == 2 && strcmp(argv[1], "serial") == 0) {
        mode = SERIAL;
        if (fork() == 0)
            server();
        wait(NULL);
        if (fork() == 0)
            client();
        wait(NULL);
    }

    if ((semid = semget(key, 2, 0600|IPC_CREAT)) < 0) {
        perror("semget");
        exit(1);
    }

    /* server run first and client run later (in the same process) */
    if (argc == 2 && strcmp(argv[1], "in-process") == 0) {
        mode = IN_PROCESS;
        server();
        client();
        semctl(semid, 0, IPC_RMID);
        return 0;
    }

    pipe(pipefds);

    /* server to be the parent and client to be the child */
    if (argc == 1) {
        if (fork() == 0)
            client();
        else
            server();
    }

    /* client to be the parent and server to be the child */
    if (argc == 2 && strcmp(argv[1], "reverse") == 0) {
        if (fork() == 0)
            server();
        else
            client();
    }

    /* both client and server are children */
    if (argc == 2 && strcmp(argv[1], "children") == 0) {
        if (fork() == 0)
            server();
        if (fork() == 0)
            client();
        wait(NULL);
        wait(NULL);
    }

    semctl(semid, 0, IPC_RMID);

    return 0;
}
/*---------------------------------------------------------------------+
|                               main                                   |
| ==================================================================== |
|                                                                      |
| Function:  Main program  (see prolog for more details)               |
|                                                                      |
| Returns:   (0)  Successful completion                                |
|            (-1) Error occurred                                       |
|                                                                      |
+---------------------------------------------------------------------*/
int main(int argc, char **argv)
{
	uid_t uid = getuid();	/* User's user id */
	gid_t gid = getgid();	/* User's group id */
	int semid;		/* Unique semaphore id */
	int nsems = NUM_SEMAPHORES;	/* Number of semaphores to create */
	struct semid_ds exp_semdata;	/* Expected semaphore values */
	union semun exp_semdatap;
	struct semid_ds act_semdata;	/* Actual semaphore values */
	union semun act_semdatap;

	exp_semdatap.buf = &exp_semdata;
	act_semdatap.buf = &act_semdata;

	umask(0000);

	/* SET semid_ds STRUCTURE TO DESIRED VALUES........ */

	/*
	 * Initialize the "expected" sempahore value structure
	 */
	exp_semdata.sem_perm.cuid = exp_semdata.sem_perm.uid = uid;
	exp_semdata.sem_perm.cgid = exp_semdata.sem_perm.gid = gid;
	exp_semdata.sem_perm.mode = 0660;
	exp_semdata.sem_nsems = nsems;

	/*
	 * Create a semaphore, set the semaphore fields and then
	 * retrieve the fields.
	 */
	if ((semid = semget(IPC_PRIVATE, nsems, IPC_CREAT | 0666)) < 0)
		sys_error("semget (IPC_PRIVATE) failed", __LINE__);

	if (semctl(semid, nsems, IPC_SET, exp_semdatap) < 0)
		sys_error("semctl (IPC_SET) failed", __LINE__);

	if (semctl(semid, nsems, IPC_STAT, act_semdatap) < 0)
		sys_error("semctl (IPC_STAT) failed", __LINE__);

	/*
	 * Verify that the semaphore fields were set correctly
	 */
	if (act_semdata.sem_perm.cuid != exp_semdata.sem_perm.cuid)
		error("sem_perm.cuid field was not set!", __LINE__);
	if (act_semdata.sem_perm.uid != exp_semdata.sem_perm.uid)
		error("sem_perm.uid field was not set!", __LINE__);
	if (act_semdata.sem_perm.cgid != exp_semdata.sem_perm.cgid)
		error("sem_perm.cgid field was not set!", __LINE__);
	if (act_semdata.sem_perm.gid != exp_semdata.sem_perm.gid)
		error("sem_perm.gid field was not set!", __LINE__);
	if (act_semdata.sem_perm.mode != exp_semdata.sem_perm.mode)
		error("sem_perm.mode field was not set!", __LINE__);
	if (act_semdata.sem_nsems != exp_semdata.sem_nsems)
		error("sem_nsems field was not set!", __LINE__);

	/*
	 * Print out the id of the newly created semaphore for comparison
	 * with the 'ipcs -s' command and then exit.
	 */
	printf("%d\n", semid);

	return (0);
}
Beispiel #16
0
/* Return non-zero if successful;  return zero on failure (no lock acquired).
 * If "wait" passed greater than zero do not attempt to assassinate a contender
 * (try to identify and print its PID anyways).  Otherwise, having killed
 * the contender, try to re-acquire the lock (without.
 */
static int/*bool*/ s_Shmem_WLock(int which, int/*bool*/ wait)
{
    static union semun dummy;
    int locked;
    int pid;

#ifdef LBSM_DEBUG
    CORE_LOGF(eLOG_Trace,
              ("LBSM W-lock[%d] acquire%s", which + 1, wait ? " w/wait" : ""));
#endif /*LBSM_DEBUG*/

    if ((locked = s_Shmem_TryWLock(which)) == 0)
        return 1/*success*/;

    if (locked < 0) {
        /* even [1] was not successfully locked, so we have either
         *   a/ a hanging writer, or
         *   b/ a hanging old reader (which doesn't change [2] in block 0 only)
         * In either case, we can try to obtain a PID of the offender.
         */
        if ((pid = semctl(s_Muxid, (which << 1) | 1, GETPID, dummy)) > 0) {
            int self   = (pid_t) pid == getpid();
            int other  = !self  &&  (kill(pid, 0) == 0  ||  errno == EPERM);
            int killed = 0;
            if (!wait) {
                if (other  &&  kill(pid, SIGTERM) == 0) {
                    CORE_LOGF_X(17, eLOG_Warning,
                                ("Terminating PID %lu", (long) pid));
                    sleep(1); /* let them catch SIGTERM and exit gracefully */
                    kill(pid, SIGKILL);
                    killed = 1;
                } else {
                    CORE_LOGF_X(18, eLOG_Warning,
                                ("Unable to kill PID %lu", (long) pid));
                }
            }
            CORE_LOGF_X(19, eLOG_Warning,
                        ("LBSM lock[%d] %s revoked from PID %lu (%s)",
                         which + 1, killed ? "is being" : "has to be",
                         (long) pid, self  ? "self" :
                         other ? (killed ? "killed" : "hanging") : "zombie"));
        } else if (pid < 0)
            return 0/*severe failure: most likely removed IPC id*/;
    } else {
        pid = 0;
        /* [1] was free (now locked) but [2] was taken by someone else,
         * we have a hanging reader, no additional info is available.
         */
        if (!wait) {
            union semun arg;
            arg.val = 1;
            if (semctl(s_Muxid, (which << 1) + 2, SETVAL, arg) < 0) {
                CORE_LOGF_ERRNO_X(9, eLOG_Error, errno,
                                  ("Unable to adjust LBSM access count[%d]",
                                   which + 1));
            }
            wait = 1/*this makes us undo [1] and fail*/;
        }
        if (wait) {
            int x_errno = errno;
            s_Shmem_Unlock(which, 1);
            errno = x_errno;
        }
    }

    if (!pid) {
        int val;
        if ((val = semctl(s_Muxid, (which << 1) + 2, GETVAL, dummy)) > 1) {
            CORE_LOGF_X(20, eLOG_Warning,
                        ("%u hanging readers in LBSM shmem[%d]%s",
                         (unsigned int) val, which + 1, wait ? "" :
                         locked < 0 ? ", revoking lock" : ", lock revoked"));
        } else {
            CORE_LOGF_X(21, eLOG_Warning,
                        ("A hanging reader in LBSM shmem[%d]%s",
                         which + 1, wait ? "" :
                         locked < 0 ? ", revoking lock" : ", lock revoked"));
        }
    }

    if (wait)
        return 0/*failure*/;

    if (locked > 0)
        return 1/*success: good to go*/;

#ifdef LBSM_DEBUG
    CORE_LOGF(eLOG_Trace,
              ("LBSM W-lock[%d] re-acquire", which + 1));
#endif /*LBSM_DEBUG*/
    return s_Shmem_WLock(which, 0/*no wait*/);
}
Beispiel #17
0
void ctrlc_handler(int sig)
{
    union semun dummy;      
    semctl(semid, 0, IPC_RMID, dummy);
    shmctl(shmid, IPC_RMID, NULL); 
}
Beispiel #18
0
void semSet()
{
	semunion.val = count;
	semctl(semid, 0, SETVAL , semunion);
}
Beispiel #19
0
static int swSem_free(swLock *lock)
{
    return semctl(lock->object.sem.semid, 0, IPC_RMID);
}
/**
 * int ipc_comm_cleanup()
 * @brief Cleans up the IPC structure
 * @param ipc structure pointer
 * @return EXIT_FAILURE for unknown type, EXIT_SUCCESS for known/success
 */
int ipc_comm_cleanup(ipc_comm_t* ipc_comm){
	free(ipc_comm->sops);
	semctl(ipc_comm->semid, INTERFACE_CONNECTED, IPC_RMID, 0);
	return EXIT_SUCCESS;
}
Beispiel #21
0
int
main(void)
{
    static const key_t private_key =
        (key_t) (0xffffffff00000000ULL | IPC_PRIVATE);
    static const key_t bogus_key = (key_t) 0xeca86420fdb97531ULL;
    static const int bogus_semid = 0xfdb97531;
    static const int bogus_semnum = 0xeca86420;
    static const int bogus_size = 0xdec0ded1;
    static const int bogus_flags = 0xface1e55;
    static const int bogus_cmd = 0xdeadbeef;
    static const unsigned long bogus_arg =
        (unsigned long) 0xbadc0dedfffffaceULL;

    int rc;
    union semun un;
    struct semid_ds ds;
    struct seminfo info;

    rc = semget(bogus_key, bogus_size, bogus_flags);
    printf("semget\\(%#llx, %d, %s%s%s%#x\\|%#04o\\) += %s\n",
           zero_extend_signed_to_ull(bogus_key), bogus_size,
           IPC_CREAT & bogus_flags ? "IPC_CREAT\\|" : "",
           IPC_EXCL & bogus_flags ? "IPC_EXCL\\|" : "",
           IPC_NOWAIT & bogus_flags ? "IPC_NOWAIT\\|" : "",
           bogus_flags & ~(0777 | IPC_CREAT | IPC_EXCL | IPC_NOWAIT),
           bogus_flags & 0777, sprintrc_grep(rc));

    id = semget(private_key, 1, 0600);
    if (id < 0)
        perror_msg_and_skip("semget");
    printf("semget\\(IPC_PRIVATE, 1, 0600\\) += %d\n", id);
    atexit(cleanup);

    rc = semctl(bogus_semid, bogus_semnum, bogus_cmd, bogus_arg);
#ifdef __GLIBC__
# define SEMCTL_BOGUS_ARG_FMT "(%#lx|\\[(%#lx|NULL)\\])"
#else
# define SEMCTL_BOGUS_ARG_FMT "(%#lx|\\[(%#lx|NULL)\\]|NULL)"
#endif
    printf("semctl\\(%d, %d, (IPC_64\\|)?%#x /\\* SEM_\\?\\?\\? \\*/"
           ", " SEMCTL_BOGUS_ARG_FMT "\\) += %s\n",
           bogus_semid, bogus_semnum, bogus_cmd,
           bogus_arg, bogus_arg, sprintrc_grep(rc));

    un.buf = &ds;
    if (semctl(id, 0, IPC_STAT, un))
        perror_msg_and_skip("semctl IPC_STAT");
    printf("semctl\\(%d, 0, (IPC_64\\|)?IPC_STAT, \\[?%p\\]?\\) += 0\n",
           id, &ds);

    un.__buf = &info;
    rc = semctl(0, 0, SEM_INFO, un);
    printf("semctl\\(0, 0, (IPC_64\\|)?SEM_INFO, \\[?%p\\]?\\) += %s\n",
           &info, sprintrc_grep(rc));

    un.buf = &ds;
    rc = semctl(id, 0, SEM_STAT, un);
    printf("semctl\\(%d, 0, (IPC_64\\|)?SEM_STAT, \\[?%p\\]?\\) += %s\n",
           id, &ds, sprintrc_grep(rc));

    return 0;
}
/* Deallocate a binary semaphore. All users must have finished their
   use. Returns -1 on failure. */
int binary_semaphore_deallocate(int semid) {
	union semun ignored_argument;
	return semctl(semid, 1, IPC_RMID, ignored_argument);
}
Beispiel #23
0
void gds_rundown(void)
{
	bool			is_mm, we_are_last_user, we_are_last_writer;
	boolean_t		ipc_deleted, remove_shm, cancelled_timer, cancelled_dbsync_timer, vermismatch;
	now_t			now;	/* for GET_CUR_TIME macro */
	char			*time_ptr, time_str[CTIME_BEFORE_NL + 2]; /* for GET_CUR_TIME macro */
	gd_region		*reg;
	int			save_errno, status;
	int4			semval, ftok_semval, sopcnt, ftok_sopcnt;
	short			crash_count;
	sm_long_t		munmap_len;
	sgmnt_addrs		*csa;
	sgmnt_data_ptr_t	csd;
	struct shmid_ds		shm_buf;
	struct sembuf		sop[2], ftok_sop[2];
	uint4           	jnl_status;
	unix_db_info		*udi;
	jnl_private_control	*jpc;
	jnl_buffer_ptr_t	jbp;

	error_def(ERR_CRITSEMFAIL);
	error_def(ERR_DBCCERR);
	error_def(ERR_DBFILERR);
	error_def(ERR_DBRNDWNWRN);
	error_def(ERR_ERRCALL);
	error_def(ERR_GBLOFLOW);
	error_def(ERR_GTMASSERT);
	error_def(ERR_IPCNOTDEL);
	error_def(ERR_JNLFLUSH);
	error_def(ERR_RNDWNSEMFAIL);
	error_def(ERR_TEXT);
	error_def(ERR_WCBLOCKED);

	forced_exit = FALSE;		/* Okay, we're dying already -- let rel_crit live in peace now.
					 * If coming through a DAL, not necessarily dying. what to do then? -- nars -- 8/15/2001
					 */
	grabbed_access_sem = FALSE;
	jnl_status = 0;
	reg = gv_cur_region;			/* Local copy */

	/*
	 * early out for cluster regions
	 * to avoid tripping the assert below.
	 * Note:
	 *	This early out is consistent with VMS.  It has been
	 *	noted that all of the gtcm assignments
	 *      to gv_cur_region should use the TP_CHANGE_REG
	 *	macro.  This would also avoid the assert problem
	 *	and should be done eventually.
	 */
	if (dba_cm == reg->dyn.addr->acc_meth)
		return;

	udi = FILE_INFO(reg);
	csa = &udi->s_addrs;
	csd = csa->hdr;
	assert(csa == cs_addrs && csd == cs_data);
	if ((reg->open) && (dba_usr == csd->acc_meth))
	{
		change_reg();
		gvusr_rundown();
		return;
	}
	ESTABLISH(gds_rundown_ch);
	if (!reg->open)				/* Not open, no point to rundown */
	{
		if (reg->opening)		/* Died partway open, kill rest of way */
		{
			rel_crit(reg);
			mutex_cleanup(reg);
/* revist this to handle MM properly  SMW 98/12/16
                        if (NULL != csa->nl)
                        {
                                status = shmdt((caddr_t)csa->nl);
                                if (-1 == status)
                                        send_msg(VARLSTCNT(9) ERR_DBFILERR, 2, DB_LEN_STR(reg),
                                                ERR_TEXT, 2, LEN_AND_LIT("Error during shmdt"), errno);
                        }
*/
			shmdt((caddr_t)csa->nl);
			csa->nl = NULL;
		}
		REVERT;
		return;
	}
	switch(csd->acc_meth)
	{	/* Pass mm and bg through */
	    case dba_bg:
		is_mm = FALSE;
		break;
	    case dba_mm:
		is_mm = TRUE;
		break;
	    case dba_usr:
		assert(FALSE);
	    default:
		REVERT;
		return;
	}
	/* Cancel any pending flush timer for this region by this task */
	CANCEL_DB_TIMERS(reg, cancelled_timer, cancelled_dbsync_timer);
	we_are_last_user = FALSE;
	if (!csa->persistent_freeze)
		region_freeze(reg, FALSE, FALSE, FALSE);
	assert(!csa->read_lock);
	rel_crit(reg);		/* get locks to known state */
	mutex_cleanup(reg);
	/*
	 * We need to guarantee that none else access database file header when semid/shmid fields are reset.
	 * We already have created ftok semaphore in db_init or, mu_rndwn_file and did not remove it.
	 * So just lock it. We do it in blocking mode.
	 */
	if (!ftok_sem_lock(reg, FALSE, FALSE))
		rts_error(VARLSTCNT(4) ERR_DBFILERR, 2, DB_LEN_STR(reg));
	/*
	 * For mupip_jnl_recover we already have database access control semaphore.
	 * We do not release it. We release it from  mur_close_files.
	 */
	if (!mupip_jnl_recover)
	{
		sop[0].sem_num = 0; sop[0].sem_op = 0;	/* Wait for 0 */
		sop[1].sem_num = 0; sop[1].sem_op = 1;	/* Lock */
		sopcnt = 2;
		sop[0].sem_flg = sop[1].sem_flg = SEM_UNDO | IPC_NOWAIT; /* Don't wait the first time thru */
		SEMOP(udi->semid, sop, sopcnt, status);
		if (-1 == status)			/* We couldn't get it in one shot -- see if we already have it */
		{
			save_errno = errno;
			/* see comment about Linux specific difference in behaviour of semctl() with GETPID in gds_rundown_ch() */
			if (semctl(udi->semid, 0, GETPID) == process_id)
			{
				send_msg(VARLSTCNT(5) MAKE_MSG_INFO(ERR_CRITSEMFAIL), 2,
					DB_LEN_STR(reg),
					ERR_RNDWNSEMFAIL);
				REVERT;
				return;			/* Already in rundown for this region */
			}
			if (EAGAIN != save_errno)
			{
				assert(FALSE);
				rts_error(VARLSTCNT(9) ERR_CRITSEMFAIL, 2, DB_LEN_STR(reg),
					ERR_TEXT, 2, RTS_ERROR_TEXT("gds_rundown first semop/semctl"), save_errno);
			}
			sop[0].sem_flg = sop[1].sem_flg = SEM_UNDO;	/* Try again - blocking this time */
			SEMOP(udi->semid, sop, 2, status);
			if (-1 == status)			/* We couldn't get it at all.. */
				rts_error(VARLSTCNT(5) ERR_CRITSEMFAIL, 2, DB_LEN_STR(reg), errno);
		}
	}
	grabbed_access_sem = TRUE;
	/*
	 * We now have the dbinit/rundown lock, so we are alone in this code for this region
	 * and nobody else can attach.
	 * See if we are all alone in accessing this database shared memory.
	 */
	assert(csa->ref_cnt);	/* decrement private ref_cnt before shared ref_cnt decrement. */
	csa->ref_cnt--;		/* Currently journaling logic in gds_rundown() in VMS relies on this order to detect last writer */
	assert(!csa->ref_cnt);
	--csa->nl->ref_cnt;
	if (memcmp(csa->nl->now_running, gtm_release_name, gtm_release_name_len + 1))
	{	/* VERMISMATCH condition. Possible only if DSE */
		assert(dse_running);
		vermismatch = TRUE;
	} else
		vermismatch = FALSE;
	if (-1 == shmctl(udi->shmid, IPC_STAT, &shm_buf))
	{
		save_errno = errno;
		rts_error(VARLSTCNT(9) ERR_CRITSEMFAIL, 2, DB_LEN_STR(reg),
			ERR_TEXT, 2, RTS_ERROR_TEXT("gds_rundown shmctl"), save_errno);
	} else
		we_are_last_user =  (1 == shm_buf.shm_nattch) && !vermismatch;
	assert(!mupip_jnl_recover || we_are_last_user); /* recover => one user */
	if (-1 == (semval = semctl(udi->semid, 1, GETVAL)))
		rts_error(VARLSTCNT(5) ERR_CRITSEMFAIL, 2, DB_LEN_STR(reg), errno);
	we_are_last_writer = (1 == semval) && (FALSE == reg->read_only) && !vermismatch;/* There's one writer left and I am it */
	assert(!(mupip_jnl_recover && !reg->read_only) || we_are_last_writer); /* recover + R/W region => one writer */
	if (-1 == (ftok_semval = semctl(udi->ftok_semid, 1, GETVAL)))
		rts_error(VARLSTCNT(5) ERR_CRITSEMFAIL, 2, DB_LEN_STR(reg), errno);
	/* If csa->nl->donotflush_dbjnl is set, it means mupip recover/rollback was interrupted and therefore we should
	 * 	not flush shared memory contents to disk as they might be in an inconsistent state.
	 * In this case, we will go ahead and remove shared memory (without flushing the contents) in this routine.
	 * A reissue of the recover/rollback command will restore the database to a consistent state.
	 * Otherwise, if we have write access to this region, let us perform a few writing tasks.
	 */
	if (csa->nl->donotflush_dbjnl)
		csa->wbuf_dqd = 0;	/* ignore csa->wbuf_dqd status as we do not care about the cache contents */
	else if (!reg->read_only && !vermismatch)
	{	/* If we had an orphaned block and were interrupted, set wc_blocked so we can invoke wcs_recover */
		if (csa->wbuf_dqd)
		{
			grab_crit(reg);
			SET_TRACEABLE_VAR(csd->wc_blocked, TRUE);
			BG_TRACE_PRO_ANY(csa, wcb_gds_rundown);
                        send_msg(VARLSTCNT(8) ERR_WCBLOCKED, 6, LEN_AND_LIT("wcb_gds_rundown"),
                                process_id, &csa->ti->curr_tn, DB_LEN_STR(reg));
			csa->wbuf_dqd = 0;
			wcs_recover(reg);
			if (is_mm)
			{
				assert(FALSE);
				csd = csa->hdr;
			}
			BG_TRACE_PRO_ANY(csa, lost_block_recovery);
			rel_crit(reg);
		}
		if (JNL_ENABLED(csd) && (GTCM_GNP_SERVER_IMAGE == image_type))
			originator_prc_vec = NULL;
		/* If we are the last writing user, then everything must be flushed */
		if (we_are_last_writer)
		{	/* Time to flush out all of our buffers */
			if (is_mm)
			{
				if (csa->total_blks != csa->ti->total_blks)	/* do remap if file had been extended */
				{
					grab_crit(reg);
					wcs_mm_recover(reg);
					csd = csa->hdr;
					rel_crit(reg);
				}
				csa->nl->remove_shm = TRUE;
			}
			/* Note WCSFLU_SYNC_EPOCH ensures the epoch is synced to the journal and indirectly
			 * also ensures that the db is fsynced. We don't want to use it in the calls to
			 * wcs_flu() from t_end() and tp_tend() since we can defer it to out-of-crit there.
			 * In this case, since we are running down, we don't have any such option.
			 */
			csa->nl->remove_shm = wcs_flu(WCSFLU_FLUSH_HDR | WCSFLU_WRITE_EPOCH | WCSFLU_SYNC_EPOCH);
			/* Since we_are_last_writer, we should be guaranteed that wcs_flu() did not change csd, (in
			 * case of MM for potential file extension), even if it did a grab_crit().  Therefore, make
			 * sure that's true.
			 */
			assert(csd == csa->hdr);
			assert(0 == memcmp(csd->label, GDS_LABEL, GDS_LABEL_SZ - 1));
			csd->trans_hist.header_open_tn = csd->trans_hist.curr_tn;
		} else if ((cancelled_timer && (0 > csa->nl->wcs_timers)) || cancelled_dbsync_timer)
		{	/* cancelled pending db or jnl flush timers - flush database and journal buffers to disk */
			grab_crit(reg);
			/* we need to sync the epoch as the fact that there is no active pending flush timer implies
			 * there will be noone else who will flush the dirty buffers and EPOCH to disk in a timely fashion
			 */
			wcs_flu(WCSFLU_FLUSH_HDR | WCSFLU_WRITE_EPOCH | WCSFLU_SYNC_EPOCH);
			rel_crit(reg);
			assert((dba_mm == cs_data->acc_meth) || (csd == cs_data));
			csd = cs_data;	/* In case this is MM and wcs_flu() remapped an extended database, reset csd */
		}
		/* Do rundown journal processing after buffer flushes since they require jnl to be open */
		if (JNL_ENABLED(csd))
		{	/* the following tp_change_reg() is not needed due to the assert csa == cs_addrs at the beginning
			 * of gds_rundown(), but just to be safe. To be removed by 2002!! --- nars -- 2001/04/25.
			 */
			tp_change_reg();	/* call this because jnl_ensure_open checks cs_addrs rather than gv_cur_region */
			jpc = csa->jnl;
			jbp = jpc->jnl_buff;
			if (jbp->fsync_in_prog_latch.u.parts.latch_pid == process_id)
                        {
                                assert(FALSE);
                                COMPSWAP_UNLOCK(&jbp->fsync_in_prog_latch, process_id, 0, LOCK_AVAILABLE, 0);
                        }
                        if (jbp->io_in_prog_latch.u.parts.latch_pid == process_id)
                        {
                                assert(FALSE);
                                COMPSWAP_UNLOCK(&jbp->io_in_prog_latch, process_id, 0, LOCK_AVAILABLE, 0);
                        }
			if (((NOJNL != jpc->channel) && !JNL_FILE_SWITCHED(jpc))
				|| we_are_last_writer && (0 != csa->nl->jnl_file.u.inode))
			{	/* We need to close the journal file cleanly if we have the latest generation journal file open
				 *	or if we are the last writer and the journal file is open in shared memory (not necessarily
				 *	by ourselves e.g. the only process that opened the journal got shot abnormally)
				 * Note: we should not infer anything from the shared memory value of csa->nl->jnl_file.u.inode
				 * 	if we are not the last writer as it can be concurrently updated.
				 */
				grab_crit(reg);
				if (JNL_ENABLED(csd))
				{
					SET_GBL_JREC_TIME; /* jnl_ensure_open/jnl_put_jrt_pini/pfin/jnl_file_close all need it */
					/* Before writing to jnlfile, adjust jgbl.gbl_jrec_time if needed to maintain time order
					 * of jnl records. This needs to be done BEFORE the jnl_ensure_open as that could write
					 * journal records (if it decides to switch to a new journal file).
					 */
					ADJUST_GBL_JREC_TIME(jgbl, jbp);
					jnl_status = jnl_ensure_open();
					if (0 == jnl_status)
					{	/* If we_are_last_writer, we would have already done a wcs_flu() which would
						 * have written an epoch record and we are guaranteed no further updates
						 * since we are the last writer. So, just close the journal.
						 * Although we assert pini_addr should be non-zero for last_writer, we
						 * play it safe in PRO and write a PINI record if not written already.
						 */
						assert(!jbp->before_images || is_mm
								|| !we_are_last_writer || 0 != jpc->pini_addr);
						if (we_are_last_writer && 0 == jpc->pini_addr)
							jnl_put_jrt_pini(csa);
						if (0 != jpc->pini_addr)
							jnl_put_jrt_pfin(csa);
						/* If not the last writer and no pending flush timer left, do jnl flush now */
						if (!we_are_last_writer && (0 > csa->nl->wcs_timers))
						{
							if (SS_NORMAL == (jnl_status = jnl_flush(reg)))
							{
								assert(jbp->freeaddr == jbp->dskaddr);
								jnl_fsync(reg, jbp->dskaddr);
								assert(jbp->fsync_dskaddr == jbp->dskaddr);
							} else
							{
								send_msg(VARLSTCNT(9) ERR_JNLFLUSH, 2, JNL_LEN_STR(csd),
									ERR_TEXT, 2,
									RTS_ERROR_TEXT("Error with journal flush in gds_rundown"),
									jnl_status);
								assert(NOJNL == jpc->channel);/* jnl file lost has been triggered */
								/* In this routine, all code that follows from here on does not
								 * assume anything about the journaling characteristics of this
								 * database so it is safe to continue execution even though
								 * journaling got closed in the middle.
								 */
							}
						}
						jnl_file_close(reg, we_are_last_writer, FALSE);
					} else
						send_msg(VARLSTCNT(6) jnl_status, 4, JNL_LEN_STR(csd), DB_LEN_STR(reg));
				}
				rel_crit(reg);
			}
		}
		if (we_are_last_writer)			/* Flush the fileheader last and harden the file to disk */
		{
			grab_crit(reg);			/* To satisfy crit requirement in fileheader_sync() */
			memset(csd->machine_name, 0, MAX_MCNAMELEN); /* clear the machine_name field */
			if (!mupip_jnl_recover && we_are_last_user)
			{	/* mupip_jnl_recover will do this after mur_close_file */
				csd->semid = INVALID_SEMID;
				csd->shmid = INVALID_SHMID;
				csd->gt_sem_ctime.ctime = 0;
				csd->gt_shm_ctime.ctime = 0;
			}
			fileheader_sync(reg);
			rel_crit(reg);
			if (FALSE == is_mm)
			{
				if (-1 == fsync(udi->fd))		/* Sync it all */
				{
					rts_error(VARLSTCNT(9) ERR_DBFILERR, 2, DB_LEN_STR(reg),
						  ERR_TEXT, 2, RTS_ERROR_TEXT("Error during file sync at close"), errno);
				}
			} else
			{	/* Now do final MM file sync before exit */
#if !defined(TARGETED_MSYNC) && !defined(NO_MSYNC)
				if (-1 == fsync(udi->fd))		/* Sync it all */
				{
					rts_error(VARLSTCNT(9) ERR_DBFILERR, 2, DB_LEN_STR(reg),
						  ERR_TEXT, 2, RTS_ERROR_TEXT("Error during file sync at close"), errno);
				}
#else
				if (-1 == msync((caddr_t)csa->db_addrs[0], (size_t)(csa->db_addrs[1] - csa->db_addrs[0]), MS_SYNC))
				{
					rts_error(VARLSTCNT(9) ERR_DBFILERR, 2, DB_LEN_STR(reg),
						  ERR_TEXT, 2, RTS_ERROR_TEXT("Error during file msync at close"), errno);
				}
#endif
			}
                }
	} /* end if (!reg->read_only && !csa->nl->donotflush_dbjnl) */
	if (reg->read_only && we_are_last_user && !mupip_jnl_recover)
	{	/* mupip_jnl_recover will do this after mur_close_file */
		db_ipcs.semid = INVALID_SEMID;
		db_ipcs.shmid = INVALID_SHMID;
		db_ipcs.gt_sem_ctime = 0;
		db_ipcs.gt_shm_ctime = 0;
		db_ipcs.fn_len = reg->dyn.addr->fname_len;
		memcpy(db_ipcs.fn, reg->dyn.addr->fname, reg->dyn.addr->fname_len);
		db_ipcs.fn[reg->dyn.addr->fname_len] = 0;
 		/* request gtmsecshr to flush. read_only cannot flush itself */
		if (0 != send_mesg2gtmsecshr(FLUSH_DB_IPCS_INFO, 0, (char *)NULL, 0))
			rts_error(VARLSTCNT(8) ERR_DBFILERR, 2, DB_LEN_STR(reg),
				  ERR_TEXT, 2, RTS_ERROR_TEXT("gtmsecshr failed to update database file header"));
	}
	/* Done with file now, close it */
	if (-1 == close(udi->fd))
	{
		rts_error(VARLSTCNT(9) ERR_DBFILERR, 2, DB_LEN_STR(reg),
			  ERR_TEXT, 2, LEN_AND_LIT("Error during file close"), errno);
	}
	/* Unmap storage if mm mode but only the part that is not the fileheader (so shows up in dumps) */
	if (is_mm)
	{
		munmap_len = (sm_long_t)((csa->db_addrs[1] - csa->db_addrs[0]) - ROUND_UP(SIZEOF_FILE_HDR(csa->hdr),
											 MSYNC_ADDR_INCS));
		if (munmap_len > 0)
		{
			munmap((caddr_t)(csa->db_addrs[0] + ROUND_UP(SIZEOF_FILE_HDR(csa->hdr), MSYNC_ADDR_INCS)),
			       (size_t)(munmap_len));
#ifdef DEBUG_DB64
			rel_mmseg((caddr_t)csa->db_addrs[0]);
#endif
		}
	}
	/* Detach our shared memory while still under lock so reference counts will be
	 * correct for the next process to run down this region.
	 * In the process also get the remove_shm status from node_local before detaching.
	 * If csa->nl->donotflush_dbjnl is TRUE, it means we can safely remove shared memory without compromising data
	 * 	integrity as a reissue of recover will restore the database to a consistent state.
	 */
	remove_shm = !vermismatch && (csa->nl->remove_shm || csa->nl->donotflush_dbjnl);
	status = shmdt((caddr_t)csa->nl);
	csa->nl = NULL; /* dereferencing nl after detach is not right, so we set it to NULL so that we can test before dereference*/
	if (-1 == status)
		send_msg(VARLSTCNT(9) ERR_DBFILERR, 2, DB_LEN_STR(reg), ERR_TEXT, 2, LEN_AND_LIT("Error during shmdt"), errno);
	reg->open = FALSE;

	/* If file is still not in good shape, die here and now before we get rid of our storage */
	if (csa->wbuf_dqd)
		GTMASSERT;
	ipc_deleted = FALSE;
	/* If we are the very last user, remove shared storage id and the semaphores */
	if (we_are_last_user)
	{	/* remove shared storage, only if last writer to rundown did a successful wcs_flu() */
		assert(!vermismatch);
		if (remove_shm)
		{
			ipc_deleted = TRUE;
			if (0 != shm_rmid(udi->shmid))
				rts_error(VARLSTCNT(8) ERR_DBFILERR, 2, DB_LEN_STR(reg),
					ERR_TEXT, 2, RTS_ERROR_TEXT("Unable to remove shared memory"));
		} else if (is_src_server || is_updproc)
		{
			gtm_putmsg(VARLSTCNT(6) ERR_DBRNDWNWRN, 4, DB_LEN_STR(reg), process_id, process_id);
			send_msg(VARLSTCNT(6) ERR_DBRNDWNWRN, 4, DB_LEN_STR(reg), process_id, process_id);
		} else
			send_msg(VARLSTCNT(6) ERR_DBRNDWNWRN, 4, DB_LEN_STR(reg), process_id, process_id);
		/*
		 * Don't release semaphore in case of mupip recover/rollback; since it has standalone access.
		 * It will release the semaphore in mur_close_files.
		 */
		if (!mupip_jnl_recover)
		{
			if (0 != sem_rmid(udi->semid))
				rts_error(VARLSTCNT(8) ERR_DBFILERR, 2, DB_LEN_STR(reg),
					ERR_TEXT, 2, RTS_ERROR_TEXT("Unable to remove semaphore"));
			grabbed_access_sem = FALSE;
		}
	} else
	{
		assert(!mupip_jnl_recover);
		/* If we were writing, get rid of our writer access count semaphore */
		if (!reg->read_only)
			if (0 != (save_errno = do_semop(udi->semid, 1, -1, SEM_UNDO)))
				rts_error(VARLSTCNT(9) ERR_CRITSEMFAIL, 2, DB_LEN_STR(reg),
					ERR_TEXT, 2, RTS_ERROR_TEXT("gds_rundown write semaphore release"), save_errno);
		/* Now remove the rundown lock */
		if (0 != (save_errno = do_semop(udi->semid, 0, -1, SEM_UNDO)))
			rts_error(VARLSTCNT(9) ERR_CRITSEMFAIL, 2, DB_LEN_STR(reg),
				ERR_TEXT, 2, RTS_ERROR_TEXT("gds_rundown rundown semaphore release"), save_errno);
		grabbed_access_sem = FALSE;
	}
	if (!ftok_sem_release(reg, !mupip_jnl_recover, FALSE))
			rts_error(VARLSTCNT(4) ERR_DBFILERR, 2, DB_LEN_STR(reg));
	if (!ipc_deleted)
	{
		GET_CUR_TIME;
		if (is_src_server)
			gtm_putmsg(VARLSTCNT(8) ERR_IPCNOTDEL, 6, CTIME_BEFORE_NL, time_ptr,
				LEN_AND_LIT("Source server"), REG_LEN_STR(reg));
		if (is_updproc)
			gtm_putmsg(VARLSTCNT(8) ERR_IPCNOTDEL, 6, CTIME_BEFORE_NL, time_ptr,
				LEN_AND_LIT("Update process"), REG_LEN_STR(reg));
		if (mupip_jnl_recover)
		{
			gtm_putmsg(VARLSTCNT(8) ERR_IPCNOTDEL, 6, CTIME_BEFORE_NL, time_ptr,
				LEN_AND_LIT("Mupip journal process"), REG_LEN_STR(reg));
			send_msg(VARLSTCNT(8) ERR_IPCNOTDEL, 6, CTIME_BEFORE_NL, time_ptr,
				LEN_AND_LIT("Mupip journal process"), REG_LEN_STR(reg));
		}
	}
	REVERT;
}
Beispiel #24
0
/* 删除信号量 */
int sem_del(int semid) 
{
	union semun sun;
	return semctl (semid, 0, IPC_RMID, sun);

}
void iniSEM(int semID,ushort queSemaforo, int queValor){
semctl(semID,queSemaforo,SETVAL,queValor);
}
Beispiel #26
0
/* 初始化信号量函数*/
int init_sem (int semid, int sem_num, int val)
{
	union semun sun;
	sun.val = val;
	return semctl (semid, sem_num, SETVAL, sun);
}
Beispiel #27
0
CSem::~CSem()
{
	if(-1 == semctl(m_SemId, 0, IPC_RMID)){
		cerr << "error remove sem!" << endl;
	}
}
Beispiel #28
0
/*
 * Create a semaphore set with the given number of useful semaphores
 * (an additional sema is actually allocated to serve as identifier).
 * Dead Postgres sema sets are recycled if found, but we do not fail
 * upon collision with non-Postgres sema sets.
 *
 * The idea here is to detect and re-use keys that may have been assigned
 * by a crashed postmaster or backend.
 */
static IpcSemaphoreId
IpcSemaphoreCreate(int numSems)
{
	IpcSemaphoreId semId;
	union semun semun;
	PGSemaphoreData mysema;

	/* Loop till we find a free IPC key */
	for (nextSemaKey++;; nextSemaKey++)
	{
		pid_t		creatorPID;

		/* Try to create new semaphore set */
		semId = InternalIpcSemaphoreCreate(nextSemaKey, numSems + 1);
		if (semId >= 0)
			break;				/* successful create */

		/* See if it looks to be leftover from a dead Postgres process */
		semId = semget(nextSemaKey, numSems + 1, 0);
		if (semId < 0)
			continue;			/* failed: must be some other app's */
		if (IpcSemaphoreGetValue(semId, numSems) != PGSemaMagic)
			continue;			/* sema belongs to a non-Postgres app */

		/*
		 * If the creator PID is my own PID or does not belong to any extant
		 * process, it's safe to zap it.
		 */
		creatorPID = IpcSemaphoreGetLastPID(semId, numSems);
		if (creatorPID <= 0)
			continue;			/* oops, GETPID failed */
		if (creatorPID != getpid())
		{
			if (kill(creatorPID, 0) == 0 || errno != ESRCH)
				continue;		/* sema belongs to a live process */
		}

		/*
		 * The sema set appears to be from a dead Postgres process, or from a
		 * previous cycle of life in this same process.  Zap it, if possible.
		 * This probably shouldn't fail, but if it does, assume the sema set
		 * belongs to someone else after all, and continue quietly.
		 */
		semun.val = 0;			/* unused, but keep compiler quiet */
		if (semctl(semId, 0, IPC_RMID, semun) < 0)
			continue;

		/*
		 * Now try again to create the sema set.
		 */
		semId = InternalIpcSemaphoreCreate(nextSemaKey, numSems + 1);
		if (semId >= 0)
			break;				/* successful create */

		/*
		 * Can only get here if some other process managed to create the same
		 * sema key before we did.	Let him have that one, loop around to try
		 * next key.
		 */
	}

	/*
	 * OK, we created a new sema set.  Mark it as created by this process. We
	 * do this by setting the spare semaphore to PGSemaMagic-1 and then
	 * incrementing it with semop().  That leaves it with value PGSemaMagic
	 * and sempid referencing this process.
	 */
	IpcSemaphoreInitialize(semId, numSems, PGSemaMagic - 1);
	mysema.semId = semId;
	mysema.semNum = numSems;
	PGSemaphoreUnlock(&mysema);

	return semId;
}
Beispiel #29
0
void mm_core_delete(void *core)
{
    mem_core *mc;
#if defined(MM_SHMT_IPCSHM)
    int fdmem;
#endif
    int fdsem;
#if defined(MM_SEMT_IPCSEM)
    int fdsem_rd;
#endif
    size_t size;
#if defined(MM_SHMT_MMFILE)
    char fnmem[MM_MAXPATH];
#endif
#if defined(MM_SEMT_FLOCK) || defined(MM_SEMT_FCNTL)
    char fnsem[MM_MAXPATH];
#endif

    if (core == NULL)
        return;
    mc = (mem_core *)((char *)core-SIZEOF_mem_core);
    size  = mc->mc_size;
#if defined(MM_SHMT_IPCSHM)
    fdmem = mc->mc_fdmem;
#endif
#if !defined(MM_SEMT_FLOCK)
    fdsem = mc->mc_fdsem;
#endif
#if defined(MM_SEMT_IPCSEM)
    fdsem_rd = mc->mc_fdsem_rd;
#endif
#if defined(MM_SEMT_FLOCK)
    fdsem = mm_core_getfdsem(mc);
#endif
#if defined(MM_SHMT_MMFILE)
    memcpy(fnmem, mc->mc_fnmem, MM_MAXPATH);
#endif
#if defined(MM_SEMT_FLOCK) || defined(MM_SEMT_FCNTL)
    memcpy(fnsem, mc->mc_fnsem, MM_MAXPATH);
#endif

#if defined(MM_SHMT_MMANON) || defined(MM_SHMT_MMPOSX) || defined(MM_SHMT_MMZERO) || defined(MM_SHMT_MMFILE)
    munmap((caddr_t)mc, size);
#endif
#if defined(MM_SHMT_IPCSHM)
    shmdt((void *)mc);
    shmctl(fdmem, IPC_RMID, NULL);
#endif
#if defined(MM_SHMT_MMFILE)
    unlink(fnmem);
#endif
#if defined(MM_SEMT_FLOCK) || defined(MM_SEMT_FCNTL)
    close(fdsem);
#endif
#if defined(MM_SEMT_FLOCK) || defined(MM_SEMT_FCNTL)
    unlink(fnsem);
#endif
#if defined(MM_SEMT_IPCSEM)
    semctl(fdsem, 0, IPC_RMID, 0);
    semctl(fdsem_rd, 0, IPC_RMID, 0);
#endif
    return;
}
Beispiel #30
0
int ipcrm_main(int argc, char **argv)
{
	int c;
	int error = 0;

	/* if the command is executed without parameters, do nothing */
	if (argc == 1)
		return 0;
#ifndef CONFIG_IPCRM_DROP_LEGACY
	/* check to see if the command is being invoked in the old way if so
	   then run the old code. Valid commands are msg, shm, sem. */
	{
		type_id what = 0; /* silence gcc */
		char w;

		w=argv[1][0];
		if ( ((w == 'm' && argv[1][1] == 's' && argv[1][2] == 'g')
		       || (argv[1][0] == 's'
		           && ((w=argv[1][1]) == 'h' || w == 'e')
		           && argv[1][2] == 'm')
		     ) && argv[1][3] == '\0'
		) {

			if (argc < 3)
				bb_show_usage();

			if (w == 'h')
				what = SHM;
			else if (w == 'm')
				what = MSG;
			else if (w == 'e')
				what = SEM;

			if (remove_ids(what, argc-2, &argv[2]))
				fflush_stdout_and_exit(1);
			printf("resource(s) deleted\n");
			return 0;
		}
	}
#endif /* #ifndef CONFIG_IPCRM_DROP_LEGACY */

	/* process new syntax to conform with SYSV ipcrm */
	while ((c = getopt(argc, argv, "q:m:s:Q:M:S:h?")) != -1) {
		int result;
		int id = 0;
		int iskey = (isupper)(c);

		/* needed to delete semaphores */
		union semun arg;

		arg.val = 0;

		if ((c == '?') || (c == 'h')) {
			bb_show_usage();
		}

		/* we don't need case information any more */
		c = tolower(c);

		/* make sure the option is in range: allowed are q, m, s */
		if (c != 'q' && c != 'm' && c != 's') {
			bb_show_usage();
		}

		if (iskey) {
			/* keys are in hex or decimal */
			key_t key = xstrtoul(optarg, 0);

			if (key == IPC_PRIVATE) {
				error++;
				bb_error_msg("illegal key (%s)", optarg);
				continue;
			}

			/* convert key to id */
			id = ((c == 'q') ? msgget(key, 0) :
				  (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0));

			if (id < 0) {
				char *errmsg;
				const char * const what = "key";

				error++;
				switch (errno) {
				case EACCES:
					errmsg = "permission denied for";
					break;
				case EIDRM:
					errmsg = "already removed";
					break;
				case ENOENT:
					errmsg = "invalid";
					break;
				default:
					errmsg = "unknown error in";
					break;
				}
				bb_error_msg("%s %s (%s)",  errmsg, what, optarg);
				continue;
			}
		} else {
			/* ids are in decimal */
			id = xatoul(optarg);
		}

		result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) :
				  (c == 'm') ? shmctl(id, IPC_RMID, NULL) :
				  semctl(id, 0, IPC_RMID, arg));

		if (result) {
			char *errmsg;
			const char * const what = iskey ? "key" : "id";

			error++;
			switch (errno) {
			case EACCES:
			case EPERM:
				errmsg = "permission denied for";
				break;
			case EINVAL:
				errmsg = "invalid";
				break;
			case EIDRM:
				errmsg = "already removed";
				break;
			default:
				errmsg = "unknown error in";
				break;
			}
			bb_error_msg("%s %s (%s)", errmsg, what, optarg);
			continue;
		}
	}

	/* print usage if we still have some arguments left over */
	if (optind != argc) {
		bb_show_usage();
	}

	/* exit value reflects the number of errors encountered */
	return error;
}