+ case EINTR:
+ continue;
+
+ case EFAULT:
+ case ENOMEM:
+ memcached_set_error(*instance, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT);
+
+ case EINVAL:
+ memcached_set_error(*instance, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, memcached_literal_param("RLIMIT_NOFILE exceeded, or if OSX the timeout value was invalid"));
+
+ default:
+ memcached_set_errno(*instance, local_errno, MEMCACHED_AT, memcached_literal_param("poll"));
+ }
+
+ break;
+ }
+
+ memcached_quit_server(instance, true);
+
+ if (memcached_has_error(instance))
+ {
+ return memcached_instance_error_return(instance);
+ }
+
+ return memcached_set_error(*instance, MEMCACHED_CONNECTION_FAILURE, MEMCACHED_AT,
+ memcached_literal_param("number of attempts to call io_wait() failed"));
+}
+
+static bool io_flush(memcached_instance_st* instance,
+ 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..
+ */
+ {
+ WATCHPOINT_ASSERT(instance->fd != INVALID_SOCKET);
+
+ if (memcached_purge(instance) == false)
+ {
+ return false;
+ }
+ }
+ char *local_write_ptr= instance->write_buffer;
+ size_t write_length= instance->write_buffer_offset;
+
+ error= MEMCACHED_SUCCESS;
+
+ WATCHPOINT_ASSERT(instance->fd != INVALID_SOCKET);
+
+ /* Looking for memory overflows */
+#if defined(DEBUG)
+ if (write_length == MEMCACHED_MAX_BUFFER)
+ WATCHPOINT_ASSERT(instance->write_buffer == local_write_ptr);
+ WATCHPOINT_ASSERT((instance->write_buffer + MEMCACHED_MAX_BUFFER) >= (local_write_ptr + write_length));
+#endif
+
+ while (write_length)
+ {
+ WATCHPOINT_ASSERT(instance->fd != INVALID_SOCKET);
+ WATCHPOINT_ASSERT(write_length > 0);
+
+ int flags;
+ if (with_flush)
+ {
+ flags= MSG_NOSIGNAL;
+ }
+ else
+ {
+ flags= MSG_NOSIGNAL|MSG_MORE;
+ }
+
+ ssize_t sent_length= ::send(instance->fd, local_write_ptr, write_length, flags);
+
+ if (sent_length == SOCKET_ERROR)
+ {
+#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;
+
+#if EWOULDBLOCK != EAGAIN
+ case EWOULDBLOCK:
+#endif
+ case EAGAIN:
+ {
+ /*
+ * 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(instance) or process_input_buffer(instance))
+ {
+ continue;
+ }
+
+ memcached_return_t rc= io_wait(instance, MEM_WRITE);
+ if (memcached_success(rc))
+ {
+ continue;
+ }
+ else if (rc == MEMCACHED_TIMEOUT)
+ {
+ return false;