Exemplo n.º 1
0
/* Return locked block number {0, 1}, or -1 on error */
static int/*tri-state*/ s_Shmem_RLock(int which)
{
#ifdef LBSM_DEBUG
    CORE_LOG(eLOG_Trace, "LBSM R-lock acquire (%d)", which + 1);
#endif /*LBSM_DEBUG*/
    /* For block 1 then block 0: check [1] first, then continue with [2] */
    if (s_Shmem_Lock(which, 1, which/*1:no-wait,0:wait*/) == 0)
        return which/*block locked*/;
    return !which  ||  errno == EINVAL ? -1 : s_Shmem_Lock(0, 1, 0/*wait*/);
}
Exemplo n.º 2
0
/* Return locked block number {0, 1}, or -1 in error */
static int/*tri-state*/ s_Shmem_RLock(void)
{
#ifdef LBSM_DEBUG
    CORE_LOG(eLOG_Trace, "LBSM R-lock acquire");
#endif /*LBSM_DEBUG*/
    /* For block 1, then block 0: check [1] first, then continue with [2] */
    if (s_Shmem_Lock(1, 1, 1/*no-wait*/) == 0)
        return 1/*block 1 locked*/;
    return errno == EINVAL ? -1 : s_Shmem_Lock(0, 1, 0/*wait*/);
}
Exemplo n.º 3
0
static int/*tri-state-bool, inverted*/ s_Shmem_TryWLock(int which)
{
    int semnum = (which << 1) | 1;
    int/*bool*/ no_undo = 0;
    struct sembuf rwlock[2];
    int i = 0;

    for (;;) {
        rwlock[0].sem_num = semnum;
        rwlock[0].sem_op  = 0; /* precondition:  [1] == 0 */
        rwlock[0].sem_flg = 0;
        rwlock[1].sem_num = semnum;
        rwlock[1].sem_op  = 1; /* postcondition: [1] == 1 */
        rwlock[1].sem_flg = no_undo ? 0 : SEM_UNDO;

        if (semop(s_Muxid, rwlock, sizeof(rwlock)/sizeof(rwlock[0])) >= 0) {
            /* No new read accesses are allowed after this point */
            s_NoUndo[semnum - 1] = no_undo;
            /* Look at [2] first, then continue with it */
            if (s_Shmem_Lock(which, 2, 0/*wait*/) != 0)
                return 1/*partially locked*/;
            return 0/*okay*/;
        }
        if (i)
            break;
        i = errno;
        if (i == ENOSPC) {
            CORE_LOGF_X(8, eLOG_Warning,
                        ("LBSM PreW-locking[%d] w/o undo", which + 1));
            no_undo = 1;
            continue;
        }
        if (i == EINTR)
            continue;
        if (i != ENOMEM)
            break;
#ifdef LBSM_DEBUG
        CORE_LOGF(eLOG_Trace,
                  ("LBSM PreW-lock[%d] wait(ENOMEM)", which + 1));
#endif/*LBSM_DEBUG*/
        sleep(1);
    }
    return -1/*not locked*/;
}