Example #1
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;
}
Example #2
0
static ssize_t io_flush(memcached_server_st *ptr,
                        memcached_return *error)
{
  size_t sent_length;
  size_t return_length;
  char *local_write_ptr= ptr->write_buffer;
  size_t write_length= ptr->write_buffer_offset;

  *error= MEMCACHED_SUCCESS;

  if (ptr->write_buffer_offset == 0)
    return 0;

  /* Looking for memory overflows */
  if (write_length == MEMCACHED_MAX_BUFFER)
    WATCHPOINT_ASSERT(ptr->write_buffer == local_write_ptr);
  WATCHPOINT_ASSERT((ptr->write_buffer + MEMCACHED_MAX_BUFFER) >= (local_write_ptr + write_length));

  return_length= 0;
  while (write_length)
  {
    WATCHPOINT_ASSERT(write_length > 0);
    sent_length= 0;
    if (ptr->type == MEMCACHED_CONNECTION_UDP)
    {
      struct addrinfo *ai;

      ai= ptr->address_info;

      /* Crappy test code */
      char buffer[HUGE_STRING_LEN + 8];
      memset(buffer, 0, HUGE_STRING_LEN + 8);
      memcpy (buffer+8, local_write_ptr, write_length);
      buffer[0]= 0;
      buffer[1]= 0;
      buffer[2]= 0;
      buffer[3]= 0;
      buffer[4]= 0;
      buffer[5]= 1;
      buffer[6]= 0;
      buffer[7]= 0;
      sent_length= sendto(ptr->fd, buffer, write_length + 8, 0, 
                          (struct sockaddr *)ai->ai_addr, 
                          ai->ai_addrlen);
      if (sent_length == -1)
      {
        WATCHPOINT_ERRNO(errno);
        WATCHPOINT_ASSERT(0);
      }
      sent_length-= 8; /* We remove the header */
    }
    else
    {
      if ((ssize_t)(sent_length= write(ptr->fd, local_write_ptr, 
                                       write_length)) == -1)
      {
        switch (errno)
        {
        case ENOBUFS:
          continue;
        case EAGAIN:
          {
            memcached_return rc;
            rc= io_wait(ptr, MEM_WRITE);

            if (rc == MEMCACHED_SUCCESS)
              continue;

            memcached_quit_server(ptr, 1);
            return -1;
          }
        default:
          memcached_quit_server(ptr, 1);
          ptr->cached_errno= errno;
          *error= MEMCACHED_ERRNO;
          return -1;
        }
      }
    }

    local_write_ptr+= sent_length;
    write_length-= sent_length;
    return_length+= sent_length;
  }

  WATCHPOINT_ASSERT(write_length == 0);
  WATCHPOINT_ASSERT(return_length == ptr->write_buffer_offset);
  ptr->write_buffer_offset= 0;

  return return_length;
}