Exemplo n.º 1
0
liMemcachedRequest* li_memcached_get(liMemcachedCon *con, GString *key, liMemcachedCB callback, gpointer cb_data, GError **err) {
	int_request* req;

	if (!li_memcached_is_key_valid(key)) {
		g_set_error(err, LI_MEMCACHED_ERROR, LI_MEMCACHED_BAD_KEY, "Invalid key: '%s'", key->str);
		return NULL;
	}

	if (-1 == con->fd) memcached_connect(con);
	if (-1 == con->fd) {
		if (NULL == con->err) {
			g_set_error(err, LI_MEMCACHED_ERROR, LI_MEMCACHED_DISABLED, "Not connected");
		} else if (err) {
			*err = g_error_copy(con->err);
		}
		return NULL;
	}

	req = g_slice_new0(int_request);
	req->req.callback = callback;
	req->req.cb_data = cb_data;

	req->type = REQ_GET;
	req->key = g_string_new_len(GSTR_LEN(key));

	if (!push_request(con, req, err)) {
		free_request(con, req);
		return NULL;
	}

	return &req->req;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
liMemcachedCon* li_memcached_con_new(liEventLoop *loop, liSocketAddress addr) {
	liMemcachedCon* con = g_slice_new0(liMemcachedCon);

	con->refcount = 1;
	con->addr = li_sockaddr_dup(addr);
	con->tmpstr = g_string_sized_new(511);

	con->fd = -1;
	li_event_io_init(loop, "memcached", &con->con_watcher, memcached_io_cb, -1, 0);
	li_event_set_keep_loop_alive(&con->con_watcher, FALSE);

	memcached_connect(con);

	return con;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
static void close_con(liMemcachedCon *con) {
	if (con->line) con->line->used = 0;
	if (con->remaining) con->remaining->used = 0;
	if (con->data) con->data->used = 0;
	if (con->buf) con->buf->used = 0;
	reset_item(&con->curitem);
	send_queue_reset(&con->out);

	memcached_stop_io(con);
	close(li_event_io_fd(&con->con_watcher));
	con->fd = -1;
	li_event_io_set_fd(&con->con_watcher, -1);
	con->cur_req = NULL;
	cancel_all_requests(con);
	memcached_connect(con);
}
Exemplo n.º 6
0
liMemcachedCon* li_memcached_con_new(struct ev_loop *loop, liSocketAddress addr) {
	liMemcachedCon* con = g_slice_new0(liMemcachedCon);

	con->refcount = 1;
	con->loop = loop;
	con->addr = li_sockaddr_dup(addr);
	con->tmpstr = g_string_sized_new(511);

	con->fd = -1;
	ev_io_init(&con->con_watcher, memcached_io_cb, -1, 0);
	con->con_watcher.data = con;

	memcached_connect(con);

	return con;
}
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;
}
Exemplo n.º 8
0
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)
    return rc;

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

  if (sent_length == -1 || sent_length != command_length)
    rc= MEMCACHED_WRITE_FAILURE;
  else
    memcached_server_response_increment(ptr);

  return rc;
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
memcached_return_t memcached_behavior_set(memcached_st *ptr,
                                          const memcached_behavior_t flag,
                                          uint64_t data)
{
  switch (flag)
  {
  case MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS:
    ptr->number_of_replicas= (uint32_t)data;
    break;
  case MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK:
    ptr->io_msg_watermark= (uint32_t) data;
    break;
  case MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK:
    ptr->io_bytes_watermark= (uint32_t)data;
    break;
  case MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH:
    ptr->io_key_prefetch = (uint32_t)data;
    break;
  case MEMCACHED_BEHAVIOR_SND_TIMEOUT:
    ptr->snd_timeout= (int32_t)data;
    break;
  case MEMCACHED_BEHAVIOR_RCV_TIMEOUT:
    ptr->rcv_timeout= (int32_t)data;
    break;
  case MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT:
    ptr->server_failure_limit= (uint32_t)data;
    break;
  case MEMCACHED_BEHAVIOR_BINARY_PROTOCOL:
    memcached_quit(ptr); // We need t shutdown all of the connections to make sure we do the correct protocol
    if (data)
    {
      ptr->flags.verify_key= false;
    }
    ptr->flags.binary_protocol= set_flag(data);
    break;
  case MEMCACHED_BEHAVIOR_SUPPORT_CAS:
    ptr->flags.support_cas= set_flag(data);
    break;
  case MEMCACHED_BEHAVIOR_NO_BLOCK:
    ptr->flags.no_block= set_flag(data);
    memcached_quit(ptr);
    break;
  case MEMCACHED_BEHAVIOR_BUFFER_REQUESTS:
    ptr->flags.buffer_requests= set_flag(data);
    memcached_quit(ptr);
    break;
  case MEMCACHED_BEHAVIOR_USE_UDP:
    if (memcached_server_count(ptr))
    {
      return MEMCACHED_FAILURE;
    }
    ptr->flags.use_udp= set_flag(data);
    if (data)
    {
      ptr->flags.no_reply= set_flag(data);
    }
    break;
  case MEMCACHED_BEHAVIOR_TCP_NODELAY:
    ptr->flags.tcp_nodelay= set_flag(data);
    memcached_quit(ptr);
    break;
  case MEMCACHED_BEHAVIOR_TCP_KEEPALIVE:
    ptr->flags.tcp_keepalive= set_flag(data);
    memcached_quit(ptr);
    break;
  case MEMCACHED_BEHAVIOR_DISTRIBUTION:
    return memcached_behavior_set_distribution(ptr, (memcached_server_distribution_t)data);
  case MEMCACHED_BEHAVIOR_KETAMA:
    {
      if (data)
      {
        (void)memcached_behavior_set_key_hash(ptr, MEMCACHED_HASH_MD5);
        (void)memcached_behavior_set_distribution_hash(ptr, MEMCACHED_HASH_MD5);
        (void)memcached_behavior_set_distribution(ptr, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA);
      }
      else
      {
        (void)memcached_behavior_set_key_hash(ptr, MEMCACHED_HASH_DEFAULT);
        (void)memcached_behavior_set_distribution_hash(ptr, MEMCACHED_HASH_DEFAULT);
        (void)memcached_behavior_set_distribution(ptr, MEMCACHED_DISTRIBUTION_MODULA);
      }

      break;
    }
  case MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED:
    {
      (void)memcached_behavior_set_key_hash(ptr, MEMCACHED_HASH_MD5);
      (void)memcached_behavior_set_distribution_hash(ptr, MEMCACHED_HASH_MD5);
      ptr->flags.ketama_weighted= set_flag(data);
      /**
        @note We try to keep the same distribution going. This should be deprecated and rewritten.
      */
      return memcached_behavior_set_distribution(ptr, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA);
    }
  case MEMCACHED_BEHAVIOR_HASH:
    return memcached_behavior_set_key_hash(ptr, (memcached_hash_t)(data));
  case MEMCACHED_BEHAVIOR_KETAMA_HASH:
    return memcached_behavior_set_distribution_hash(ptr, (memcached_hash_t)(data));
  case MEMCACHED_BEHAVIOR_CACHE_LOOKUPS:
    ptr->flags.use_cache_lookups= set_flag(data);
    memcached_quit(ptr);
    break;
  case MEMCACHED_BEHAVIOR_VERIFY_KEY:
    if (ptr->flags.binary_protocol)
      return MEMCACHED_FAILURE;
    ptr->flags.verify_key= set_flag(data);
    break;
  case MEMCACHED_BEHAVIOR_SORT_HOSTS:
    {
      ptr->flags.use_sort_hosts= set_flag(data);
      run_distribution(ptr);

      break;
    }
  case MEMCACHED_BEHAVIOR_POLL_TIMEOUT:
    ptr->poll_timeout= (int32_t)data;
    break;
  case MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT:
    ptr->connect_timeout= (int32_t)data;
    break;
  case MEMCACHED_BEHAVIOR_RETRY_TIMEOUT:
    ptr->retry_timeout= (int32_t)data;
    break;
  case MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE:
    ptr->send_size= (int32_t)data;
    memcached_quit(ptr);
    break;
  case MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE:
    ptr->recv_size= (int32_t)data;
    memcached_quit(ptr);
    break;
  case MEMCACHED_BEHAVIOR_TCP_KEEPIDLE:
    ptr->tcp_keepidle= (uint32_t)data;
    memcached_quit(ptr);
    break;
  case MEMCACHED_BEHAVIOR_USER_DATA:
    return MEMCACHED_FAILURE;
  case MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY:
    ptr->flags.hash_with_prefix_key= set_flag(data);
    break;
  case MEMCACHED_BEHAVIOR_NOREPLY:
    ptr->flags.no_reply= set_flag(data);
    break;
  case MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS:
    ptr->flags.auto_eject_hosts= set_flag(data);
    break;
  case MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ:
      srandom((uint32_t) time(NULL));
      ptr->flags.randomize_replica_read= set_flag(data);
      break;
  case MEMCACHED_BEHAVIOR_CORK:
      {
        memcached_server_write_instance_st instance;
        bool action= set_flag(data);

        if (action == false)
        {
          ptr->flags.cork= set_flag(false);
          return MEMCACHED_SUCCESS;
        }

        instance= memcached_server_instance_fetch(ptr, 0);
        if (! instance)
          return MEMCACHED_NO_SERVERS;


        /* We just try the first host, and if it is down we return zero */
        memcached_return_t rc;
        rc= memcached_connect(instance);
        if (rc != MEMCACHED_SUCCESS)
        {
          return rc;
        }

        /* Now we test! */
        memcached_ternary_t enabled;
        enabled= test_cork(instance, true);

        switch (enabled)
        {
        case MEM_FALSE:
          return ptr->cached_errno ? MEMCACHED_ERRNO : MEMCACHED_FAILURE ;
        case MEM_TRUE:
          {
            enabled= test_cork(instance, false);

            if (enabled == false) // Possible bug in OS?
            {
              memcached_quit_server(instance, false); // We should reset everything on this error.
              return MEMCACHED_ERRNO;  // Errno will be true because we will have already set it.
            }
            ptr->flags.cork= true;
            ptr->flags.tcp_nodelay= true;
            memcached_quit(ptr); // We go on and reset the connections.
          }
          break;
        case MEM_NOT:
        default:
          return MEMCACHED_NOT_SUPPORTED;
        }
      }
      break;
  case MEMCACHED_BEHAVIOR_MAX:
  default:
    /* Shouldn't get here */
    WATCHPOINT_ASSERT(0);
    return MEMCACHED_FAILURE;
  }

  return MEMCACHED_SUCCESS;
}
Exemplo n.º 11
0
uint64_t memcached_behavior_get(memcached_st *ptr,
                                const memcached_behavior_t flag)
{
  switch (flag)
  {
  case MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS:
    return ptr->number_of_replicas;
  case MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK:
    return ptr->io_msg_watermark;
  case MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK:
    return ptr->io_bytes_watermark;
  case MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH:
    return ptr->io_key_prefetch;
  case MEMCACHED_BEHAVIOR_BINARY_PROTOCOL:
    return ptr->flags.binary_protocol;
  case MEMCACHED_BEHAVIOR_SUPPORT_CAS:
    return ptr->flags.support_cas;
  case MEMCACHED_BEHAVIOR_CACHE_LOOKUPS:
    return ptr->flags.use_cache_lookups;
  case MEMCACHED_BEHAVIOR_NO_BLOCK:
    return ptr->flags.no_block;
  case MEMCACHED_BEHAVIOR_BUFFER_REQUESTS:
    return ptr->flags.buffer_requests;
  case MEMCACHED_BEHAVIOR_USE_UDP:
    return ptr->flags.use_udp;
  case MEMCACHED_BEHAVIOR_TCP_NODELAY:
    return ptr->flags.tcp_nodelay;
  case MEMCACHED_BEHAVIOR_VERIFY_KEY:
    return ptr->flags.verify_key;
  case MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED:
    return ptr->flags.ketama_weighted;
  case MEMCACHED_BEHAVIOR_DISTRIBUTION:
    return ptr->distribution;
  case MEMCACHED_BEHAVIOR_KETAMA:
    return (ptr->distribution == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA) ? (uint64_t) 1 : 0;
  case MEMCACHED_BEHAVIOR_HASH:
    return hashkit_get_function(&ptr->hashkit);
  case MEMCACHED_BEHAVIOR_KETAMA_HASH:
    return hashkit_get_function(&ptr->distribution_hashkit);
  case MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT:
    return ptr->server_failure_limit;
  case MEMCACHED_BEHAVIOR_SORT_HOSTS:
    return ptr->flags.use_sort_hosts;
  case MEMCACHED_BEHAVIOR_POLL_TIMEOUT:
    return (uint64_t)ptr->poll_timeout;
  case MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT:
    return (uint64_t)ptr->connect_timeout;
  case MEMCACHED_BEHAVIOR_RETRY_TIMEOUT:
    return (uint64_t)ptr->retry_timeout;
  case MEMCACHED_BEHAVIOR_SND_TIMEOUT:
    return (uint64_t)ptr->snd_timeout;
  case MEMCACHED_BEHAVIOR_RCV_TIMEOUT:
    return (uint64_t)ptr->rcv_timeout;
  case MEMCACHED_BEHAVIOR_TCP_KEEPIDLE:
    return (uint64_t)ptr->tcp_keepidle;
  case MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE:
    {
      int sock_size= 0;
      socklen_t sock_length= sizeof(int);
      memcached_server_write_instance_st instance;

      if (ptr->send_size != -1) // If value is -1 then we are using the default
        return (uint64_t) ptr->send_size;

      instance= memcached_server_instance_fetch(ptr, 0);

      if (instance) // If we have an instance we test, otherwise we just set and pray
      {
        /* REFACTOR */
        /* We just try the first host, and if it is down we return zero */
        if ((memcached_connect(instance)) != MEMCACHED_SUCCESS)
          return 0;

        if (getsockopt(instance->fd, SOL_SOCKET,
                       SO_SNDBUF, &sock_size, &sock_length))
          return 0; /* Zero means error */
      }

      return (uint64_t) sock_size;
    }
  case MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE:
    {
      int sock_size= 0;
      socklen_t sock_length= sizeof(int);
      memcached_server_write_instance_st instance;

      if (ptr->recv_size != -1) // If value is -1 then we are using the default
        return (uint64_t) ptr->recv_size;

      instance= memcached_server_instance_fetch(ptr, 0);

      /**
        @note REFACTOR
      */
      if (instance)
      {
        /* We just try the first host, and if it is down we return zero */
        if ((memcached_connect(instance)) != MEMCACHED_SUCCESS)
          return 0;

        if (getsockopt(instance->fd, SOL_SOCKET,
                       SO_RCVBUF, &sock_size, &sock_length))
          return 0; /* Zero means error */

      }

      return (uint64_t) sock_size;
    }
  case MEMCACHED_BEHAVIOR_USER_DATA:
    return MEMCACHED_FAILURE;
  case MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY:
    return ptr->flags.hash_with_prefix_key;
  case MEMCACHED_BEHAVIOR_NOREPLY:
    return ptr->flags.no_reply;
  case MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS:
    return ptr->flags.auto_eject_hosts;
  case MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ:
    return ptr->flags.randomize_replica_read;
  case MEMCACHED_BEHAVIOR_CORK:
    return ptr->flags.cork;
  case MEMCACHED_BEHAVIOR_TCP_KEEPALIVE:
    return ptr->flags.tcp_keepalive;
  case MEMCACHED_BEHAVIOR_MAX:
  default:
    WATCHPOINT_ASSERT(0); /* Programming mistake if it gets this far */
    return 0;
  }

  /* NOTREACHED */
}
Exemplo n.º 12
0
static void memcached_io_cb(liEventBase *watcher, int events) {
	liMemcachedCon *con = LI_CONTAINER_OF(li_event_io_from(watcher), liMemcachedCon, con_watcher);

	if (1 == g_atomic_int_get(&con->refcount) && li_event_active(&con->con_watcher)) {
		memcached_stop_io(con);
		return;
	}

	if (-1 == con->fd) {
		memcached_connect(con);
		return;
	}

	li_memcached_con_acquire(con); /* make sure con isn't freed in the middle of something */

	if (events & LI_EV_WRITE) {
		int i;
		ssize_t written, len;
		gchar *data;
		send_item *si;

		si = g_queue_peek_head(&con->out);

		for (i = 0; si && (i < 10); i++) { /* don't send more than 10 chunks */
			data = si->buf->addr + si->pos;
			len = si->len;
			written = write(li_event_io_fd(&con->con_watcher), data, len);
			if (written < 0) {
				switch (errno) {
				case EINTR:
					continue;
				case EAGAIN:
#if EWOULDBLOCK != EAGAIN
				case EWOULDBLOCK:
#endif
					goto write_eagain;
				default: /* Fatal error, connection has to be closed */
					g_clear_error(&con->err);
					g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Couldn't write socket '%s': %s",
						li_sockaddr_to_string(con->addr, con->tmpstr, TRUE)->str,
						g_strerror(errno));
					close_con(con);
					goto out;
				}
			} else {
				si->pos += written;
				si->len -= written;
				if (0 == si->len) {
					send_queue_item_free(si);
					g_queue_pop_head(&con->out);
					si = g_queue_peek_head(&con->out);
				}
			}
		}

write_eagain:
		send_queue_clean(&con->out);
	}

	if (events & LI_EV_READ) {
		do {
			handle_read(con);
		} while (con->remaining && con->remaining->used > 0);
	}

