Esempio n. 1
0
static int redisContextWaitReady(redisContext *c, long msec) {
    struct pollfd   wfd[1];

    wfd[0].fd     = c->fd;
    wfd[0].events = POLLOUT;

    if (errno == EINPROGRESS) {
        int res;

        if ((res = poll(wfd, 1, msec)) == -1) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
            redisContextCloseFd(c);
            return REDIS_ERR;
        } else if (res == 0) {
            errno = ETIMEDOUT;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        if (redisCheckSocketError(c) != REDIS_OK)
            return REDIS_ERR;

        return REDIS_OK;
    }

    __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
    redisContextCloseFd(c);
    return REDIS_ERR;
}
Esempio n. 2
0
File: net.c Progetto: lamby/hiredis
static int redisContextWaitReady(redisContext *c, const struct timeval *timeout) {
    struct pollfd   wfd[1];
    long msec;

    msec          = -1;
    wfd[0].fd     = c->fd;
    wfd[0].events = POLLOUT;

    /* Only use timeout when not NULL. */
    if (timeout != NULL) {
        if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);

        if (msec < 0 || msec > INT_MAX) {
            msec = INT_MAX;
        }
    }

    if (errno == EINPROGRESS) {
        int res;

        if ((res = poll(wfd, 1, msec)) == -1) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
            redisContextCloseFd(c);
            return REDIS_ERR;
        } else if (res == 0) {
            errno = ETIMEDOUT;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        if (redisCheckSocketError(c) != REDIS_OK)
            return REDIS_ERR;

        return REDIS_OK;
    }

    __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
    redisContextCloseFd(c);
    return REDIS_ERR;
}
Esempio n. 3
0
/* Internal helper function to detect socket status the first time a read or
 * write event fires. When connecting was not succesful, the connect callback
 * is called with a REDIS_ERR status and the context is free'd. */
static int __redisAsyncHandleConnect(redisAsyncContext *ac) {
    redisContext *c = &(ac->c);

    if (redisCheckSocketError(c) == REDIS_ERR) {
        /* Try again later when connect(2) is still in progress. */
        if (errno == EINPROGRESS)
            return REDIS_OK;

        if (ac->onConnect) ac->onConnect(ac,REDIS_ERR);
        __redisAsyncDisconnect(ac);
        return REDIS_ERR;
    }

    /* Mark context as connected. */
    c->flags |= REDIS_CONNECTED;
    if (ac->onConnect) ac->onConnect(ac,REDIS_OK);
    return REDIS_OK;
}
Esempio n. 4
0
/* Internal helper function to detect socket status the first time a read or
 * write event fires. When connecting was not succesful, the connect callback
 * is called with a REDIS_ERR status and the context is free'd. */
static int __redisAsyncHandleConnect(redisAsyncContext *ac) {
    redisContext *c = &(ac->c);

    // 当一个套接口出错时,它会被 select 调用标记为既可读又可写。
    // 因此,我们要用 getsockopt() 判断是否连接真的创建成功了

    // 检测 socket 错误
    if (redisCheckSocketError(c,c->fd) == REDIS_ERR) {
        /* Try again later when connect(2) is still in progress. */
        if (errno == EINPROGRESS)
            return REDIS_OK;

        if (ac->onConnect) ac->onConnect(ac,REDIS_ERR);
        __redisAsyncDisconnect(ac);
        return REDIS_ERR;
    }

    // 连接是成功的
    /* Mark context as connected. */
    c->flags |= REDIS_CONNECTED;
    if (ac->onConnect) ac->onConnect(ac,REDIS_OK);
    return REDIS_OK;
}
Esempio n. 5
0
static int redisContextWaitReady(redisContext *c, int fd, const struct timeval *timeout) {
#ifdef HIREDIS_WIN
    // Keep using older select mechanism in windows
    struct timeval to;
    struct timeval *toptr = NULL;
    fd_set wfd;

    /* Only use timeout when not NULL. */
    if (timeout != NULL) {
        to = *timeout;
        toptr = &to;
    }

    if (errno == EINPROGRESS || errno == WSAEWOULDBLOCK) {
        FD_ZERO(&wfd);
        FD_SET(fd, &wfd);

        if (select(FD_SETSIZE, NULL, &wfd, NULL, toptr) == -1) {
            SETERRNO;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,"select(2)");
            close(fd);
            return REDIS_ERR;
        }

        if (!FD_ISSET(fd, &wfd)) {
            errno = WSAETIMEDOUT;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,"timed out");
            close(fd);
            return REDIS_ERR;
        }
#else
    // newer implementation uses poll
    struct pollfd   wfd[1];
    long msec;

    msec          = -1;
    wfd[0].fd     = fd;
    wfd[0].events = POLLOUT;

    /* Only use timeout when not NULL. */
    if (timeout != NULL) {
        if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
            close(fd);
            return REDIS_ERR;
        }

        msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);

        if (msec < 0 || msec > INT_MAX) {
            msec = INT_MAX;
        }
    }

    if (errno == EINPROGRESS) {
        int res;

        if ((res = poll(wfd, 1, msec)) == -1) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
            close(fd);
            return REDIS_ERR;
        } else if (res == 0) {
            errno = ETIMEDOUT;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
            close(fd);
            return REDIS_ERR;
        }
