void alloc_clear(struct alloc_cache* alloc) { alloc_special_type* p; struct regional* r, *nr; if(!alloc) return; if(!alloc->super) { lock_quick_destroy(&alloc->lock); } if(alloc->super && alloc->quar) { /* push entire list into super */ p = alloc->quar; while(alloc_special_next(p)) /* find last */ p = alloc_special_next(p); lock_quick_lock(&alloc->super->lock); alloc_set_special_next(p, alloc->super->quar); alloc->super->quar = alloc->quar; alloc->super->num_quar += alloc->num_quar; lock_quick_unlock(&alloc->super->lock); } else { alloc_clear_special_list(alloc); } alloc->quar = 0; alloc->num_quar = 0; r = alloc->reg_list; while(r) { nr = (struct regional*)r->next; free(r); r = nr; } alloc->reg_list = NULL; alloc->num_reg_blocks = 0; }
/** * main program. Set options given commandline arguments. * @param argc: number of commandline arguments. * @param argv: array of commandline arguments. * @return: exit status of the program. */ int main(int argc, char* argv[]) { int c; const char* cfgfile = CONFIGFILE; const char* winopt = NULL; const char* log_ident_default; int cmdline_verbose = 0; int debug_mode = 0; int need_pidfile = 1; #ifdef UB_ON_WINDOWS int cmdline_cfg = 0; #endif log_init(NULL, 0, NULL); log_ident_default = strrchr(argv[0],'/')?strrchr(argv[0],'/')+1:argv[0]; log_ident_set(log_ident_default); /* parse the options */ while( (c=getopt(argc, argv, "c:dhpvw:")) != -1) { switch(c) { case 'c': cfgfile = optarg; #ifdef UB_ON_WINDOWS cmdline_cfg = 1; #endif break; case 'v': cmdline_verbose++; verbosity++; break; case 'p': need_pidfile = 0; break; case 'd': debug_mode++; break; case 'w': winopt = optarg; break; case '?': case 'h': default: usage(); return 1; } } argc -= optind; /* argv += optind; not using further arguments */ if(winopt) { #ifdef UB_ON_WINDOWS wsvc_command_option(winopt, cfgfile, cmdline_verbose, cmdline_cfg); #else fatal_exit("option not supported"); #endif } if(argc != 0) { usage(); return 1; } run_daemon(cfgfile, cmdline_verbose, debug_mode, log_ident_default, need_pidfile); log_init(NULL, 0, NULL); /* close logfile */ #ifndef unbound_testbound if(log_get_lock()) { lock_quick_destroy((lock_quick_type*)log_get_lock()); } #endif return 0; }
/** test bin_find_entry function and bin_overflow_remove */ static void test_bin_find_entry(struct lruhash* table) { testkey_t* k = newkey(12); testdata_t* d = newdata(128); testkey_t* k2 = newkey(12 + 1024); testkey_t* k3 = newkey(14); testkey_t* k4 = newkey(12 + 1024*2); hashvalue_t h = myhash(12); struct lruhash_bin bin; memset(&bin, 0, sizeof(bin)); bin_init(&bin, 1); /* remove from empty list */ bin_overflow_remove(&bin, &k->entry); /* find in empty list */ unit_assert( bin_find_entry(table, &bin, h, k) == NULL ); /* insert */ lock_quick_lock(&bin.lock); bin.overflow_list = &k->entry; lock_quick_unlock(&bin.lock); /* find, hash not OK. */ unit_assert( bin_find_entry(table, &bin, myhash(13), k) == NULL ); /* find, hash OK, but cmp not */ unit_assert( k->entry.hash == k2->entry.hash ); unit_assert( bin_find_entry(table, &bin, h, k2) == NULL ); /* find, hash OK, and cmp too */ unit_assert( bin_find_entry(table, &bin, h, k) == &k->entry ); /* remove the element */ lock_quick_lock(&bin.lock); bin_overflow_remove(&bin, &k->entry); lock_quick_unlock(&bin.lock); unit_assert( bin_find_entry(table, &bin, h, k) == NULL ); /* prepend two different elements; so the list is long */ /* one has the same hash, but different cmp */ lock_quick_lock(&bin.lock); unit_assert( k->entry.hash == k4->entry.hash ); k4->entry.overflow_next = &k->entry; k3->entry.overflow_next = &k4->entry; bin.overflow_list = &k3->entry; lock_quick_unlock(&bin.lock); /* find, hash not OK. */ unit_assert( bin_find_entry(table, &bin, myhash(13), k) == NULL ); /* find, hash OK, but cmp not */ unit_assert( k->entry.hash == k2->entry.hash ); unit_assert( bin_find_entry(table, &bin, h, k2) == NULL ); /* find, hash OK, and cmp too */ unit_assert( bin_find_entry(table, &bin, h, k) == &k->entry ); /* remove middle element */ unit_assert( bin_find_entry(table, &bin, k4->entry.hash, k4) == &k4->entry ); lock_quick_lock(&bin.lock); bin_overflow_remove(&bin, &k4->entry); lock_quick_unlock(&bin.lock); unit_assert( bin_find_entry(table, &bin, k4->entry.hash, k4) == NULL); /* remove last element */ lock_quick_lock(&bin.lock); bin_overflow_remove(&bin, &k->entry); lock_quick_unlock(&bin.lock); unit_assert( bin_find_entry(table, &bin, h, k) == NULL ); lock_quick_destroy(&bin.lock); delkey(k); delkey(k2); delkey(k3); delkey(k4); deldata(d); }