/** * \brief Get a new host * * Get a new host. We're checking memcap first and will try to make room * if the memcap is reached. * * \retval h *LOCKED* host on succes, NULL on error. */ static Host *HostGetNew(Address *a) { Host *h = NULL; /* get a host from the spare queue */ h = HostDequeue(&host_spare_q); if (h == NULL) { /* If we reached the max memcap, we get a used host */ if (!(HOST_CHECK_MEMCAP(sizeof(Host)))) { /* declare state of emergency */ //if (!(SC_ATOMIC_GET(host_flags) & HOST_EMERGENCY)) { // SC_ATOMIC_OR(host_flags, HOST_EMERGENCY); /* under high load, waking up the flow mgr each time leads * to high cpu usage. Flows are not timed out much faster if * we check a 1000 times a second. */ // FlowWakeupFlowManagerThread(); //} h = HostGetUsedHost(); if (h == NULL) { return NULL; } /* freed a host, but it's unlocked */ } else { /* now see if we can alloc a new host */ h = HostNew(a); if (h == NULL) { return NULL; } /* host is initialized but *unlocked* */ } } else { /* host has been recycled before it went into the spare queue */ /* host is initialized (recylced) but *unlocked* */ } (void) SC_ATOMIC_ADD(host_counter, 1); SCMutexLock(&h->m); return h; }
/** \brief shutdown the flow engine * \warning Not thread safe */ void HostShutdown(void) { Host *h; uint32_t u; HostPrintStats(); /* free spare queue */ while((h = HostDequeue(&host_spare_q))) { BUG_ON(SC_ATOMIC_GET(h->use_cnt) > 0); HostFree(h); } /* clear and free the hash */ if (host_hash != NULL) { for (u = 0; u < host_config.hash_size; u++) { Host *h = host_hash[u].head; while (h) { Host *n = h->hnext; HostClearMemory(h); HostFree(h); h = n; } HRLOCK_DESTROY(&host_hash[u]); } SCFree(host_hash); host_hash = NULL; } (void) SC_ATOMIC_SUB(host_memuse, host_config.hash_size * sizeof(HostHashRow)); HostQueueDestroy(&host_spare_q); SC_ATOMIC_DESTROY(host_prune_idx); SC_ATOMIC_DESTROY(host_memuse); SC_ATOMIC_DESTROY(host_counter); //SC_ATOMIC_DESTROY(flow_flags); return; }