void stack_push_rel_view(mvc *sql, char *name, sql_rel *var) { if (sql->topvars == sql->sizevars) { sql->sizevars <<= 1; sql->vars = RENEW_ARRAY(sql_var,sql->vars,sql->sizevars); } sql->vars[sql->topvars].s = var; sql->vars[sql->topvars].name = _STRDUP(name); sql->vars[sql->topvars].value.vtype = 0; sql->vars[sql->topvars].view = 1; sql->vars[sql->topvars].type.comp_type = NULL; sql->topvars++; }
void stack_push_rel_var(mvc *sql, char *name, sql_rel *var, sql_subtype *type) { if (sql->topvars == sql->sizevars) { sql->sizevars <<= 1; sql->vars = RENEW_ARRAY(sql_var,sql->vars,sql->sizevars); } sql->vars[sql->topvars].s = rel_dup(var); sql->vars[sql->topvars].name = _STRDUP(name); sql->vars[sql->topvars].value.vtype = 0; sql->vars[sql->topvars].type = *type; assert(sql->vars[sql->topvars].type.comp_type != NULL); sql->vars[sql->topvars].view = 0; sql->topvars++; }
void stack_push_frame(mvc *sql, char *name) { if (sql->topvars == sql->sizevars) { sql->sizevars <<= 1; sql->vars = RENEW_ARRAY(sql_var,sql->vars,sql->sizevars); } sql->vars[sql->topvars].s = NULL; sql->vars[sql->topvars].name = NULL; sql->vars[sql->topvars].value.vtype = 0; sql->vars[sql->topvars].view = 0; sql->vars[sql->topvars].type.comp_type = NULL; if (name) sql->vars[sql->topvars].name = _STRDUP(name); sql->topvars++; sql->frame++; }
/* variable management */ static void stack_set(mvc *sql, int var, const char *name, sql_subtype *type, sql_rel *rel, sql_table *t, int view, int frame) { sql_var *v; if (var == sql->sizevars) { sql->sizevars <<= 1; sql->vars = RENEW_ARRAY(sql_var,sql->vars,sql->sizevars); } v = sql->vars+var; v->name = NULL; v->value.vtype = 0; v->rel = rel; v->t = t; v->view = view; v->frame = frame; v->type.type = NULL; if (type) { int tpe = type->type->localtype; VALinit(&sql->vars[var].value, tpe, ATOMnilptr(tpe)); v->type = *type; } if (name) v->name = _STRDUP(name); }
/** * Returns a file description structure for the given process and file name. * Must be called under global_lock(). * The fd argument is only used when it's not -1 and when opt is HashMapOpt_New * — in this case the given fd will be associated with the returned description * so that when close is called on that fd it will be deassociated (and will * cause the desc deletion if there is no other use of it). Optional o_bucket, * o_prev and o_proc arguments will receive the appropriate values for the * returned file description when they are not NULL (and may be later used in * e.g. a free_file_desc_ex() call). Optional o_desc_g, when not NULL, will * receive a global (shared) file description - this is the only way to get it * when no process-specific file description exists and opt is HashMapOpt_None. * Returns NULL when opt is HashMapOpt_New and there is not enough memory * to allocate a new sctructure, or when opt is not HashMapOpt_New and there * is no descriptor for the given file. */ FileDesc *get_file_desc_ex(pid_t pid, int fd, const char *path, enum HashMapOpt opt, size_t *o_bucket, FileDesc **o_prev, ProcDesc **o_proc, SharedFileDesc **o_desc_g) { size_t bucket; FileDesc *desc, *prev; ProcDesc *proc; int rc; ASSERT(gpData); ASSERT(path); if (pid == -1) pid = getpid(); enum { FDArrayInc = 4 }; proc = get_proc_desc_ex(pid, opt == HashMapOpt_New ? opt : HashMapOpt_None, NULL, NULL); if (!proc) return NULL; if (!proc->files) { /* Lazily create a process-specific file desc hash map */ GLOBAL_NEW_ARRAY(proc->files, FILE_DESC_HASH_SIZE); if (!proc->files) return NULL; } bucket = hash_string(path) % FILE_DESC_HASH_SIZE; desc = proc->files[bucket]; prev = NULL; while (desc) { ASSERT(desc->g); if (strcmp(desc->g->path, path) == 0) break; prev = desc; desc = desc->next; } if (!desc && opt == HashMapOpt_New) { /* Initialize a new desc */ GLOBAL_NEW(desc); if (desc) { /* Associate the fd with this description */ desc->size_fds = FDArrayInc; GLOBAL_NEW_ARRAY(desc->fds, desc->size_fds); if (desc->fds) { desc->fds[0] = fd; memset(&desc->fds[1], 0xFF, sizeof(desc->fds[0]) * (FDArrayInc - 1)); /* Associate with the shared part, if any */ desc->g = gpData->files[bucket]; while (desc->g) { if (strcmp(desc->g->path, path) == 0) break; desc->g = desc->g->next; } if (!desc->g) { /* Initialize a new shared part */ GLOBAL_NEW_PLUS(desc->g, strlen(path) + 1); if (desc->g) { desc->g->refcnt = 1; desc->g->path = ((char *)(desc->g + 1)); strcpy(desc->g->path, path); } TRACE("new global file desc %p for [%s]\n", desc->g, desc->g->path); } else { /* Reuse the existing shared part */ ++desc->g->refcnt; ASSERT_MSG(desc->g->refcnt >= 2, "%d", desc->g->refcnt); } if (desc->g) { /* Call component-specific initialization */ rc = fcntl_locking_filedesc_init(desc); if (rc == 0) { rc = pwrite_filedesc_init(desc); if (rc == -1) fcntl_locking_filedesc_term(desc); } if (rc == 0) { if (desc->g->refcnt == 1) { /* Put to the head of the bucket (shared part) */ desc->g->next = gpData->files[bucket]; gpData->files[bucket] = desc->g; #if STATS_ENABLED ++gpData->num_shared_files; if (gpData->num_shared_files > gpData->max_shared_files) gpData->max_shared_files = gpData->num_shared_files; #endif } /* Put to the head of the bucket */ desc->next = proc->files[bucket]; proc->files[bucket] = desc; #if STATS_ENABLED ++gpData->num_files; if (gpData->num_files > gpData->max_files) gpData->max_files = gpData->num_files; #endif } else { if (desc->g->refcnt == 1) free(desc->g); else --desc->g->refcnt; free(desc->fds); free(desc); desc = NULL; } TRACE("new file desc %p for g %p [%s] (refcnt %d)\n", desc, desc->g, desc->g->path, desc->g->refcnt); } else { free(desc->fds); free(desc); desc = NULL; } } else { free(desc); desc = NULL; } } } if (fd != -1 && desc && opt == HashMapOpt_New) { int i; /* Associate the fd with this file description (if not already) */ for (i = 0; i < desc->size_fds; ++i) if (desc->fds[i] == -1 || desc->fds[i] == fd) break; if (i < desc->size_fds) { desc->fds[i] = fd; } else { int *fds = RENEW_ARRAY(desc->fds, desc->size_fds + FDArrayInc); if (fds) { desc->fds = fds; desc->fds[desc->size_fds] = fd; memset(&desc->fds[desc->size_fds + 1], 0xFF, sizeof(desc->fds[0]) * (FDArrayInc - 1)); desc->size_fds += FDArrayInc; } else desc = NULL; } } else if (opt == HashMapOpt_None) { if (o_desc_g) { if (!desc) { /* Return a global description if there is any */ SharedFileDesc *desc_g = gpData->files[bucket]; while (desc_g) { if (strcmp(desc_g->path, path) == 0) break; desc_g = desc_g->next; } *o_desc_g = desc_g; } else { *o_desc_g = desc->g; } } } if (o_bucket) *o_bucket = bucket; if (o_prev) *o_prev = prev; if (o_proc) *o_proc = proc; return desc; }