out:
	memcached_update_io(con);
	li_memcached_con_release(con);
}
Exemplo n.º 13
0
uint64_t memcached_behavior_get(memcached_st *ptr,
                                memcached_behavior flag)
{
  memcached_flags temp_flag= MEM_NO_BLOCK;

  switch (flag)
  {
  case MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK:
    return ptr->io_msg_watermark;
  case MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK:
    return ptr->io_bytes_watermark;
  case MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH:
    return ptr->io_key_prefetch;
  case MEMCACHED_BEHAVIOR_BINARY_PROTOCOL:
    temp_flag= MEM_BINARY_PROTOCOL;
    break;
  case MEMCACHED_BEHAVIOR_SUPPORT_CAS:
    temp_flag= MEM_SUPPORT_CAS;
    break;
  case MEMCACHED_BEHAVIOR_CACHE_LOOKUPS:
    temp_flag= MEM_USE_CACHE_LOOKUPS;
    break;
  case MEMCACHED_BEHAVIOR_NO_BLOCK:
    temp_flag= MEM_NO_BLOCK;
    break;
  case MEMCACHED_BEHAVIOR_BUFFER_REQUESTS:
    temp_flag= MEM_BUFFER_REQUESTS;
    break;
  case MEMCACHED_BEHAVIOR_USE_UDP:
    temp_flag= MEM_USE_UDP;
    break;
  case MEMCACHED_BEHAVIOR_TCP_NODELAY:
    temp_flag= MEM_TCP_NODELAY;
    break;
  case MEMCACHED_BEHAVIOR_VERIFY_KEY:
    temp_flag= MEM_VERIFY_KEY;
    break;
  case MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED:
    temp_flag= MEM_KETAMA_WEIGHTED;
    break;
  case MEMCACHED_BEHAVIOR_DISTRIBUTION:
    return ptr->distribution;
  case MEMCACHED_BEHAVIOR_KETAMA:
    return (ptr->distribution == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA) ? (uint64_t) 1 : 0;
  case MEMCACHED_BEHAVIOR_HASH:
    return ptr->hash;
  case MEMCACHED_BEHAVIOR_KETAMA_HASH:
    return ptr->hash_continuum;
  case MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT:
    return ptr->server_failure_limit;
  case MEMCACHED_BEHAVIOR_SORT_HOSTS:
    temp_flag= MEM_USE_SORT_HOSTS;
    break;
  case MEMCACHED_BEHAVIOR_POLL_TIMEOUT:
    return (uint64_t)ptr->poll_timeout;
  case MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT:
    return (uint64_t)ptr->connect_timeout;
  case MEMCACHED_BEHAVIOR_RETRY_TIMEOUT:
    return (uint64_t)ptr->retry_timeout;
  case MEMCACHED_BEHAVIOR_SND_TIMEOUT:
    return (uint64_t)ptr->snd_timeout;
  case MEMCACHED_BEHAVIOR_RCV_TIMEOUT:
    return (uint64_t)ptr->rcv_timeout;
  case MEMCACHED_BEHAVIOR_POLL_MAX_RETRIES:
    return (uint64_t)ptr->poll_max_retries;
  case MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE:
    {
      int sock_size;
      socklen_t sock_length= sizeof(int);

      /* REFACTOR */
      /* We just try the first host, and if it is down we return zero */
      if ((memcached_connect(&ptr->hosts[0])) != MEMCACHED_SUCCESS)
        return 0;

      if (getsockopt(ptr->hosts[0].fd, SOL_SOCKET,
                     SO_SNDBUF, &sock_size, &sock_length))
        return 0; /* Zero means error */

      return (uint64_t) sock_size;
    }
  case MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE:
    {
      int sock_size;
      socklen_t sock_length= sizeof(int);

      /* REFACTOR */
      /* We just try the first host, and if it is down we return zero */
      if ((memcached_connect(&ptr->hosts[0])) != MEMCACHED_SUCCESS)
        return 0;

      if (getsockopt(ptr->hosts[0].fd, SOL_SOCKET,
                     SO_RCVBUF, &sock_size, &sock_length))
        return 0; /* Zero means error */

      return (uint64_t) sock_size;
    }
  case MEMCACHED_BEHAVIOR_USER_DATA:
    return MEMCACHED_FAILURE;
  case MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY:
    temp_flag= MEM_HASH_WITH_PREFIX_KEY;
    break;
  case MEMCACHED_BEHAVIOR_NOREPLY:
    temp_flag= MEM_NOREPLY;
    break;
  case MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS:
    temp_flag= MEM_AUTO_EJECT_HOSTS;
    break;
  default:
    WATCHPOINT_ASSERT(flag);
    break;
  }

  WATCHPOINT_ASSERT(temp_flag); /* Programming mistake if it gets this far */
  if (ptr->flags & temp_flag)
    return 1;
  else
    return 0;
}
Exemplo n.º 14
0
static int memcached_query_daemon (char *buffer, size_t buffer_size, memcached_t *st)
{
  int fd = -1;
  int status;
  size_t buffer_fill;

  fd = memcached_connect (st);
  if (fd < 0) {
    ERROR ("memcached plugin: Instance \"%s\" could not connect to daemon.",
        st->name);
    return -1;
  }

  status = (int) swrite (fd, "stats\r\n", strlen ("stats\r\n"));
  if (status != 0)
  {
    char errbuf[1024];
    ERROR ("memcached plugin: write(2) failed: %s",
        sstrerror (errno, errbuf, sizeof (errbuf)));
    shutdown(fd, SHUT_RDWR);
    close (fd);
    return (-1);
  }

  /* receive data from the memcached daemon */
  memset (buffer, 0, buffer_size);

  buffer_fill = 0;
  while ((status = (int) recv (fd, buffer + buffer_fill,
          buffer_size - buffer_fill, /* flags = */ 0)) != 0)
  {
    char const end_token[5] = {'E', 'N', 'D', '\r', '\n'};
    if (status < 0)
    {
      char errbuf[1024];

      if ((errno == EAGAIN) || (errno == EINTR))
          continue;

      ERROR ("memcached: Error reading from socket: %s",
          sstrerror (errno, errbuf, sizeof (errbuf)));
      shutdown(fd, SHUT_RDWR);
      close (fd);
      return (-1);
    }

    buffer_fill += (size_t) status;
    if (buffer_fill > buffer_size)
    {
      buffer_fill = buffer_size;
      WARNING ("memcached plugin: Message was truncated.");
      break;
    }

    /* If buffer ends in end_token, we have all the data. */
    if (memcmp (buffer + buffer_fill - sizeof (end_token),
          end_token, sizeof (end_token)) == 0)
      break;
  } /* while (recv) */

  status = 0;
  if (buffer_fill == 0)
  {
    WARNING ("memcached plugin: No data returned by memcached.");
    status = -1;
  }

  shutdown(fd, SHUT_RDWR);
  close(fd);
  return (status);
} /* int memcached_query_daemon */