+static memcached_return_t connect_poll(memcached_server_st *ptr)
+{
+ struct pollfd fds[1];
+ fds[0].fd = ptr->fd;
+ fds[0].events = POLLOUT;
+
+ int timeout= ptr->root->connect_timeout;
+ if (ptr->root->flags.no_block == true)
+ timeout= -1;
+
+ int error;
+ size_t loop_max= 5;
+
+ while (--loop_max) // Should only loop on cases of ERESTART or EINTR
+ {
+ error= poll(fds, 1, timeout);
+
+ switch (error)
+ {
+ case 1:
+ {
+ int err;
+ socklen_t len= sizeof (err);
+ (void)getsockopt(ptr->fd, SOL_SOCKET, SO_ERROR, &err, &len);
+
+ // We check the value to see what happened wth the socket.
+ if (err == 0)
+ {
+ return MEMCACHED_SUCCESS;
+ }
+ else
+ {
+ ptr->cached_errno= errno;
+
+ return MEMCACHED_ERRNO;
+ }
+ }
+ case 0:
+ return MEMCACHED_TIMEOUT;
+ default: // A real error occurred and we need to completely bail
+ WATCHPOINT_ERRNO(errno);
+ switch (errno)
+ {
+#ifdef TARGET_OS_LINUX
+ case ERESTART:
+#endif
+ case EINTR:
+ continue;
+ default:
+ if (fds[0].revents & POLLERR)
+ {
+ int err;
+ socklen_t len= sizeof (err);
+ (void)getsockopt(ptr->fd, SOL_SOCKET, SO_ERROR, &err, &len);
+ ptr->cached_errno= (err == 0) ? errno : err;
+ }
+ else
+ {
+ ptr->cached_errno= errno;
+ }
+
+ (void)close(ptr->fd);
+ ptr->fd= -1;
+
+ return MEMCACHED_ERRNO;
+ }
+ }
+ WATCHPOINT_ASSERT(0); // Programming error
+ }
+
+ // This should only be possible from ERESTART or EINTR;
+ ptr->cached_errno= errno;
+
+ return MEMCACHED_ERRNO;
+}
+