- return instance;
- }
- }
- }
- }
-
- return NULL;
-}
-
-static ssize_t io_flush(memcached_server_write_instance_st ptr,
- const bool with_flush,
- memcached_return_t *error)
-{
- /*
- ** We might want to purge the input buffer if we haven't consumed
- ** any output yet... The test for the limits is the purge is inline
- ** in the purge function to avoid duplicating the logic..
- */
- {
- memcached_return_t rc;
- WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
- rc= memcached_purge(ptr);
-
- if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_STORED)
- {
- return -1;
- }
- }
- ssize_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;
-
- WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
-
- // UDP Sanity check, make sure that we are not sending somthing too big
- if (ptr->type == MEMCACHED_CONNECTION_UDP && write_length > MAX_UDP_DATAGRAM_LENGTH)
- {
- *error= MEMCACHED_WRITE_FAILURE;
- return -1;
- }
-
- if (ptr->write_buffer_offset == 0 || (ptr->type == MEMCACHED_CONNECTION_UDP
- && ptr->write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH))
- {
- return 0;
- }
-
- /* Looking for memory overflows */
-#if defined(DEBUG)
- 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));
-#endif
-
- return_length= 0;
- while (write_length)
- {
- WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
- WATCHPOINT_ASSERT(write_length > 0);
- sent_length= 0;
- if (ptr->type == MEMCACHED_CONNECTION_UDP)
- increment_udp_message_id(ptr);
-
- WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
- if (with_flush)
- {
- sent_length= send(ptr->fd, local_write_ptr, write_length, MSG_NOSIGNAL|MSG_DONTWAIT);
- }
- else
- {
- sent_length= send(ptr->fd, local_write_ptr, write_length, MSG_NOSIGNAL|MSG_DONTWAIT|MSG_MORE);
- }
-
- if (sent_length == SOCKET_ERROR)
- {
- ptr->cached_errno= get_socket_errno();
-#if 0 // @todo I should look at why we hit this bit of code hard frequently
- WATCHPOINT_ERRNO(get_socket_errno());
- WATCHPOINT_NUMBER(get_socket_errno());
-#endif
- switch (get_socket_errno())
- {
- case ENOBUFS:
- continue;
- case EWOULDBLOCK:
-#ifdef USE_EAGAIN
- case EAGAIN:
-#endif
- {
- /*
- * We may be blocked on write because the input buffer
- * is full. Let's check if we have room in our input
- * buffer for more data and retry the write before
- * waiting..
- */
- if (repack_input_buffer(ptr) or
- process_input_buffer(ptr))
- {
- continue;
- }
-
- memcached_return_t rc= io_wait(ptr, MEM_WRITE);
- if (memcached_success(rc))
- {
- continue;
- }
- else if (rc == MEMCACHED_TIMEOUT)