Exemple #1
0
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++;
}
Exemple #2
0
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++;
}
Exemple #3
0
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++;
}
Exemple #4
0
/* 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);
}
Exemple #5
0
/**
 * 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;
}