/* * this function frees all cached connections, including in-use ones. * * potential problems: * - connections which are currently in-use are freed too. * - connections which are uncached are NOT freed. * i.e. the followings are all NOT freed: * - connections which have never cached, * - connections which had been once cached but currently uncached * (since their network connections were dead) */ void gfp_cached_connection_terminate(struct gfp_conn_cache *cache) { struct gfarm_hash_iterator it; struct gfarm_hash_entry *entry; struct gfp_cached_connection *connection; static const char diag[] = "gfp_cached_connection_terminate"; gfarm_mutex_lock(&cache->mutex, diag, diag_what); if (cache->hashtab == NULL) { gfarm_mutex_unlock(&cache->mutex, diag, diag_what); return; } gfarm_mutex_unlock(&cache->mutex, diag, diag_what); /* * clear all free connections. * to makes cache->lru_list.free_cached_entries 0. */ gfp_cached_connection_gc_all(cache); gfarm_mutex_lock(&cache->mutex, diag, diag_what); /* clear all in-use connections too. XXX really necessary? */ for (gfarm_hash_iterator_begin(cache->hashtab, &it); !gfarm_hash_iterator_is_end(&it);) { entry = gfarm_hash_iterator_access(&it); connection = *(struct gfp_cached_connection **) gfarm_hash_entry_data(entry); gfarm_lru_cache_purge_entry(&connection->lru_entry); gfp_conn_hash_iterator_purge(&it); gfarm_mutex_unlock(&cache->mutex, diag, diag_what); (*cache->dispose_connection)(connection->connection_data); gfarm_mutex_lock(&cache->mutex, diag, diag_what); /* restart from the top, because maybe changed by others */ gfarm_hash_iterator_begin(cache->hashtab, &it); } /* free hash table */ gfarm_hash_table_free(cache->hashtab); cache->hashtab = NULL; gfarm_mutex_unlock(&cache->mutex, diag, diag_what); }
static void sweep_nodes(struct node *n) { struct gfarm_hash_iterator i; struct gfarm_hash_entry *child; /* assert((n->flags & NODE_FLAG_IS_DIR) != 0); */ /* * We don't have to honor the PURGED flag here, * because the mark phase overrides the flag. */ for (gfarm_hash_iterator_begin(n->u.d.children, &i); (child = gfarm_hash_iterator_access(&i)) != NULL; gfarm_hash_iterator_next(&i)) { struct node *c = gfarm_hash_entry_data(child); if ((c->flags & NODE_FLAG_MARKED) == 0) { if (opendir_count > 0) { recursive_delayed_purge_nodes(c); } else { recursive_free_nodes(c); gfarm_hash_iterator_purge(&i); } } else { if ((c->flags & NODE_FLAG_IS_DIR) != 0) sweep_nodes(c); else if (opendir_count == 0 && c->u.d.children != NULL) recursive_free_children(c); c->flags &= ~NODE_FLAG_MARKED; } } }
static void cache_path_info_free() { struct gfarm_hash_iterator iterator; struct gfarm_hash_entry *he; struct path_info_cache *pic; #ifdef DEBUG char *key; char path[PATH_MAX]; #endif gfarm_hash_iterator_begin(cache_table, &iterator); while (1) { he = gfarm_hash_iterator_access(&iterator); if (he == NULL) break; pic = gfarm_hash_entry_data(he); #ifdef DEBUG key = gfarm_hash_entry_key(he); memset(path, 0, PATH_MAX); memcpy(path, key, gfarm_hash_entry_key_length(he)); _debug("! free path_info cache: %d: %s\n", pic->noent, path); #endif if (pic->noent == CACHE_SET) gfarm_path_info_free(&pic->info); gfarm_hash_iterator_next(&iterator); } /* ?? gfarm_hash_iterator_purge(&iterator); */ gfarm_hash_table_free(cache_table); prepare_cache_table = 0; }
static void recursive_free_children(struct node *n) { struct gfarm_hash_iterator i; struct gfarm_hash_entry *child; for (gfarm_hash_iterator_begin(n->u.d.children, &i); (child = gfarm_hash_iterator_access(&i)) != NULL; gfarm_hash_iterator_next(&i)) { recursive_free_nodes(gfarm_hash_entry_data(child)); } gfarm_hash_table_free(n->u.d.children); n->u.d.children = NULL; }
static char * hosts_for_program(char *program, int *n_all_hostsp, struct gfarm_host_info **all_hostsp, struct gfarm_hash_table **hosts_statep, int *n_runnable_hostsp) { char *e; int n_all_hosts, n_runnable_hosts; struct gfarm_host_info *all_hosts; struct gfarm_hash_table *hosts_state; struct gfarm_hash_table *arch_set; struct gfarm_hash_iterator it; struct gfarm_hash_entry *entry; struct search_idle_host_state *h; e = alloc_hosts_state(&n_all_hosts, &all_hosts, &hosts_state); if (e == NULL) { e = program_arch_set(program, &arch_set); if (e == NULL) { n_runnable_hosts = 0; for (gfarm_hash_iterator_begin(hosts_state, &it); !gfarm_hash_iterator_is_end(&it); gfarm_hash_iterator_next(&it)) { entry = gfarm_hash_iterator_access(&it); h = gfarm_hash_entry_data(entry); if (IS_IN_ARCH_SET(h->host_info->architecture, arch_set)) { h->flags |= HOST_STATE_FLAG_RUNNABLE; ++n_runnable_hosts; } } free_arch_set(arch_set); if (n_runnable_hosts > 0) { *n_all_hostsp = n_all_hosts; *all_hostsp = all_hosts; *hosts_statep = hosts_state; *n_runnable_hostsp = n_runnable_hosts; return (NULL); } e = "there is no host which can run the program"; } free_hosts_state(n_all_hosts, all_hosts, hosts_state); } return (e); }
static gfarm_error_t gfarm_hash_to_string_array(struct gfarm_hash_table *hash, int *array_lengthp, char ***arrayp) { struct gfarm_hash_iterator iter; struct gfarm_hash_entry *entry; gfarm_stringlist ls; char *ent, **array; gfarm_error_t e; e = gfarm_stringlist_init(&ls); if (e != GFARM_ERR_NO_ERROR) return (e); for (gfarm_hash_iterator_begin(hash, &iter); !gfarm_hash_iterator_is_end(&iter); gfarm_hash_iterator_next(&iter)) { entry = gfarm_hash_iterator_access(&iter); if (entry != NULL) { ent = strdup(gfarm_hash_entry_key(entry)); if (ent == NULL) e = GFARM_ERR_NO_MEMORY; else e = gfarm_stringlist_add(&ls, ent); } if (e != GFARM_ERR_NO_ERROR) goto stringlist_free; } array = gfarm_strings_alloc_from_stringlist(&ls); if (array == NULL) { e = GFARM_ERR_NO_MEMORY; goto stringlist_free; } *array_lengthp = gfarm_stringlist_length(&ls); *arrayp = array; stringlist_free: if (e == GFARM_ERR_NO_ERROR) gfarm_stringlist_free(&ls); else gfarm_stringlist_free_deeply(&ls); return (e); }
static void for_each_node(struct node *n, void (*f)(void *, struct node *), void *cookie) { #if 0 if ((n->flags & NODE_FLAG_IS_DIR) != 0) #else if (n->u.d.children != NULL) #endif { struct gfarm_hash_iterator i; struct gfarm_hash_entry *child; for (gfarm_hash_iterator_begin(n->u.d.children, &i); (child = gfarm_hash_iterator_access(&i)) != NULL; gfarm_hash_iterator_next(&i)) { for_each_node(gfarm_hash_entry_data(child), f, cookie); } } (*f)(cookie, n); }
char * gfs_opendir(const char *path, GFS_Dir *dirp) { char *e, *canonic_path; struct node *n; struct gfs_dir *dir; struct gfs_stat st; /* gfs_stat() -> gfarm_path_info_get() makes the dircache consistent */ if ((e = gfs_stat(path, &st)) != NULL) return (e); if (!GFARM_S_ISDIR(st.st_mode)) { gfs_stat_free(&st); return (GFARM_ERR_NOT_A_DIRECTORY); } gfs_stat_free(&st); e = gfarm_canonical_path(gfarm_url_prefix_skip(path), &canonic_path); if (e != NULL) return (e); e = lookup_relative(root, canonic_path, NODE_FLAG_IS_DIR, GFARM_INODE_LOOKUP, &n); free(canonic_path); if (e != NULL) return (e); dir = malloc(sizeof(struct gfs_dir)); if (dir == NULL) return (GFARM_ERR_NO_MEMORY); dir->dir = n; gfarm_hash_iterator_begin(n->u.d.children, &dir->iterator); dir->index = 0; *dirp = dir; ++opendir_count; /* XXX if someone removed a path, while opening a directory... */ return (NULL); }