Ejemplo n.º 1
0
static enum ach_status wrlock(ach_channel_t * chan)
{
    enum ach_status r = chan_lock(chan) ;
    if( ACH_OK != r ) return r;
    chan->shm->sync.dirty = 1;
    return ACH_OK;
}
Ejemplo n.º 2
0
Archivo: ach.c Proyecto: penghou620/ach
static enum ach_status
rdlock( ach_channel_t *chan, int wait, const struct timespec *abstime ) {

    ach_header_t *shm = chan->shm;
    {
        enum ach_status r = chan_lock(chan);
        if( ACH_OK != r ) return r;
    }
    enum ach_status r = ACH_BUG;

    while(ACH_BUG == r) {
        if( chan->cancel ) {  /* check operation cancelled */
            pthread_mutex_unlock( &shm->sync.mutex );
            r = ACH_CANCELED;
        } else if( !wait ) r = ACH_OK;                          /* check no wait */
        else if ( chan->seq_num != shm->last_seq ) r = ACH_OK;  /* check if got a frame */
        /* else condition wait */
        else {
            int i = abstime ?
                pthread_cond_timedwait( &shm->sync.cond,  &shm->sync.mutex, abstime ) :
                pthread_cond_wait( &shm->sync.cond,  &shm->sync.mutex );
            enum ach_status c = check_lock(i, chan, 1);
            if( ACH_OK != c ) r = c;
            /* check r and condition next iteration */
        }
    }

    return r;
}
Ejemplo n.º 3
0
static enum ach_status
rdlock_wait(ach_channel_t * chan, const struct timespec *reltime)
{
    int res;
    struct ach_header *shm = chan->shm;
    volatile uint64_t *c_seq = &chan->seq_num, *s_seq = &shm->last_seq;
    volatile unsigned int *cancel = &chan->cancel;
    enum ach_status r;

    for(;;) {
        /* do the wait */
        if (reltime->tv_sec != 0 || reltime->tv_nsec != 0) {
            res = wait_event_interruptible_timeout( shm->sync. readq,
            ((*c_seq != *s_seq) || *cancel),
            timespec_to_jiffies (reltime) );
            if (0 == res) return ACH_TIMEOUT;
        } else {
            res = wait_event_interruptible( shm->sync.readq,
                                            ((*c_seq != *s_seq) || *cancel) );
        }

        /* check what happened */
        if (-ERESTARTSYS == res) return ACH_EINTR;
        if( res < 0 ) {
            ACH_ERRF("ach bug: rdlock_wait(), "
                     "could not wait for event, "
                     "timeout: (%lu,%ld), result=%d\n",
                     reltime->tv_sec, reltime->tv_nsec, res);
            return ACH_BUG;
        }

        r = chan_lock( chan );
        /* Check condition with the lock held in case someone
         * else flushed the channel, or someone else unset the
         * cancel */
        if( (*c_seq != *s_seq) || (ACH_OK != r) || *cancel ) {
            return r;
        }
        rt_mutex_unlock(&shm->sync.mutex);
    }
}
Ejemplo n.º 4
0
static unsigned int ach_ch_poll(struct file *file, poll_table * wait)
{
    unsigned int mask = POLLOUT | POLLWRNORM;
    struct ach_ch_file *ch_file = (struct ach_ch_file *)file->private_data;
    struct ach_header *shm = ch_file->shm;
    enum ach_status r;

    /* KDEBUG1("In ach_ch_poll (minor=%d)\n", ch_file->dev->minor); */

    /* Add ourselves wait queue */
    poll_wait(file, &shm->sync.readq, wait);

    /* Lock channel and check what happened */
    r = chan_lock(ch_file);
    if( ACH_OK != r ) return -get_errno(r);

    if (ch_file->seq_num != shm->last_seq) {
        mask |= POLLIN | POLLRDNORM;
    }

    rt_mutex_unlock(&shm->sync.mutex);

    return mask;
}
Ejemplo n.º 5
0
static enum ach_status
rdlock(ach_channel_t * chan, int wait, const struct timespec *reltime)
{
    if( wait ) return rdlock_wait(chan, reltime);
    else return chan_lock(chan);
}