#endif

        if (redisCheckSocketError(c, fd) != REDIS_OK)
            return REDIS_ERR;

        return REDIS_OK;
    }

    SETERRNO;
    __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
    close(fd);
    return REDIS_ERR;
}

int redisCheckSocketError(redisContext *c, int fd) {
    int err = 0;
    socklen_t errlen = sizeof(err);

    if (getsockopt(fd, SOL_SOCKET, SO_ERROR,(char*)&err, &errlen) == -1) {
        SETERRNO;
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)");
        close(fd);
        return REDIS_ERR;
    }

    if (err) {
        errno = err;
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
        close(fd);
        return REDIS_ERR;
    }

    return REDIS_OK;
}
Esempio n. 6
0
static int redisContextWaitReady(redisContext *c, const struct timeval *timeout) {
#ifdef FASTOREDIS
    #ifdef OS_WIN
        fd_set master_set;
        FD_ZERO(&master_set);
        int max_sd = c->fd;
        FD_SET(c->fd, &master_set);

        struct timeval tm;
        tm.tv_sec  = 60;
        tm.tv_usec = 0;

        /* Only use timeout when not NULL. */
        if (timeout != NULL) {
            if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
                redisContextCloseFd(c);
                return REDIS_ERR;
            }
            tm = *timeout;
        }

        if (errno == EINPROGRESS) {
            int res;

            if ((res = select(max_sd + 1, &master_set, NULL, NULL, &tm)) == -1) {
                __redisSetErrorFromErrno(c, REDIS_ERR_IO, "select(2)");
                redisContextCloseFd(c);
                return REDIS_ERR;
            } else if (res == 0) {
                errno = ETIMEDOUT;
                __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
                redisContextCloseFd(c);
                return REDIS_ERR;
            }

            if (redisCheckSocketError(c) != REDIS_OK)
                return REDIS_ERR;

            return REDIS_OK;
        }

        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
        redisContextCloseFd(c);
        return REDIS_ERR;
    #else
        struct pollfd   wfd[1];
        long msec;

        msec          = -1;
        wfd[0].fd     = c->fd;
        wfd[0].events = POLLOUT;

        /* Only use timeout when not NULL. */
        if (timeout != NULL) {
            if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
                __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL);
                redisContextCloseFd(c);
                return REDIS_ERR;
            }

            msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);

            if (msec < 0 || msec > INT_MAX) {
                msec = INT_MAX;
            }
        }

        if (errno == EINPROGRESS) {
            int res;

            if ((res = poll(wfd, 1, msec)) == -1) {
                __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
                redisContextCloseFd(c);
                return REDIS_ERR;
            } else if (res == 0) {
                errno = ETIMEDOUT;
                __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
                redisContextCloseFd(c);
                return REDIS_ERR;
            }

            if (redisCheckSocketError(c) != REDIS_OK)
                return REDIS_ERR;

            return REDIS_OK;
        }

        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
        redisContextCloseFd(c);
        return REDIS_ERR;
    #endif
#else
    struct pollfd   wfd[1];
    long msec;

    msec          = -1;
    wfd[0].fd     = c->fd;
    wfd[0].events = POLLOUT;

    /* Only use timeout when not NULL. */
    if (timeout != NULL) {
        if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);

        if (msec < 0 || msec > INT_MAX) {
            msec = INT_MAX;
        }
    }

    if (errno == EINPROGRESS) {
        int res;

        if ((res = poll(wfd, 1, msec)) == -1) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
            redisContextCloseFd(c);
            return REDIS_ERR;
        } else if (res == 0) {
            errno = ETIMEDOUT;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        if (redisCheckSocketError(c) != REDIS_OK)
            return REDIS_ERR;

        return REDIS_OK;
    }

    __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
    redisContextCloseFd(c);
    return REDIS_ERR;
