示例#1
0
文件: sxe-dirwatch.c 项目: davidu/sxe
static void
sxe_dirwatch_event(EV_P_ ev_io * io, int revents)
{
    char                   buffer[8192];
    int                    length;
    unsigned               offset;
    struct inotify_event * event;

    SXE_UNUSED_PARAMETER(revents);
    SXEE62("(fd=%d, revents=%08x)", io->fd, revents);
    SXEA11((length = read(io->fd, buffer, sizeof(buffer))) >= 0, "sxe_dirwatch_event: Failed to read events from inotify: %s",
            strerror(errno));

    for (offset = 0; offset < (unsigned)length;)
    {
        SXE_LIST_WALKER walker;
        SXE_DIRWATCH  * dirwatch;
        int             flags = 0;

        SXEA12(length - offset >= sizeof(struct inotify_event),
               "Odd sized chunk left in buffer %u (expected inotify event of %u bytes)",
               length - offset, sizeof(struct inotify_event));
        event = (struct inotify_event *)&buffer[offset];
        offset += sizeof(struct inotify_event);
        SXEA12(length - offset >= event->len, "Chunk left in buffer %u (expected length %u)", length - offset, event->len);
        offset += event->len;
        SXEL63("dirwatch_event: fd=%d flags=%08x file=%s", event->wd, event->mask, event->name);
        sxe_list_walker_construct(&walker, &sxe_dirwatch_list);

        while ((dirwatch = (SXE_DIRWATCH *)sxe_list_walker_step(&walker)) != NULL) {
            if (dirwatch->fd == event->wd) {
                break;
            }
        }

        SXEA11(dirwatch, "No watched directory found with fd %d", event->wd);

        flags |= (event->mask & IN_CREATE)     ? SXE_DIRWATCH_CREATED  : 0;
        flags |= (event->mask & IN_MOVED_TO)   ? SXE_DIRWATCH_CREATED  : 0;
        flags |= (event->mask & IN_MODIFY)     ? SXE_DIRWATCH_MODIFIED : 0;
        flags |= (event->mask & IN_DELETE)     ? SXE_DIRWATCH_DELETED  : 0;
        flags |= (event->mask & IN_MOVED_FROM) ? SXE_DIRWATCH_DELETED  : 0;

        dirwatch->notify(EV_A_ event->name, flags, dirwatch->user_data);
    }

    SXER60("return");
}
示例#2
0
/**
 * Construct a pool state walker (AKA iterator)
 *
 * @param walker Pointer to the walker
 * @param array  Pointer to the pool array
 * @param state  State to walk
 *
 * @exception If the pool is both locked and timed, it cannot be walked safely
 */
void
sxe_pool_walker_construct(SXE_POOL_WALKER * walker, void * array, unsigned state)
{
    SXE_POOL_IMPL * pool = SXE_POOL_ARRAY_TO_IMPL(array);

    SXEE83("sxe_pool_walker_construct(walker=%p,pool=%s,state=%s)", walker, pool->name, (*pool->state_to_string)(state));
    SXEA11(!((pool->options & SXE_POOL_OPTION_LOCKED) && (pool->options & SXE_POOL_OPTION_TIMED)),
           "sxe_pool_walker_construct: Can't walk thread safe timed pool %s safely", pool->name);
    sxe_list_walker_construct(&walker->list_walker, &SXE_POOL_QUEUE(pool)[state]);
    walker->pool  = pool;
    walker->state = state;

    if (pool->options & SXE_POOL_OPTION_TIMED) {
        walker->last.time  = 0.0;
    }
    else {
        walker->last.count = 0;
    }

    SXER80("return");
}
示例#3
0
/**
 * Step to the next object in a pool state
 *
 * @param walker Pointer to the pool state walker
 *
 * @return Index of the next object or SXE_POOL_NO_INDEX if the end of the state queue has been reached.
 *
 * @note Thread safety is implemented by verifying that the last node stepped to is still in the same state queue. If it is not,
 *       the state queue is rewalked to find a node with a time or count greater than or equal to the time that the last stepped
 *       to node had when it was stepped to.
 */
unsigned
sxe_pool_walker_step(SXE_POOL_WALKER * walker)
{
    SXE_POOL_NODE * node;
    SXE_POOL_IMPL * pool = walker->pool;
    unsigned        result;

    SXEE81("sxe_pool_walker_step(walker=%p)", walker);

    if ((result = sxe_pool_lock(pool)) == SXE_POOL_LOCK_NOT_TAKEN) {
        goto SXE_ERROR_OUT;
    }

    /* If not at the head of the state queue and the current object has been moved to another state.
     */
    if (((node = sxe_list_walker_find(&walker->list_walker)) != NULL)
            && (SXE_LIST_NODE_GET_ID(&node->list_node) != walker->state))
        /* TODO: Check for touching */
    {
        SXEL83("sxe_pool_walker_step: node %u moved from state %s to state %s by another thread", node - SXE_POOL_NODES(pool),
               (*pool->state_to_string)(walker->state), (*pool->state_to_string)(SXE_LIST_NODE_GET_ID(&node->list_node)));

        /* If there is a previous object and it has not been moved, get the new next one.
         */
        if (((node = sxe_list_walker_back(&walker->list_walker)) != NULL)
                && (SXE_LIST_NODE_GET_ID(&node->list_node) == walker->state))
            /* TODO: Check for touching */
        {
            node = sxe_list_walker_step(&walker->list_walker);
        }
        else {
            sxe_list_walker_construct(&walker->list_walker, &SXE_POOL_QUEUE(pool)[walker->state]);

            while ((node = sxe_list_walker_step(&walker->list_walker)) != NULL) {
                if (pool->options & SXE_POOL_OPTION_TIMED) {
                    if (node->last.time >= walker->last.time) {    /* Coverage Exclusion: TODO refactor SXE_POOL_TIME */
                        break;                                     /* Coverage Exclusion: TODO refactor SXE_POOL_TIME */
                    }
                }
                else {
                    if (node->last.count >= walker->last.count) {
                        break;
                    }
                }
            }
        }
    }
    else {
        node = sxe_list_walker_step(&walker->list_walker);
    }

    result = SXE_POOL_NO_INDEX;

    if (node != NULL) {
        result = node - SXE_POOL_NODES(pool);

        if (pool->options & SXE_POOL_OPTION_TIMED) {
            walker->last.time  = node->last.time;
        }
        else {
            walker->last.count = node->last.count;
        }
    }

    sxe_pool_unlock(pool);

SXE_ERROR_OUT:
    SXER81("return %s", sxe_pool_return_to_string(result));
    return result;
}