ret_t cherokee_resolv_cache_get_addrinfo (cherokee_resolv_cache_t *resolv, cherokee_buffer_t *domain, const struct addrinfo **addr_info) { ret_t ret; cherokee_resolv_cache_entry_t *entry = NULL; /* Look for the name in the cache */ CHEROKEE_RWLOCK_READER (&resolv->lock); ret = cherokee_avl_get (&resolv->table, domain, (void **)&entry); CHEROKEE_RWLOCK_UNLOCK (&resolv->lock); if (ret != ret_ok) { TRACE (ENTRIES, "Resolve '%s': missed.\n", domain->buf); /* Bad luck: it wasn't cached */ ret = table_add_new_entry (resolv, domain, &entry); if (ret != ret_ok) { TRACE (ENTRIES, "Resolve '%s': error ret=%d.\n", domain->buf, ret); return ret; } TRACE (ENTRIES, "Resolve '%s': added succesfuly as '%s'.\n", domain->buf, entry->ip_str.buf); } else { TRACE (ENTRIES, "Resolve '%s': hit.\n", domain->buf); } *addr_info = entry->addr; return ret_ok; }
static ret_t table_add_new_entry (cherokee_resolv_cache_t *resolv, cherokee_buffer_t *domain, cherokee_resolv_cache_entry_t **entry) { ret_t ret; cherokee_resolv_cache_entry_t *n = NULL; /* Instance the entry */ ret = entry_new (&n); if (unlikely (ret != ret_ok)) { return ret; } /* Fill it up */ ret = entry_fill_up (n, domain); if (unlikely (ret != ret_ok)) { entry_free (n); return ret; } /* Add it to the table */ CHEROKEE_RWLOCK_WRITER (&resolv->lock); ret = cherokee_avl_add (&resolv->table, domain, (void **)n); CHEROKEE_RWLOCK_UNLOCK (&resolv->lock); *entry = n; return ret_ok; }
ret_t cherokee_resolv_cache_clean (cherokee_resolv_cache_t *resolv) { CHEROKEE_RWLOCK_WRITER (&resolv->lock); cherokee_avl_mrproper (&resolv->table, entry_free); CHEROKEE_RWLOCK_UNLOCK (&resolv->lock); return ret_ok; }
ret_t cherokee_avl_r_get (cherokee_avl_r_t *avl_r, cherokee_buffer_t *key, void **value) { ret_t ret; CHEROKEE_RWLOCK_READER (AVL_R_LOCK(avl_r)); ret = cherokee_avl_get (&avl_r->avl, key, value); CHEROKEE_RWLOCK_UNLOCK (AVL_R_LOCK(avl_r)); return ret; }
ret_t cherokee_avl_r_add (cherokee_avl_r_t *avl_r, cherokee_buffer_t *key, void *value) { ret_t ret; CHEROKEE_RWLOCK_WRITER (AVL_R_LOCK(avl_r)); ret = cherokee_avl_add (&avl_r->avl, key, value); CHEROKEE_RWLOCK_UNLOCK (AVL_R_LOCK(avl_r)); return ret; }
static ret_t _add (cherokee_regex_table_t *table, char *pattern, void **regex) { ret_t ret; const char *error_msg; int error_offset; void *tmp = NULL; /* It wasn't in the cache. Lets go to compile the pattern.. * First of all, we have to check again the table because another * thread could create a new entry after the previous unlock. */ CHEROKEE_RWLOCK_WRITER (&table->rwlock); ret = cherokee_avl_get_ptr (&table->cache, pattern, &tmp); if ((tmp != NULL) && (ret == ret_ok)) { if (regex != NULL) *regex = tmp; CHEROKEE_RWLOCK_UNLOCK (&table->rwlock); return ret_ok; } tmp = pcre_compile (pattern, 0, &error_msg, &error_offset, NULL); if (tmp == NULL) { LOG_ERROR (CHEROKEE_ERROR_REGEX_COMPILATION, pattern, error_msg, error_offset); CHEROKEE_RWLOCK_UNLOCK (&table->rwlock); return ret_error; } cherokee_avl_add_ptr (&table->cache, pattern, tmp); CHEROKEE_RWLOCK_UNLOCK (&table->rwlock); if (regex != NULL) *regex = tmp; return ret_ok; }
ret_t cherokee_regex_table_get (cherokee_regex_table_t *table, char *pattern, void **regex) { ret_t ret; /* Check if it is already in the cache */ CHEROKEE_RWLOCK_READER(&table->rwlock); ret = cherokee_avl_get_ptr (&table->cache, pattern, regex); CHEROKEE_RWLOCK_UNLOCK(&table->rwlock); if (ret == ret_ok) return ret_ok; /* It wasn't there; add a new entry */ return _add (table, pattern, regex); }
ret_t cherokee_resolv_cache_get_ipstr (cherokee_resolv_cache_t *resolv, cherokee_buffer_t *domain, const char **ip) { ret_t ret; cherokee_resolv_cache_entry_t *entry = NULL; /* Look for the name in the cache */ CHEROKEE_RWLOCK_READER (&resolv->lock); ret = cherokee_avl_get (&resolv->table, domain, (void **)&entry); CHEROKEE_RWLOCK_UNLOCK (&resolv->lock); if (ret != ret_ok) { TRACE (ENTRIES, "Resolve '%s': missed.\n", domain->buf); /* Bad luck: it wasn't cached */ ret = table_add_new_entry (resolv, domain, &entry); if (ret != ret_ok) { return ret; } TRACE (ENTRIES, "Resolve '%s': added succesfuly as '%s'.\n", domain->buf, entry->ip_str_all.buf); } else { TRACE (ENTRIES, "Resolve '%s': hit: %s\n", domain->buf, entry->ip_str_all.buf); } /* Return the ip string */ if (ip != NULL) { *ip = entry->ip_str.buf; } return ret_ok; }