#endif
}
Esempio n. 7
0
static int redisContextWaitReady(redisContext *c, long msec) {
#ifdef FASTO
    #ifdef OS_WIN
        fd_set master_set;
        FD_ZERO(&master_set);
        int max_sd = c->fd;
        FD_SET(c->fd, &master_set);

        struct timeval tv;
        tv.tv_sec = msec/1000;
        tv.tv_usec = (msec % 1000) * 1000;

        if (errno == EINPROGRESS) {
            int res;

            if ((res = select(max_sd + 1, &master_set, NULL, NULL, &tv)) == -1) {
                __redisSetErrorFromErrno(c, REDIS_ERR_IO, "select(2)");
                redisContextCloseFd(c);
                return REDIS_ERR;
            } else if (res == 0) {
                errno = ETIMEDOUT;
                __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
                redisContextCloseFd(c);
                return REDIS_ERR;
            }

            if (redisCheckSocketError(c) != REDIS_OK)
                return REDIS_ERR;

            return REDIS_OK;
        }

        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
        redisContextCloseFd(c);
        return REDIS_ERR;
    #else
    struct pollfd   wfd[1];

    wfd[0].fd     = c->fd;
    wfd[0].events = POLLOUT;

    if (errno == EINPROGRESS) {
        int res;

        if ((res = poll(wfd, 1, msec)) == -1) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
            redisContextCloseFd(c);
            return REDIS_ERR;
        } else if (res == 0) {
            errno = ETIMEDOUT;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        if (redisCheckSocketError(c) != REDIS_OK)
            return REDIS_ERR;

        return REDIS_OK;
    }

    __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
    redisContextCloseFd(c);
    return REDIS_ERR;
    #endif
#else
    struct pollfd   wfd[1];

    wfd[0].fd     = c->fd;
    wfd[0].events = POLLOUT;

    if (errno == EINPROGRESS) {
        int res;

        if ((res = poll(wfd, 1, msec)) == -1) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
            redisContextCloseFd(c);
            return REDIS_ERR;
        } else if (res == 0) {
            errno = ETIMEDOUT;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        if (redisCheckSocketError(c) != REDIS_OK)
            return REDIS_ERR;

        return REDIS_OK;
    }

    __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
    redisContextCloseFd(c);
    return REDIS_ERR;
#endif
}
Esempio n. 8
0
static int redisContextWaitReady(redisContext *c, const struct timeval *timeout) {

    long msec;
    /* msec          = -1; */
    msec = 15000;   // 15 seconds
    /* Only use timeout when not NULL. */
    if (timeout != NULL) {
        if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL);
            redisContextCloseFd(c->fd);
            return REDIS_ERR;
        }

        msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);

        if (msec < 0 || msec > INT_MAX) {
            msec = INT_MAX;
        }
    }
#ifdef _WIN32
    fd_set wfd;    
    struct timeval toptr = {15, 0};
    if (timeout != NULL) {
        toptr.tv_sec = timeout->tv_sec;
        toptr.tv_usec = timeout->tv_usec;
    }
    if (errno == EINPROGRESS || errno == WSAEWOULDBLOCK) {
       FD_ZERO(&wfd);
       FD_SET(c->fd, &wfd);
       if (select(FD_SETSIZE, NULL, &wfd, NULL, &toptr) == -1) {
           SETERRNO;
           __redisSetErrorFromErrno(c,REDIS_ERR_IO,"select(2)");
           redisContextCloseFd(c->fd);
           return REDIS_ERR;
       }
       if (!FD_ISSET(c->fd, &wfd)) {
           #ifdef _WIN32
            errno = WSAETIMEDOUT;
           #else
           errno = ETIMEDOUT;
           #endif
           __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
           close(c->fd);
           return REDIS_ERR;
       }
       if (redisCheckSocketError(c) != REDIS_OK)
        return REDIS_ERR;
       return REDIS_OK;
    }
#else
    struct pollfd   wfd[1];
    if (errno == EINPROGRESS) {
        int res;
        wfd[0].fd     = c->fd;
        wfd[0].events = POLLOUT;

        if ((res = poll(wfd, 1, msec)) == -1) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
            redisContextCloseFd(c);
            return REDIS_ERR;
        } else if (res == 0) {
            errno = ETIMEDOUT;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        if (redisCheckSocketError(c) != REDIS_OK)
            return REDIS_ERR;

        return REDIS_OK;
    }
#endif
    __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
    redisContextCloseFd(c);
    return REDIS_ERR;
}
Esempio n. 9
0
static int redisContextWaitReady(redisContext *c, const struct timeval *timeout) {
	struct timeval to;
	struct timeval *toptr = NULL;
	fd_set wfd;

	/* Only use timeout when not NULL. */
	if (timeout != NULL) {
		to = *timeout;
		toptr = &to;
	}

#ifdef _WIN32
	if (errno == EINPROGRESS || errno == WSAEWOULDBLOCK) {
#else
	if (errno == EINPROGRESS) {
#endif
		FD_ZERO(&wfd);
		FD_SET(c->fd, &wfd);

		if (select(FD_SETSIZE, NULL, &wfd, &wfd, toptr) == -1) {
			SETERRNO;
			__redisSetErrorFromErrno(c, REDIS_ERR_IO, "select(2)");
			close(c->fd);
			return REDIS_ERR;
		}

		if (!FD_ISSET(c->fd, &wfd)) {
#ifdef _WIN32
			errno = WSAETIMEDOUT;
#else
			errno = ETIMEDOUT;
#endif
			__redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL);
			close(c->fd);
			return REDIS_ERR;
		}

		if (redisCheckSocketError(c) != REDIS_OK)
			return REDIS_ERR;

		return REDIS_OK;
	}

	SETERRNO;
	__redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL);
	close(c->fd);
	return REDIS_ERR;
}

int redisCheckSocketError(redisContext *c) {
    int err = 0;
    socklen_t errlen = sizeof(err);

    if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)");
        return REDIS_ERR;
    }

    if (err) {
        errno = err;
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
        return REDIS_ERR;
    }

    return REDIS_OK;
}