"Fossies" - the Fresh Open Source Software Archive

Member "smbnetfs-0.6.3/src/neg_cache.c" (9 Jan 2015, 4515 Bytes) of package /linux/misc/smbnetfs-0.6.3.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "neg_cache.c" see the Fossies "Dox" file reference documentation.

    1 #include <stdlib.h>
    2 #include <string.h>
    3 #include <sys/time.h>
    4 #include <pthread.h>
    5 
    6 #include "common.h"
    7 #include "list.h"
    8 #include "neg_cache.h"
    9 
   10 struct neg_cache{
   11     LIST        usage_entries;
   12     LIST        time_entries;
   13     struct timeval  tv;
   14     int         errno_value;
   15     char        hostname[1];
   16 };
   17 
   18 
   19 static int      neg_cache_timeout   = 3000;
   20 static int      neg_cache_enabled   = 1;
   21 
   22 static LIST     neg_cache_usage_list    = STATIC_LIST_INITIALIZER(neg_cache_usage_list);
   23 static LIST     neg_cache_time_list = STATIC_LIST_INITIALIZER(neg_cache_time_list);
   24 static pthread_mutex_t  m_neg_cache     = PTHREAD_MUTEX_INITIALIZER;
   25 
   26 
   27 static void neg_cache_remove_outdate_tv(struct timeval *tv){
   28     LIST        *elem;
   29     struct neg_cache    *cache;
   30     struct timeval  res;
   31 
   32     while(1){
   33     elem = last_list_elem(&neg_cache_time_list);
   34     if (!is_valid_list_elem(&neg_cache_time_list, elem)) break;
   35 
   36     cache = list_entry(elem, struct neg_cache, time_entries);
   37     if (timercmp(tv, &cache->tv, <)) goto bad_time;
   38 
   39     timersub(tv, &cache->tv, &res);
   40     if (res.tv_usec / 1000 + res.tv_sec * 1000 < neg_cache_timeout) break;
   41 
   42       bad_time:
   43     remove_from_list(&neg_cache_usage_list, &cache->usage_entries);
   44     remove_from_list(&neg_cache_time_list, &cache->time_entries);
   45     free(cache);
   46     }
   47 }
   48 
   49 static struct neg_cache * neg_cache_find_by_name(const char *name, size_t len){
   50     LIST        *elem;
   51     struct neg_cache    *cache;
   52 
   53     elem = first_list_elem(&neg_cache_usage_list);
   54     while(is_valid_list_elem(&neg_cache_usage_list, elem)){
   55     cache = list_entry(elem, struct neg_cache, usage_entries);
   56     if ((strncmp(cache->hostname, name, len) == 0) && (cache->hostname[len] == '\0'))
   57         return cache;
   58     elem = elem->next;
   59     }
   60     return NULL;
   61 }
   62 
   63 static inline void neg_cache_remove_outdate(void){
   64     struct timeval  tv;
   65 
   66     gettimeofday(&tv, NULL);
   67     neg_cache_remove_outdate_tv(&tv);
   68 }
   69 
   70 int neg_cache_set_timeout(int timeout){
   71     if (timeout <= 0) return 0;
   72     DPRINTF(7, "timeout=%d\n", timeout);
   73     pthread_mutex_lock(&m_neg_cache);
   74     neg_cache_timeout = timeout;
   75     neg_cache_remove_outdate();
   76     pthread_mutex_unlock(&m_neg_cache);
   77     return 1;
   78 }
   79 
   80 int neg_cache_enable(int status){
   81     DPRINTF(7, "status=%d\n", status);
   82     pthread_mutex_lock(&m_neg_cache);
   83     neg_cache_enabled = status;
   84     if (!status) neg_cache_flush();
   85     pthread_mutex_unlock(&m_neg_cache);
   86     return 1;
   87 }
   88 
   89 int neg_cache_check(const char *url){
   90     int         result = 0;
   91     size_t      len = 0;
   92     struct neg_cache    *cache;
   93 
   94     while(*url == '/') url++;
   95     while((url[len] != '/') && (url[len] != '\0')) len++;
   96     if (len == 0) return 0;
   97 
   98     pthread_mutex_lock(&m_neg_cache);
   99     if (!neg_cache_enabled) goto end;
  100     neg_cache_remove_outdate();
  101     cache = neg_cache_find_by_name(url, len);
  102     if (cache != NULL){
  103     remove_from_list(&neg_cache_usage_list, &cache->usage_entries);
  104     add_to_list(&neg_cache_usage_list, &cache->usage_entries);
  105     result = cache->errno_value;
  106     }
  107   end:
  108     pthread_mutex_unlock(&m_neg_cache);
  109     return result;
  110 }
  111 
  112 int neg_cache_store(const char *url, int errno_value){
  113     int         result = 0;
  114     size_t      len = 0;
  115     struct neg_cache    *cache;
  116     struct timeval  tv;
  117 
  118     while(*url == '/') url++;
  119     while((url[len] != '/') && (url[len] != '\0')) len++;
  120     if (len == 0) return 0;
  121 
  122     pthread_mutex_lock(&m_neg_cache);
  123     if (!neg_cache_enabled) goto end;
  124 
  125     gettimeofday(&tv, NULL);
  126     neg_cache_remove_outdate_tv(&tv);
  127 
  128     cache = neg_cache_find_by_name(url, len);
  129     if (cache != NULL){
  130     remove_from_list(&neg_cache_usage_list, &cache->usage_entries);
  131     remove_from_list(&neg_cache_time_list, &cache->time_entries);
  132     }else{
  133     cache = malloc(sizeof(struct neg_cache) + len);
  134     if (cache == NULL) goto end;
  135     memset(cache, 0, sizeof(struct neg_cache) + len);
  136     strncpy(cache->hostname, url, len);
  137     }
  138     cache->tv = tv;
  139     cache->errno_value = errno_value;
  140     add_to_list(&neg_cache_usage_list, &cache->usage_entries);
  141     add_to_list(&neg_cache_time_list, &cache->time_entries);
  142     result = 1;
  143 
  144   end:
  145     pthread_mutex_unlock(&m_neg_cache);
  146     return result;
  147 }
  148 
  149 void neg_cache_flush(void){
  150     LIST        *elem;
  151     struct neg_cache    *cache;
  152 
  153     pthread_mutex_lock(&m_neg_cache);
  154     while(1){
  155     elem = first_list_elem(&neg_cache_usage_list);
  156     if (!is_valid_list_elem(&neg_cache_usage_list, elem)) break;
  157 
  158     cache = list_entry(elem, struct neg_cache, usage_entries);
  159     remove_from_list(&neg_cache_usage_list, &cache->usage_entries);
  160     remove_from_list(&neg_cache_time_list, &cache->time_entries);
  161     free(cache);
  162     }
  163     pthread_mutex_unlock(&m_neg_cache);
  164 }