Ejemplo n.º 1
0
/*
 * api_check_memory - check memory 
 *    return: 0 if successful, count of failure otherwise
 *    fp(in): FILE * to print check message 
 * NOTE : this function checks malloc/free pair match and 
 *        dump debug debug information of malloc/calloced but not freeed.
 */
int
api_check_memory (FILE * fp)
{
  int res = 0;

  if (api_malloc_dhook_flag_set == 0)
    return 0;

  API_ONCE_FUNC (&once, once_function);
  API_LOCK (&mutex);
  if (malloc_count != free_count)
    {
      fprintf (fp, "malloc/free count mismatch (%d/%d)\n", malloc_count, free_count);
      res++;
    }
  if (!dlisth_is_empty (&malloc_list))
    {
      dlisth *h;
      fprintf (fp, "malloc list not empty (memory leak)\n");
      for (h = malloc_list.next; h != &malloc_list; h = h->next)
	{
	  fprintf (fp, "\t");
	  dump_debug_h ((debug_malloc_h *) h, fp);
	  fprintf (fp, "\n");
	}
      res++;
    }
  API_UNLOCK (&mutex);
  return res;
}
Ejemplo n.º 2
0
static int
smrCbClose (void *arg, long long seq, short nid, int sid)
{
  redisClient *c;
  callbackInfo *cb;
  dlisth *node;

  if (nid != smr_get_nid (server.smr_conn)
      || !(server.smr_init_flags & SMR_INIT_DONE))
    return REDIS_OK;

  /* query from this server. get client from global callback list */
  assert (!dlisth_is_empty (&server.global_callbacks));	/* global callback list shouldn't be empty */
  node = server.global_callbacks.next;
  cb = (callbackInfo *) node;
  dlisth_delete (&cb->global_head);
  dlisth_delete (&cb->client_head);
  c = cb->client;
  zfree (cb);

  if (c->fd == -1)
    return REDIS_OK;		/* ignore if the client is already freed */

  assert (c->fd == sid);

  addReplyError (c, c->smr.protocol_error_reply);
  c->flags |= REDIS_CLOSE_AFTER_REPLY;

  return REDIS_OK;
}
Ejemplo n.º 3
0
void
decref_be_job (be_job_t * job)
{
  int need_mutex;
  int need_free = 0;

  if (job == NULL)
    {
      return;
    }

  need_mutex = is_job_need_mutex (job);
  if (need_mutex)
    {
      pthread_mutex_lock (&job->ref_mutex);
    }

  job->ref_count--;
  need_free = (job->ref_count <= 0);

  if (need_mutex)
    {
      pthread_mutex_unlock (&job->ref_mutex);
    }

  if (need_free)
    {
      assert (dlisth_is_empty (&job->head));
      assert (dlisth_is_empty (&job->htwhead));
      pthread_mutex_destroy (&job->ref_mutex);
      if (job->free_func)
	{
	  job->free_func (job->data);
	}
      free (job);
    }
}
Ejemplo n.º 4
0
/*
 * li_api_destroy - destroy value indexer
 *    return: void
 *    indexer(in): VALUE_INDEXER
 *    df(in): element destroy function
 */
static void
li_api_destroy (VALUE_INDEXER * indexer, void (*df) (VALUE_AREA * va, API_VALUE * db))
{
  LIST_INDEXER *li = (LIST_INDEXER *) indexer;

  assert (li != NULL);
  while (!dlisth_is_empty (&li->elems))
    {
      LIST_INDEXER_ELEM *e = (LIST_INDEXER_ELEM *) li->elems.next;
      if (df)
	df (e->va, e->value);
      dlisth_delete ((dlisth *) e);
      API_FREE (e);
    }
  API_FREE (li);
}
Ejemplo n.º 5
0
/* sid = |flags(4byte)|client fd(4byte)| */
static int
smrCbData (void *arg, long long seq, long long timestamp,
	   short nid, int sid, int hash, smrData * smr_data, int size)
{
  char *data = smr_data_get_data (smr_data);
  redisClient *c;
  short cmdflags;
  dlisth *node;

  /* Special commands */
  if (size == 1 && data[0] == REDIS_SMR_CMD_CATCHUP_CHECK)
    {
      if (nid == smr_get_nid (server.smr_conn)
	  && (server.smr_init_flags & SMR_INIT_CATCHUP_PHASE2))
	checkSmrCatchup ();
      goto release_seq;
    }
  else if (size == 1 && data[0] == REDIS_SMR_CMD_DELIVER_OOM)
    {
      server.smr_oom_until = timestamp + REDIS_OOM_DURATION_MS;
      goto release_seq;
    }

  /* Normal command */
  server.smr_mstime = timestamp;
  cmdflags = (0xFFFF0000 & sid) >> 16;

  /* Because we fixed the bug that causes timestamp be 0, 
   * this warning log is not necessary and just an assert statement is enough after all.
   * But currently, there are nbase-arc clusters which have the bug.
   * So, we don't assert for now. */
  if (timestamp == 0)
    {
      redisLog (REDIS_WARNING, "Timestamp of SMR callback is 0,"
		"seq:%lld, nid:%d, sid:%d, hash:%d, size:%d",
		seq, nid, sid, hash, size);
    }

  if ((server.smr_init_flags & SMR_INIT_DONE)
      && nid == smr_get_nid (server.smr_conn))
    {
      callbackInfo *cb;
      /* query from this server. get client from global callback list */
      assert (!dlisth_is_empty (&server.global_callbacks));	/* global callback list shouldn't be empty */
      node = server.global_callbacks.next;
      cb = (callbackInfo *) node;
      dlisth_delete (&cb->global_head);
      dlisth_delete (&cb->client_head);
      c = cb->client;
      assert (cb->hash == hash);
      assert (c->fd == -1 || c->fd == (0X0000FFFF & sid));

      /* We already parsed querybuf because the query is requested from this 
       * server before smr callback*/
      c->argc = cb->argc;
      c->argv = cb->argv;
      cb->argc = 0;
      cb->argv = NULL;
      zfree (cb);

      server.current_client = c;

      /* fake client doesn't need to execute non-write query(read-only or admin) */
      if (c->fd != -1 || cmdflags & REDIS_CMD_WRITE)
	{
	  assert (!(c->flags & REDIS_CLOSE_AFTER_REPLY));
	  processCommand (c);
	}
    }
  else
    {
      /* replicated query from other servers, or catchup query during initialize */
      c = server.smrlog_client;
      server.current_client = c;

      /* fake client doesn't need to execute non-write query(read-only or admin) */
      if (cmdflags & REDIS_CMD_WRITE)
	{
	  /* We need to parse querybuf because the query is from different server 
	   * or we are recovering without client */
	  sdsclear (c->querybuf);
	  c->querybuf = sdsMakeRoomFor (c->querybuf, size);
	  memcpy (c->querybuf, data, size);
	  sdsIncrLen (c->querybuf, size);
	  if (c->querybuf_peak < size)
	    c->querybuf_peak = size;
	  processInputBuffer (c);
	}
    }

  resetClient (c);
  zfree (c->argv);
  c->argv = NULL;
  server.current_client = NULL;

release_seq:
  if (smr_release_seq_upto (server.smr_conn, seq + size) == -1)
    {
      redisLog (REDIS_WARNING, "smr_release_seq_upto error");
      redisAssert (0);
      return REDIS_ERR;
    }
  server.smr_seqnum = seq + size;

  return REDIS_OK;
}