#include #include #include #include #include #include #include #include "semarray.h" void semarray::init_creator(const char *lockname, int size) { int fd=open(lockname,O_RDONLY); close(fd); if (fd>=0) { fprintf(stderr,"lock %s exists\n",lockname); exit(1); } semid=semget(IPC_PRIVATE,size,0666|IPC_CREAT); if (semid<0) { perror("semget"); exit(1); } fd=open(lockname,O_CREAT|O_TRUNC|O_WRONLY,0644); if (fd<0) { perror(lockname); exit(1); } write(fd,&semid,sizeof(semid)); close(fd); lockfile=strdup(lockname); } semarray::semarray(const char *lockname, int size, int value) : creator(true), lockfile(0), numsem(size), sembuffer(new(struct sembuf)[size]) { init_creator(lockname,size); union semun sem_union; sem_union.val=value; for (int i=0;isem_nsems; sembuffer=new(struct sembuf)[numsem]; } semarray::~semarray() { if (creator) { union semun dummy; semctl(semid,0,IPC_RMID,dummy); if (lockfile) { unlink(lockfile); free((char *)lockfile); } } delete[] sembuffer; } void semarray::sem_up_down(int semnum, int value) { struct sembuf sbuf={ semnum, value, 0 }; if (semnum>=numsem) { fprintf(stderr,"illegal semaphore\n"); exit(1); } if (semop(semid,&sbuf,1)) { perror("semop1"); exit(1); } } void semarray::sdown_sup(va_list &ap, int size, int value) { struct sembuf *P=sembuffer; for (int i=0;i=numsem) { fprintf(stderr,"illegal semaphore\n"); exit(1); } P->sem_num=semnum; P->sem_op=value; P->sem_flg=0; } va_end(ap); if (semop(semid,sembuffer,size)) { perror("semop2"); exit(1); } } void semarray::sdown(int size, ...) { va_list ap; va_start(ap,size); sdown_sup(ap,size,-1); } void semarray::sup(int size, ...) { va_list ap; va_start(ap,size); sdown_sup(ap,size,1); }