Пример #1
0
/**
 *  \brief time out hosts from the hash
 *
 *  \param ts timestamp
 *
 *  \retval cnt number of timed out host
 */
uint32_t HostTimeoutHash(struct timeval *ts) {
    uint32_t idx = 0;
    uint32_t cnt = 0;

    for (idx = 0; idx < host_config.hash_size; idx++) {
        HostHashRow *hb = &host_hash[idx];
        if (hb == NULL)
            continue;
        if (HRLOCK_TRYLOCK(hb) != 0)
            continue;

        /* host hash bucket is now locked */

        if (hb->tail == NULL) {
            HRLOCK_UNLOCK(hb);
            continue;
        }

        /* we have a host, or more than one */
        cnt += HostHashRowTimeout(hb, hb->tail, ts);
        HRLOCK_UNLOCK(hb);
    }

    return cnt;
}
Пример #2
0
/** \internal
 *  \brief Get a host from the hash directly.
 *
 *  Called in conditions where the spare queue is empty and memcap is reached.
 *
 *  Walks the hash until a host can be freed. "host_prune_idx" atomic int makes
 *  sure we don't start at the top each time since that would clear the top of
 *  the hash leading to longer and longer search times under high pressure (observed).
 *
 *  \retval h host or NULL
 */
static Host *HostGetUsedHost(void) {
    uint32_t idx = SC_ATOMIC_GET(host_prune_idx) % host_config.hash_size;
    uint32_t cnt = host_config.hash_size;

    while (cnt--) {
        if (++idx >= host_config.hash_size)
            idx = 0;

        HostHashRow *hb = &host_hash[idx];
        if (hb == NULL)
            continue;

        if (HRLOCK_TRYLOCK(hb) != 0)
            continue;

        Host *h = hb->tail;
        if (h == NULL) {
            HRLOCK_UNLOCK(hb);
            continue;
        }

        if (SCMutexTrylock(&h->m) != 0) {
            HRLOCK_UNLOCK(hb);
            continue;
        }

        /** never prune a host that is used by a packets
         *  we are currently processing in one of the threads */
        if (SC_ATOMIC_GET(h->use_cnt) > 0) {
            HRLOCK_UNLOCK(hb);
            SCMutexUnlock(&h->m);
            continue;
        }

        /* remove from the hash */
        if (h->hprev != NULL)
            h->hprev->hnext = h->hnext;
        if (h->hnext != NULL)
            h->hnext->hprev = h->hprev;
        if (hb->head == h)
            hb->head = h->hnext;
        if (hb->tail == h)
            hb->tail = h->hprev;

        h->hnext = NULL;
        h->hprev = NULL;
        HRLOCK_UNLOCK(hb);

        HostClearMemory (h);

        SCMutexUnlock(&h->m);

        (void) SC_ATOMIC_ADD(host_prune_idx, (host_config.hash_size - cnt));
        return h;
    }

    return NULL;
}