コード例 #1
0
static test_return_t drizzle(memcached_st *memc)
{
  memcached_return_t rc;
  char *return_value;
  size_t return_value_length;
  uint32_t flags;

infinite:
  for (size_t x= 0; x < TEST_COUNTER; x++)
  {
    uint32_t test_bit;
    uint8_t which;

    test_bit= (uint32_t)(random() % GLOBAL_COUNT);
    which= (uint8_t)(random() % 2);

    if (which == 0)
    {
      return_value= memcached_get(memc, global_keys[test_bit], global_keys_length[test_bit],
                                  &return_value_length, &flags, &rc);
      if (rc == MEMCACHED_SUCCESS && return_value)
      {
        free(return_value);
      }
      else if (rc == MEMCACHED_NOTFOUND)
      {
        continue;
      }
      else
      {
        WATCHPOINT_ERROR(rc);
        WATCHPOINT_ASSERT(rc);
      }
    }
    else
    {
      rc= memcached_set(memc, global_pairs[test_bit].key,
                        global_pairs[test_bit].key_length,
                        global_pairs[test_bit].value,
                        global_pairs[test_bit].value_length,
                        0, 0);
      if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED)
      {
        WATCHPOINT_ERROR(rc);
        WATCHPOINT_ASSERT(0);
      }
    }
  }

  if (getenv("MEMCACHED_ATOM_BURIN_IN"))
    goto infinite;

  return TEST_SUCCESS;
}
コード例 #2
0
ファイル: do.c プロジェクト: bsmr-couchbase/moxi
memcached_return_t memcached_vdo(memcached_server_write_instance_st ptr,
                                 const struct libmemcached_io_vector_st *vector, size_t count,
                                 bool with_flush)
{
  memcached_return_t rc;
  ssize_t sent_length;
  size_t command_length= 0;
  uint32_t x;

  WATCHPOINT_ASSERT(count);
  WATCHPOINT_ASSERT(vector);

  if ((rc= memcached_connect(ptr)) != MEMCACHED_SUCCESS)
  {
    WATCHPOINT_ERROR(rc);
    return rc;
  }

  /*
  ** Since non buffering ops in UDP mode dont check to make sure they will fit
  ** before they start writing, if there is any data in buffer, clear it out,
  ** otherwise we might get a partial write.
  **/
  if (ptr->type == MEMCACHED_CONNECTION_UDP && with_flush && ptr->write_buffer_offset > UDP_DATAGRAM_HEADER_LENGTH)
  {
    memcached_io_write(ptr, NULL, 0, true);
  }

  sent_length= memcached_io_writev(ptr, vector, count, with_flush);

  for (x= 0; x < count; ++x, vector++)
  {
    command_length+= vector->length;
  }

  if (sent_length == -1 || (size_t)sent_length != command_length)
  {
    rc= MEMCACHED_WRITE_FAILURE;
    WATCHPOINT_ERROR(rc);
    WATCHPOINT_ERRNO(errno);
  }
  else if ((ptr->root->flags.no_reply) == 0)
  {
    memcached_server_response_increment(ptr);
  }

  return rc;
}
コード例 #3
0
ファイル: memcached_do.c プロジェクト: aroben/memcached
memcached_return memcached_do(memcached_server_st *ptr, const void *command,
                              size_t command_length, uint8_t with_flush)
{
  memcached_return rc;
  ssize_t sent_length;

  WATCHPOINT_ASSERT(command_length);
  WATCHPOINT_ASSERT(command);

  if ((rc= memcached_connect(ptr)) != MEMCACHED_SUCCESS)
  {
    WATCHPOINT_ERROR(rc);
    return rc;
  }

  /*
  ** Since non buffering ops in UDP mode dont check to make sure they will fit
  ** before they start writing, if there is any data in buffer, clear it out,
  ** otherwise we might get a partial write.
  **/
  if (ptr->type == MEMCACHED_CONNECTION_UDP && with_flush && ptr->write_buffer_offset > UDP_DATAGRAM_HEADER_LENGTH)
    memcached_io_write(ptr, NULL, 0, 1);

  sent_length= memcached_io_write(ptr, command, command_length, (char) with_flush);

  if (sent_length == -1 || (size_t)sent_length != command_length)
    rc= MEMCACHED_WRITE_FAILURE;
  else if ((ptr->root->flags & MEM_NOREPLY) == 0)
    memcached_server_response_increment(ptr);

  return rc;
}
コード例 #4
0
ファイル: memcached_do.c プロジェクト: aroben/memcached
memcached_return memcached_vdo(memcached_server_st *ptr,
                               const struct libmemcached_io_vector_st *vector, size_t count,
                               uint8_t with_flush)
{
  memcached_return rc;
  ssize_t sent_length;
	size_t command_length;
  uint32_t x;

  WATCHPOINT_ASSERT(count);
  WATCHPOINT_ASSERT(vector);

  if ((rc= memcached_connect(ptr)) != MEMCACHED_SUCCESS)
  {
    WATCHPOINT_ERROR(rc);
    return rc;
  }

  if (ptr->type == MEMCACHED_CONNECTION_UDP && with_flush && ptr->write_buffer_offset > UDP_DATAGRAM_HEADER_LENGTH)
  {
    memcached_io_write(ptr, NULL, 0, true);
  }

  sent_length= memcached_io_writev(ptr, vector, count, (char) with_flush);

  command_length = 0;
  for (x= 0; x < count; ++x, vector++)
    command_length+= vector->length;

  if (sent_length == -1 || (size_t)sent_length != command_length) {
    rc = MEMCACHED_WRITE_FAILURE;
    WATCHPOINT_ERROR(rc);
  } else if ((ptr->root->flags & MEM_NOREPLY) == 0)
    memcached_server_response_increment(ptr);

  return rc;
}
コード例 #5
0
memcached_return memcached_flush_buffers(memcached_st *mem)
{
  memcached_return ret= MEMCACHED_SUCCESS;

  for (int x= 0; x < mem->number_of_hosts; ++x)
    if (mem->hosts[x].write_buffer_offset != 0) 
    {
      if (mem->hosts[x].fd == -1 &&
          (ret= memcached_connect(&mem->hosts[x])) != MEMCACHED_SUCCESS)
      {
        WATCHPOINT_ERROR(ret);
        return ret;
      }
      if (memcached_io_write(&mem->hosts[x], NULL, 0, 1) == -1)
        ret= MEMCACHED_SOME_ERRORS;
    }

  return ret;
}
コード例 #6
0
ファイル: purge.c プロジェクト: bsmr-couchbase/moxi
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;
}
コード例 #7
0
ファイル: response.c プロジェクト: jmedrano/libmemcached
static memcached_return_t binary_read_one_response(memcached_server_write_instance_st ptr,
                                                   char *buffer, size_t buffer_length,
                                                   memcached_result_st *result)
{
  memcached_return_t rc;
  protocol_binary_response_header header;

  if (ptr->root->flags.use_udp) {
    // This is how we detect we are expecting a new UDP response
    ptr->num_datagrams = 0;
  }

  for (;;) 
  {
    if ((rc= memcached_safe_read(ptr, &header.bytes, sizeof(header.bytes))) != MEMCACHED_SUCCESS)
    {
      WATCHPOINT_ERROR(rc);
      return rc;
    }

    if (memcached_server_response_decrement(ptr, header.response.opaque))
    {
      break;
    } else {
      memcached_safe_read(ptr, NULL, ntohl(header.response.bodylen));
    }
  }

  if (header.response.magic != PROTOCOL_BINARY_RES)
  {
    return MEMCACHED_PROTOCOL_ERROR;
  }

  /*
   * Convert the header to host local endian!
   */
  header.response.keylen= ntohs(header.response.keylen);
  header.response.status= ntohs(header.response.status);
  header.response.bodylen= ntohl(header.response.bodylen);
  header.response.cas= ntohll(header.response.cas);
  uint32_t bodylen= header.response.bodylen;

  if (header.response.status == PROTOCOL_BINARY_RESPONSE_SUCCESS ||
      header.response.status == PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE)
  {
    switch (header.response.opcode)
    {
    case PROTOCOL_BINARY_CMD_GETKQ:
      /*
       * We didn't increment the response counter for the GETKQ packet
       * (only the final NOOP), so we need to increment the counter again.
       */
      if (!ptr->root->flags.check_opaque)
      {
        memcached_server_response_increment(ptr, 0);
      }
      /* FALLTHROUGH */
    case PROTOCOL_BINARY_CMD_GETK:
      {
        uint16_t keylen= header.response.keylen;
        memcached_result_reset(result);
        result->item_cas= header.response.cas;

        if ((rc= memcached_safe_read(ptr, &result->item_flags, 
                  sizeof (result->item_flags))) != MEMCACHED_SUCCESS)
        {
          WATCHPOINT_ERROR(rc);
          return MEMCACHED_UNKNOWN_READ_FAILURE;
        }

        result->item_flags= ntohl(result->item_flags);
        bodylen -= header.response.extlen;

        result->key_length= keylen;
        if ((rc= memcached_safe_read(ptr, result->item_key, keylen)) != MEMCACHED_SUCCESS)
        {
          WATCHPOINT_ERROR(rc);
          return MEMCACHED_UNKNOWN_READ_FAILURE;
        }

        bodylen -= keylen;
        if (memcached_string_check(&result->value,
                                   bodylen) != MEMCACHED_SUCCESS)
          return MEMCACHED_MEMORY_ALLOCATION_FAILURE;

        char *vptr= memcached_string_value_mutable(&result->value);
        if ((rc= memcached_safe_read(ptr, vptr, bodylen)) != MEMCACHED_SUCCESS)
        {
          WATCHPOINT_ERROR(rc);
          return MEMCACHED_UNKNOWN_READ_FAILURE;
        }

        memcached_string_set_length(&result->value, bodylen);
      }
      break;
    case PROTOCOL_BINARY_CMD_INCREMENT:
    case PROTOCOL_BINARY_CMD_DECREMENT:
      {
        if (bodylen != sizeof(uint64_t) || buffer_length != sizeof(uint64_t))
          return MEMCACHED_PROTOCOL_ERROR;

        WATCHPOINT_ASSERT(bodylen == buffer_length);
        uint64_t val;
        if ((rc= memcached_safe_read(ptr, &val, sizeof(val))) != MEMCACHED_SUCCESS)
        {
          WATCHPOINT_ERROR(rc);
          return MEMCACHED_UNKNOWN_READ_FAILURE;
        }

        val= ntohll(val);
        memcpy(buffer, &val, sizeof(val));
      }
      break;
    case PROTOCOL_BINARY_CMD_SASL_LIST_MECHS:
    case PROTOCOL_BINARY_CMD_VERSION:
      {
        memset(buffer, 0, buffer_length);
        if (bodylen >= buffer_length)
        {
          /* not enough space in buffer.. should not happen... */
          return MEMCACHED_UNKNOWN_READ_FAILURE;
        }
        else if ((rc= memcached_safe_read(ptr, buffer, bodylen)) != MEMCACHED_SUCCESS)
        {
          WATCHPOINT_ERROR(rc);
          return MEMCACHED_UNKNOWN_READ_FAILURE;
        }
      }
      break;
    case PROTOCOL_BINARY_CMD_FLUSH:
    case PROTOCOL_BINARY_CMD_QUIT:
    case PROTOCOL_BINARY_CMD_SET:
    case PROTOCOL_BINARY_CMD_ADD:
    case PROTOCOL_BINARY_CMD_REPLACE:
    case PROTOCOL_BINARY_CMD_APPEND:
    case PROTOCOL_BINARY_CMD_PREPEND:
    case PROTOCOL_BINARY_CMD_DELETE:
      {
        WATCHPOINT_ASSERT(bodylen == 0);
        return MEMCACHED_SUCCESS;
      }
    case PROTOCOL_BINARY_CMD_NOOP:
      {
        WATCHPOINT_ASSERT(bodylen == 0);
        return MEMCACHED_END;
      }
    case PROTOCOL_BINARY_CMD_STAT:
      {
        if (bodylen == 0)
        {
          return MEMCACHED_END;
        }
        else if (bodylen + 1 > buffer_length)
        {
          /* not enough space in buffer.. should not happen... */
          return MEMCACHED_UNKNOWN_READ_FAILURE;
        }
        else
        {
          size_t keylen= header.response.keylen;
          memset(buffer, 0, buffer_length);
          if ((rc= memcached_safe_read(ptr, buffer, keylen)) != MEMCACHED_SUCCESS ||
              (rc= memcached_safe_read(ptr, buffer + keylen + 1, bodylen - keylen)) != MEMCACHED_SUCCESS)
          {
            WATCHPOINT_ERROR(rc);
            return MEMCACHED_UNKNOWN_READ_FAILURE;
          }
	  if (header.response.keylen > 0)
	  {
	    memcached_server_response_increment(ptr, header.response.opaque);
	  }
        }
      }
      break;

    case PROTOCOL_BINARY_CMD_SASL_AUTH:
    case PROTOCOL_BINARY_CMD_SASL_STEP:
      {
        memcached_result_reset(result);
        result->item_cas= header.response.cas;

        if (memcached_string_check(&result->value,
                                   bodylen) != MEMCACHED_SUCCESS)
          return MEMCACHED_MEMORY_ALLOCATION_FAILURE;

        char *vptr= memcached_string_value_mutable(&result->value);
        if ((rc= memcached_safe_read(ptr, vptr, bodylen)) != MEMCACHED_SUCCESS)
        {
          WATCHPOINT_ERROR(rc);
          return MEMCACHED_UNKNOWN_READ_FAILURE;
        }

        memcached_string_set_length(&result->value, bodylen);
      }
      break;
    default:
      {
        /* Command not implemented yet! */
        WATCHPOINT_ASSERT(0);
        return MEMCACHED_PROTOCOL_ERROR;
      }
    }
  }
  else if (header.response.bodylen)
  {
    /* What should I do with the error message??? just discard it for now */
    char hole[SMALL_STRING_LEN];
    while (bodylen > 0)
    {
      size_t nr= (bodylen > SMALL_STRING_LEN) ? SMALL_STRING_LEN : bodylen;
      if ((rc= memcached_safe_read(ptr, hole, nr)) != MEMCACHED_SUCCESS)
      {
        WATCHPOINT_ERROR(rc);
        return MEMCACHED_UNKNOWN_READ_FAILURE;
      }
      bodylen-= (uint32_t) nr;
    }

    /* This might be an error from one of the quiet commands.. if
     * so, just throw it away and get the next one. What about creating
     * a callback to the user with the error information?
   */
    switch (header.response.opcode)
    {
    case PROTOCOL_BINARY_CMD_SETQ:
    case PROTOCOL_BINARY_CMD_ADDQ:
    case PROTOCOL_BINARY_CMD_REPLACEQ:
    case PROTOCOL_BINARY_CMD_APPENDQ:
    case PROTOCOL_BINARY_CMD_PREPENDQ:
      if (!ptr->root->flags.check_opaque)
         memcached_server_response_increment(ptr, 0);
      return binary_read_one_response(ptr, buffer, buffer_length, result);
    default:
      break;
    }
  }

  rc= MEMCACHED_SUCCESS;
  unlikely(header.response.status != 0)
    switch (header.response.status)
    {
    case PROTOCOL_BINARY_RESPONSE_KEY_ENOENT:
      rc= MEMCACHED_NOTFOUND;
      break;
    case PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS:
      rc= MEMCACHED_DATA_EXISTS;
      break;
    case PROTOCOL_BINARY_RESPONSE_NOT_STORED:
      rc= MEMCACHED_NOTSTORED;
      break;
    case PROTOCOL_BINARY_RESPONSE_E2BIG:
      rc= MEMCACHED_E2BIG;
      break;
    case PROTOCOL_BINARY_RESPONSE_ENOMEM:
      rc= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
      break;
    case PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE:
      rc= MEMCACHED_AUTH_CONTINUE;
      break;
    case PROTOCOL_BINARY_RESPONSE_AUTH_ERROR:
      rc= MEMCACHED_AUTH_FAILURE;
      break;
    case PROTOCOL_BINARY_RESPONSE_EINVAL:
    case PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND:
    default:
      /* @todo fix the error mappings */
      rc= MEMCACHED_PROTOCOL_ERROR;
      break;
    }

  return rc;
}