Exemple #1
0
memcached_return_t memcached_response(memcached_server_write_instance_st ptr,
                                      char *buffer, size_t buffer_length,
                                      memcached_result_st *result)
{
  /* We may have old commands in the buffer not set, first purge */
  if ((ptr->root->flags.no_block) && (memcached_is_processing_input(ptr->root) == false))
  {
    (void)memcached_io_write(ptr, NULL, 0, true);
  }

  /*
   * The previous implementation purged all pending requests and just
   * returned the last one. Purge all pending messages to ensure backwards
   * compatibility. But this breaks prefetching, so we only make it when
   * mget_flush_old_results is true.
   */
  if ((ptr->root->flags.mget_flush_old_results) && (ptr->root->flags.binary_protocol == false))
    while (memcached_server_response_count(ptr) > 1)
    {
      memcached_return_t rc= memcached_read_one_response(ptr, buffer, buffer_length, result);

      unlikely (rc != MEMCACHED_END &&
                rc != MEMCACHED_STORED &&
                rc != MEMCACHED_SUCCESS &&
                rc != MEMCACHED_STAT &&
                rc != MEMCACHED_DELETED &&
                rc != MEMCACHED_NOTFOUND &&
                rc != MEMCACHED_NOTSTORED &&
                rc != MEMCACHED_DATA_EXISTS)
        return rc;
    }

  return memcached_read_one_response(ptr, buffer, buffer_length, result);
}
char *memcached_fetch(memcached_st *ptr, char *key, size_t *key_length, 
                      size_t *value_length, 
                      uint32_t *flags,
                      memcached_return *error)
{
  memcached_result_st *result_buffer= &ptr->result;

  while (ptr->cursor_server < ptr->number_of_hosts)
  {
    char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];

    if (memcached_server_response_count(&ptr->hosts[ptr->cursor_server]) == 0)
    {
      ptr->cursor_server++;
      continue;
    }

  *error= memcached_response(&ptr->hosts[ptr->cursor_server], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, result_buffer);

    if (*error == MEMCACHED_END) /* END means that we move on to the next */
    {
      memcached_server_response_reset(&ptr->hosts[ptr->cursor_server]);
      ptr->cursor_server++;
      continue;
    }
    else if (*error == MEMCACHED_SUCCESS)
    {
      *value_length= memcached_string_length(&result_buffer->value);
    
      if (key)
      {
        strncpy(key, result_buffer->key, result_buffer->key_length);
        *key_length= result_buffer->key_length;
      }

      if (result_buffer->flags)
        *flags= result_buffer->flags;
      else
        *flags= 0;

      return  memcached_string_c_copy(&result_buffer->value);
    }
    else
    {
      *value_length= 0;
      return NULL;
    }
  }

  ptr->cursor_server= 0;
  *value_length= 0;
  return NULL;
}
memcached_result_st *memcached_fetch_result(memcached_st *ptr, 
                                            memcached_result_st *result,
                                            memcached_return *error)
{
  if (result == NULL)
    result= memcached_result_create(ptr, NULL);

#ifdef UNUSED
  if (ptr->flags & MEM_NO_BLOCK)
    memcached_io_preread(ptr);
#endif

  while (ptr->cursor_server < ptr->number_of_hosts)
  {
    char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];

    if (memcached_server_response_count(&ptr->hosts[ptr->cursor_server]) == 0)
    {
      ptr->cursor_server++;
      continue;
    }

    *error= memcached_response(&ptr->hosts[ptr->cursor_server], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, result);
    
    if (*error == MEMCACHED_END) /* END means that we move on to the next */
    {
      memcached_server_response_reset(&ptr->hosts[ptr->cursor_server]);
      ptr->cursor_server++;
      continue;
    }
    else if (*error == MEMCACHED_SUCCESS)
      return result;
    else
      return NULL;
  }

  /* We have completed reading data */
  if (result->is_allocated)
    memcached_result_free(result);
  else
    memcached_string_reset(&result->value);

  ptr->cursor_server= 0;
  return NULL;
}
Exemple #4
0
void memcached_io_preread(memcached_st *ptr)
{
  unsigned int x;

  return;

  for (x= 0; x < ptr->number_of_hosts; x++)
  {
    if (memcached_server_response_count(ptr, x) &&
        ptr->hosts[x].read_data_length < MEMCACHED_MAX_BUFFER )
    {
      size_t data_read;

      data_read= read(ptr->hosts[x].fd,
                      ptr->hosts[x].read_ptr + ptr->hosts[x].read_data_length,
                      MEMCACHED_MAX_BUFFER - ptr->hosts[x].read_data_length);
      if (data_read == -1)
        continue;

      ptr->hosts[x].read_buffer_length+= data_read;
      ptr->hosts[x].read_data_length+= data_read;
    }
  }
}
Exemple #5
0
memcached_return_t memcached_purge(memcached_server_write_instance_st ptr)
{
  uint32_t x;
  memcached_return_t ret= MEMCACHED_SUCCESS;
  memcached_st *root= (memcached_st *)ptr->root;
  uint32_t no_msg;

  if (memcached_is_purging(ptr->root) || /* already purging */
      (memcached_server_response_count(ptr) < ptr->root->io_msg_watermark &&
       ptr->io_bytes_sent < ptr->root->io_bytes_watermark) ||
      (ptr->io_bytes_sent >= ptr->root->io_bytes_watermark &&
       memcached_server_response_count(ptr) < 2))
  {
    return MEMCACHED_SUCCESS;
  }

  /* memcached_io_write and memcached_response may call memcached_purge
    so we need to be able stop any recursion.. */
  memcached_set_purging(root, true);

  WATCHPOINT_ASSERT(ptr->fd != -1);
  /* Force a flush of the buffer to ensure that we don't have the n-1 pending
    requests buffered up.. */
  if (memcached_io_write(ptr, NULL, 0, true) == -1)
  {
    memcached_set_purging(root, true);

    return MEMCACHED_WRITE_FAILURE;
  }
  WATCHPOINT_ASSERT(ptr->fd != -1);

  no_msg= memcached_server_response_count(ptr) - 1;
  if (no_msg > 0)
  {
    memcached_result_st result;
    memcached_result_st *result_ptr;
    char buffer[SMALL_STRING_LEN];

    /*
     * We need to increase the timeout, because we might be waiting for
     * data to be sent from the server (the commands was in the output buffer
     * and just flushed
   */
    const int32_t timeo= ptr->root->poll_timeout;
    root->poll_timeout= 2000;

    result_ptr= memcached_result_create(root, &result);
    WATCHPOINT_ASSERT(result_ptr);

    for (x= 0; x < no_msg; x++)
    {
      memcached_return_t rc;
      memcached_result_reset(result_ptr);
      rc= memcached_read_one_response(ptr, buffer,
                                                         sizeof (buffer),
                                                         result_ptr);
      /*
       * Purge doesn't care for what kind of command results that is received.
       * The only kind of errors I care about if is I'm out of sync with the
       * protocol or have problems reading data from the network..
     */
      if (rc== MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_UNKNOWN_READ_FAILURE)
      {
        WATCHPOINT_ERROR(rc);
        ret = rc;
        memcached_io_reset(ptr);
      }

      if (ptr->root->callbacks != NULL)
      {
        memcached_callback_st cb = *ptr->root->callbacks;
        if (rc == MEMCACHED_SUCCESS)
        {
          uint32_t y;
          for (y= 0; y < cb.number_of_callback; y++)
          {
            rc = (*cb.callback[y])(ptr->root, result_ptr, cb.context);
            if (rc != MEMCACHED_SUCCESS)
              break;
          }
        }
      }
    }

    memcached_result_free(result_ptr);
    root->poll_timeout= timeo;
  }
  memcached_set_purging(root, false);

  return ret;
}