/* 如sem[index]为负且不超时,则阻塞,超时则返回EAGAIN,否则将信号量减1,返回0*/ int TryLockSemaphore(int semid, int index, int milliseconds) { int ret; struct sembuf operation; operation.sem_num = index; operation.sem_op = -1; if(milliseconds<1) { operation.sem_flg = IPC_NOWAIT; ret= semop (semid, &operation, 1); } else { operation.sem_flg = SEM_UNDO; struct timespec timeout; timeout.tv_sec = (milliseconds / 1000); timeout.tv_nsec = (milliseconds - timeout.tv_sec*1000L)*1000000L; ret= semtimedop(semid, &operation, 1, &timeout); } if(ret == -1) { if(errno == EAGAIN) return EAGAIN; } return (ret == -1)? WhenError("Wait(semop)", errno):ret; }
int SetSemaphoreValues(int semid, unsigned short * values) { union semun argument; argument.array=values; int ret; ret= semctl(semid,0,SETALL,argument); return (ret == -1)? WhenError("Set Values(semctl)", errno):ret; }
/* Set a semaphore to a value。*/ int SetSemaphoreValue(int semid, int index, int value) { union semun argument; argument.val = value; int ret; ret= semctl(semid,index,SETVAL,argument); return (ret == -1)? WhenError("Set Value(semctl)", errno):ret; }
/* 将sem[index]值加一。 这个操作会立即返回,应配合LockSemaphore一起使用。*/ int UnlockSemaphore(int semid, int index) { struct sembuf operation; operation.sem_num = index; operation.sem_op = 1; /* 加一 */ operation.sem_flg = SEM_UNDO; /* 允许撤销操作 */ int ret; ret= semop(semid, &operation, 1); return (ret == -1)? WhenError("Post(semctl)", errno):ret; }
/* 如果sem[index]为负,则阻塞,直到信号量值为正,然后将其减1*/ int LockSemaphore(int semid, int index) { struct sembuf operation; operation.sem_num = index; operation.sem_op = -1; /* 减一。 */ operation.sem_flg = SEM_UNDO; /* 允许撤销操作 */ int ret; ret= semop (semid, &operation, 1); return (ret == -1)? WhenError("Wait(semop)", errno):ret; }
/* 获取一个count元信号量的标识符。如果需要则创建这个信号量 */ int CreateSemaphore(int count) { // key_t key; // key = ftok("/var/httcsec",IPC_ID); // printf("key:%d\n", (int)key); int semid; semid = semget ((key_t)12345, count, 0666|IPC_CREAT); if(EEXIST == semid) printf("exist semid\n"); return (semid == -1)? WhenError("create sem(semget)", errno):semid; }
void Lex::ThrowError(const char *e) { WhenError(e); throw Parser::Error(); }
int GetSemaphoreValue(int semid, int index) { int ret = semctl(semid,index,GETVAL,0); return (ret == -1)? WhenError("Get Value(semctl)", errno):ret; }