winlin

Merge branch 'srs.master'

... ... @@ -54,9 +54,9 @@
#if EAGAIN != EWOULDBLOCK
#define _IO_NOT_READY_ERROR ((errno == EAGAIN) || (errno == EWOULDBLOCK))
#define _IO_NOT_READY_ERROR ((errno == EAGAIN) || (errno == EWOULDBLOCK))
#else
#define _IO_NOT_READY_ERROR (errno == EAGAIN)
#define _IO_NOT_READY_ERROR (errno == EAGAIN)
#endif
#define _LOCAL_MAXIOV 16
... ... @@ -78,20 +78,23 @@ int _st_io_init(void)
sigact.sa_handler = SIG_IGN;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = 0;
if (sigaction(SIGPIPE, &sigact, NULL) < 0)
if (sigaction(SIGPIPE, &sigact, NULL) < 0) {
return -1;
}
/* Set maximum number of open file descriptors */
if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
return -1;
}
fdlim = (*_st_eventsys->fd_getlimit)();
if (fdlim > 0 && rlim.rlim_max > (rlim_t) fdlim) {
rlim.rlim_max = fdlim;
}
rlim.rlim_cur = rlim.rlim_max;
if (setrlimit(RLIMIT_NOFILE, &rlim) < 0)
if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
return -1;
}
_st_osfd_limit = (int) rlim.rlim_max;
return 0;
... ... @@ -106,14 +109,17 @@ int st_getfdlimit(void)
void st_netfd_free(_st_netfd_t *fd)
{
if (!fd->inuse)
if (!fd->inuse) {
return;
}
fd->inuse = 0;
if (fd->aux_data)
if (fd->aux_data) {
_st_netfd_free_aux_data(fd);
if (fd->private_data && fd->destructor)
}
if (fd->private_data && fd->destructor) {
(*(fd->destructor))(fd->private_data);
}
fd->private_data = NULL;
fd->destructor = NULL;
fd->next = _st_netfd_freelist;
... ... @@ -126,17 +132,19 @@ static _st_netfd_t *_st_netfd_new(int osfd, int nonblock, int is_socket)
_st_netfd_t *fd;
int flags = 1;
if ((*_st_eventsys->fd_new)(osfd) < 0)
if ((*_st_eventsys->fd_new)(osfd) < 0) {
return NULL;
}
if (_st_netfd_freelist) {
fd = _st_netfd_freelist;
_st_netfd_freelist = _st_netfd_freelist->next;
} else {
fd = calloc(1, sizeof(_st_netfd_t));
if (!fd)
if (!fd) {
return NULL;
}
}
fd->osfd = osfd;
fd->inuse = 1;
... ... @@ -144,11 +152,11 @@ static _st_netfd_t *_st_netfd_new(int osfd, int nonblock, int is_socket)
if (nonblock) {
/* Use just one system call */
if (is_socket && ioctl(osfd, FIONBIO, &flags) != -1)
if (is_socket && ioctl(osfd, FIONBIO, &flags) != -1) {
return fd;
}
/* Do it the Posix way */
if ((flags = fcntl(osfd, F_GETFL, 0)) < 0 ||
fcntl(osfd, F_SETFL, flags | O_NONBLOCK) < 0) {
if ((flags = fcntl(osfd, F_GETFL, 0)) < 0 || fcntl(osfd, F_SETFL, flags | O_NONBLOCK) < 0) {
st_netfd_free(fd);
return NULL;
}
... ... @@ -172,8 +180,9 @@ _st_netfd_t *st_netfd_open_socket(int osfd)
int st_netfd_close(_st_netfd_t *fd)
{
if ((*_st_eventsys->fd_close)(fd->osfd) < 0)
if ((*_st_eventsys->fd_close)(fd->osfd) < 0) {
return -1;
}
st_netfd_free(fd);
return close(fd->osfd);
... ... @@ -186,14 +195,14 @@ int st_netfd_fileno(_st_netfd_t *fd)
}
void st_netfd_setspecific(_st_netfd_t *fd, void *value,
_st_destructor_t destructor)
void st_netfd_setspecific(_st_netfd_t *fd, void *value, _st_destructor_t destructor)
{
if (value != fd->private_data) {
/* Free up previously set non-NULL data value */
if (fd->private_data && fd->destructor)
if (fd->private_data && fd->destructor) {
(*(fd->destructor))(fd->private_data);
}
}
fd->private_data = value;
fd->destructor = destructor;
}
... ... @@ -217,8 +226,9 @@ int st_netfd_poll(_st_netfd_t *fd, int how, st_utime_t timeout)
pd.events = (short) how;
pd.revents = 0;
if ((n = st_poll(&pd, 1, timeout)) < 0)
if ((n = st_poll(&pd, 1, timeout)) < 0) {
return -1;
}
if (n == 0) {
/* Timed out */
errno = ETIME;
... ... @@ -232,7 +242,6 @@ int st_netfd_poll(_st_netfd_t *fd, int how, st_utime_t timeout)
return 0;
}
#ifdef MD_ALWAYS_UNSERIALIZED_ACCEPT
/* No-op */
int st_netfd_serialize_accept(_st_netfd_t *fd)
... ... @@ -247,21 +256,23 @@ static void _st_netfd_free_aux_data(_st_netfd_t *fd)
fd->aux_data = NULL;
}
_st_netfd_t *st_accept(_st_netfd_t *fd, struct sockaddr *addr, int *addrlen,
st_utime_t timeout)
_st_netfd_t *st_accept(_st_netfd_t *fd, struct sockaddr *addr, int *addrlen, st_utime_t timeout)
{
int osfd, err;
_st_netfd_t *newfd;
while ((osfd = accept(fd->osfd, addr, (socklen_t *)addrlen)) < 0) {
if (errno == EINTR)
if (errno == EINTR) {
continue;
if (!_IO_NOT_READY_ERROR)
}
if (!_IO_NOT_READY_ERROR) {
return NULL;
}
/* Wait until the socket becomes readable */
if (st_netfd_poll(fd, POLLIN, timeout) < 0)
if (st_netfd_poll(fd, POLLIN, timeout) < 0) {
return NULL;
}
}
/* On some platforms the new socket created by accept() inherits */
/* the nonblocking attribute of the listening socket */
... ... @@ -270,7 +281,7 @@ _st_netfd_t *st_accept(_st_netfd_t *fd, struct sockaddr *addr, int *addrlen,
#elif defined (MD_ACCEPT_NB_NOT_INHERITED)
newfd = _st_netfd_new(osfd, 1, 1);
#else
#error Unknown OS
#error Unknown OS
#endif
if (!newfd) {
... ... @@ -298,24 +309,25 @@ int st_netfd_serialize_accept(_st_netfd_t *fd)
errno = EINVAL;
return -1;
}
if ((p = (_st_netfd_t **)calloc(2, sizeof(_st_netfd_t *))) == NULL)
if ((p = (_st_netfd_t **)calloc(2, sizeof(_st_netfd_t *))) == NULL) {
return -1;
}
if (pipe(osfd) < 0) {
free(p);
return -1;
}
if ((p[0] = st_netfd_open(osfd[0])) != NULL &&
(p[1] = st_netfd_open(osfd[1])) != NULL &&
write(osfd[1], " ", 1) == 1) {
if ((p[0] = st_netfd_open(osfd[0])) != NULL && (p[1] = st_netfd_open(osfd[1])) != NULL && write(osfd[1], " ", 1) == 1) {
fd->aux_data = p;
return 0;
}
/* Error */
err = errno;
if (p[0])
if (p[0]) {
st_netfd_free(p[0]);
if (p[1])
}
if (p[1]) {
st_netfd_free(p[1]);
}
close(osfd[0]);
close(osfd[1]);
free(p);
... ... @@ -334,8 +346,7 @@ static void _st_netfd_free_aux_data(_st_netfd_t *fd)
fd->aux_data = NULL;
}
_st_netfd_t *st_accept(_st_netfd_t *fd, struct sockaddr *addr, int *addrlen,
st_utime_t timeout)
_st_netfd_t *st_accept(_st_netfd_t *fd, struct sockaddr *addr, int *addrlen, st_utime_t timeout)
{
int osfd, err;
_st_netfd_t *newfd;
... ... @@ -349,8 +360,9 @@ _st_netfd_t *st_accept(_st_netfd_t *fd, struct sockaddr *addr, int *addrlen,
} else {
/* Get the lock */
n = st_read(p[0], &c, 1, timeout);
if (n < 0)
if (n < 0) {
return NULL;
}
ST_ASSERT(n == 1);
/* Got the lock */
osfd = accept(fd->osfd, addr, (socklen_t *)addrlen);
... ... @@ -360,16 +372,20 @@ _st_netfd_t *st_accept(_st_netfd_t *fd, struct sockaddr *addr, int *addrlen,
ST_ASSERT(n == 1);
errno = err;
}
if (osfd >= 0)
if (osfd >= 0) {
break;
if (errno == EINTR)
}
if (errno == EINTR) {
continue;
if (!_IO_NOT_READY_ERROR)
}
if (!_IO_NOT_READY_ERROR) {
return NULL;
}
/* Wait until the socket becomes readable */
if (st_netfd_poll(fd, POLLIN, timeout) < 0)
if (st_netfd_poll(fd, POLLIN, timeout) < 0) {
return NULL;
}
}
/* On some platforms the new socket created by accept() inherits */
/* the nonblocking attribute of the listening socket */
... ... @@ -378,7 +394,7 @@ _st_netfd_t *st_accept(_st_netfd_t *fd, struct sockaddr *addr, int *addrlen,
#elif defined (MD_ACCEPT_NB_NOT_INHERITED)
newfd = _st_netfd_new(osfd, 1, 1);
#else
#error Unknown OS
#error Unknown OS
#endif
if (!newfd) {
... ... @@ -392,8 +408,7 @@ _st_netfd_t *st_accept(_st_netfd_t *fd, struct sockaddr *addr, int *addrlen,
#endif /* MD_ALWAYS_UNSERIALIZED_ACCEPT */
int st_connect(_st_netfd_t *fd, const struct sockaddr *addr, int addrlen,
st_utime_t timeout)
int st_connect(_st_netfd_t *fd, const struct sockaddr *addr, int addrlen, st_utime_t timeout)
{
int n, err = 0;
... ... @@ -407,16 +422,18 @@ int st_connect(_st_netfd_t *fd, const struct sockaddr *addr, int addrlen,
* "UNIX Network Programming," Vol. 1, 2nd edition, p. 413
* ("Interrupted connect").
*/
if (errno != EINPROGRESS && (errno != EADDRINUSE || err == 0))
if (errno != EINPROGRESS && (errno != EADDRINUSE || err == 0)) {
return -1;
}
/* Wait until the socket becomes writable */
if (st_netfd_poll(fd, POLLOUT, timeout) < 0)
if (st_netfd_poll(fd, POLLOUT, timeout) < 0) {
return -1;
}
/* Try to find out whether the connection setup succeeded or failed */
n = sizeof(int);
if (getsockopt(fd->osfd, SOL_SOCKET, SO_ERROR, (char *)&err,
(socklen_t *)&n) < 0)
if (getsockopt(fd->osfd, SOL_SOCKET, SO_ERROR, (char *)&err, (socklen_t *)&n) < 0) {
return -1;
}
if (err) {
errno = err;
return -1;
... ... @@ -435,21 +452,23 @@ ssize_t st_read(_st_netfd_t *fd, void *buf, size_t nbyte, st_utime_t timeout)
ssize_t n;
while ((n = read(fd->osfd, buf, nbyte)) < 0) {
if (errno == EINTR)
if (errno == EINTR) {
continue;
if (!_IO_NOT_READY_ERROR)
}
if (!_IO_NOT_READY_ERROR) {
return -1;
}
/* Wait until the socket becomes readable */
if (st_netfd_poll(fd, POLLIN, timeout) < 0)
if (st_netfd_poll(fd, POLLIN, timeout) < 0) {
return -1;
}
}
return n;
}
int st_read_resid(_st_netfd_t *fd, void *buf, size_t *resid,
st_utime_t timeout)
int st_read_resid(_st_netfd_t *fd, void *buf, size_t *resid, st_utime_t timeout)
{
struct iovec iov, *riov;
int riov_size, rv;
... ... @@ -464,76 +483,78 @@ int st_read_resid(_st_netfd_t *fd, void *buf, size_t *resid,
}
ssize_t st_readv(_st_netfd_t *fd, const struct iovec *iov, int iov_size,
st_utime_t timeout)
ssize_t st_readv(_st_netfd_t *fd, const struct iovec *iov, int iov_size, st_utime_t timeout)
{
ssize_t n;
while ((n = readv(fd->osfd, iov, iov_size)) < 0) {
if (errno == EINTR)
if (errno == EINTR) {
continue;
if (!_IO_NOT_READY_ERROR)
}
if (!_IO_NOT_READY_ERROR) {
return -1;
}
/* Wait until the socket becomes readable */
if (st_netfd_poll(fd, POLLIN, timeout) < 0)
if (st_netfd_poll(fd, POLLIN, timeout) < 0) {
return -1;
}
}
return n;
}
int st_readv_resid(_st_netfd_t *fd, struct iovec **iov, int *iov_size,
st_utime_t timeout)
int st_readv_resid(_st_netfd_t *fd, struct iovec **iov, int *iov_size, st_utime_t timeout)
{
ssize_t n;
while (*iov_size > 0) {
if (*iov_size == 1)
if (*iov_size == 1) {
n = read(fd->osfd, (*iov)->iov_base, (*iov)->iov_len);
else
} else {
n = readv(fd->osfd, *iov, *iov_size);
}
if (n < 0) {
if (errno == EINTR)
if (errno == EINTR) {
continue;
if (!_IO_NOT_READY_ERROR)
}
if (!_IO_NOT_READY_ERROR) {
return -1;
} else if (n == 0)
}
} else if (n == 0) {
break;
else {
} else {
while ((size_t) n >= (*iov)->iov_len) {
n -= (*iov)->iov_len;
(*iov)->iov_base = (char *) (*iov)->iov_base + (*iov)->iov_len;
(*iov)->iov_len = 0;
(*iov)++;
(*iov_size)--;
if (n == 0)
if (n == 0) {
break;
}
if (*iov_size == 0)
}
if (*iov_size == 0) {
break;
}
(*iov)->iov_base = (char *) (*iov)->iov_base + n;
(*iov)->iov_len -= n;
}
/* Wait until the socket becomes readable */
if (st_netfd_poll(fd, POLLIN, timeout) < 0)
if (st_netfd_poll(fd, POLLIN, timeout) < 0) {
return -1;
}
}
return 0;
}
ssize_t st_read_fully(_st_netfd_t *fd, void *buf, size_t nbyte,
st_utime_t timeout)
ssize_t st_read_fully(_st_netfd_t *fd, void *buf, size_t nbyte, st_utime_t timeout)
{
size_t resid = nbyte;
return st_read_resid(fd, buf, &resid, timeout) == 0 ?
(ssize_t) (nbyte - resid) : -1;
return st_read_resid(fd, buf, &resid, timeout) == 0 ? (ssize_t) (nbyte - resid) : -1;
}
int st_write_resid(_st_netfd_t *fd, const void *buf, size_t *resid,
st_utime_t timeout)
int st_write_resid(_st_netfd_t *fd, const void *buf, size_t *resid, st_utime_t timeout)
{
struct iovec iov, *riov;
int riov_size, rv;
... ... @@ -547,18 +568,13 @@ int st_write_resid(_st_netfd_t *fd, const void *buf, size_t *resid,
return rv;
}
ssize_t st_write(_st_netfd_t *fd, const void *buf, size_t nbyte,
st_utime_t timeout)
ssize_t st_write(_st_netfd_t *fd, const void *buf, size_t nbyte, st_utime_t timeout)
{
size_t resid = nbyte;
return st_write_resid(fd, buf, &resid, timeout) == 0 ?
(ssize_t) (nbyte - resid) : -1;
return st_write_resid(fd, buf, &resid, timeout) == 0 ? (ssize_t) (nbyte - resid) : -1;
}
ssize_t st_writev(_st_netfd_t *fd, const struct iovec *iov, int iov_size,
st_utime_t timeout)
ssize_t st_writev(_st_netfd_t *fd, const struct iovec *iov, int iov_size, st_utime_t timeout)
{
ssize_t n, rv;
size_t nleft, nbyte;
... ... @@ -568,8 +584,9 @@ ssize_t st_writev(_st_netfd_t *fd, const struct iovec *iov, int iov_size,
/* Calculate the total number of bytes to be sent */
nbyte = 0;
for (index = 0; index < iov_size; index++)
for (index = 0; index < iov_size; index++) {
nbyte += iov[index].iov_len;
}
rv = (ssize_t)nbyte;
nleft = nbyte;
... ... @@ -578,25 +595,29 @@ ssize_t st_writev(_st_netfd_t *fd, const struct iovec *iov, int iov_size,
while (nleft > 0) {
if (iov_cnt == 1) {
if (st_write(fd, tmp_iov[0].iov_base, nleft, timeout) != (ssize_t) nleft)
if (st_write(fd, tmp_iov[0].iov_base, nleft, timeout) != (ssize_t) nleft) {
rv = -1;
}
break;
}
if ((n = writev(fd->osfd, tmp_iov, iov_cnt)) < 0) {
if (errno == EINTR)
if (errno == EINTR) {
continue;
}
if (!_IO_NOT_READY_ERROR) {
rv = -1;
break;
}
} else {
if ((size_t) n == nleft)
if ((size_t) n == nleft) {
break;
}
nleft -= n;
/* Find the next unwritten vector */
n = (ssize_t)(nbyte - nleft);
for (index = 0; (size_t) n >= iov[index].iov_len; index++)
for (index = 0; (size_t) n >= iov[index].iov_len; index++) {
n -= iov[index].iov_len;
}
if (tmp_iov == iov) {
/* Must copy iov's around */
... ... @@ -604,10 +625,11 @@ ssize_t st_writev(_st_netfd_t *fd, const struct iovec *iov, int iov_size,
tmp_iov = local_iov;
} else {
tmp_iov = calloc(1, (iov_size - index) * sizeof(struct iovec));
if (tmp_iov == NULL)
if (tmp_iov == NULL) {
return -1;
}
}
}
/* Fill in the first partial read */
tmp_iov[0].iov_base = &(((char *)iov[index].iov_base)[n]);
... ... @@ -626,28 +648,30 @@ ssize_t st_writev(_st_netfd_t *fd, const struct iovec *iov, int iov_size,
}
}
if (tmp_iov != iov && tmp_iov != local_iov)
if (tmp_iov != iov && tmp_iov != local_iov) {
free(tmp_iov);
}
return rv;
}
int st_writev_resid(_st_netfd_t *fd, struct iovec **iov, int *iov_size,
st_utime_t timeout)
int st_writev_resid(_st_netfd_t *fd, struct iovec **iov, int *iov_size, st_utime_t timeout)
{
ssize_t n;
while (*iov_size > 0) {
if (*iov_size == 1)
if (*iov_size == 1) {
n = write(fd->osfd, (*iov)->iov_base, (*iov)->iov_len);
else
} else {
n = writev(fd->osfd, *iov, *iov_size);
}
if (n < 0) {
if (errno == EINTR)
if (errno == EINTR) {
continue;
if (!_IO_NOT_READY_ERROR)
}
if (!_IO_NOT_READY_ERROR) {
return -1;
}
} else {
while ((size_t) n >= (*iov)->iov_len) {
n -= (*iov)->iov_len;
... ... @@ -655,104 +679,109 @@ int st_writev_resid(_st_netfd_t *fd, struct iovec **iov, int *iov_size,
(*iov)->iov_len = 0;
(*iov)++;
(*iov_size)--;
if (n == 0)
if (n == 0) {
break;
}
if (*iov_size == 0)
}
if (*iov_size == 0) {
break;
}
(*iov)->iov_base = (char *) (*iov)->iov_base + n;
(*iov)->iov_len -= n;
}
/* Wait until the socket becomes writable */
if (st_netfd_poll(fd, POLLOUT, timeout) < 0)
if (st_netfd_poll(fd, POLLOUT, timeout) < 0) {
return -1;
}
}
return 0;
}
/*
* Simple I/O functions for UDP.
*/
int st_recvfrom(_st_netfd_t *fd, void *buf, int len, struct sockaddr *from,
int *fromlen, st_utime_t timeout)
int st_recvfrom(_st_netfd_t *fd, void *buf, int len, struct sockaddr *from, int *fromlen, st_utime_t timeout)
{
int n;
while ((n = recvfrom(fd->osfd, buf, len, 0, from, (socklen_t *)fromlen))
< 0) {
if (errno == EINTR)
while ((n = recvfrom(fd->osfd, buf, len, 0, from, (socklen_t *)fromlen)) < 0) {
if (errno == EINTR) {
continue;
if (!_IO_NOT_READY_ERROR)
}
if (!_IO_NOT_READY_ERROR) {
return -1;
}
/* Wait until the socket becomes readable */
if (st_netfd_poll(fd, POLLIN, timeout) < 0)
if (st_netfd_poll(fd, POLLIN, timeout) < 0) {
return -1;
}
}
return n;
}
int st_sendto(_st_netfd_t *fd, const void *msg, int len,
const struct sockaddr *to, int tolen, st_utime_t timeout)
int st_sendto(_st_netfd_t *fd, const void *msg, int len, const struct sockaddr *to, int tolen, st_utime_t timeout)
{
int n;
while ((n = sendto(fd->osfd, msg, len, 0, to, tolen)) < 0) {
if (errno == EINTR)
if (errno == EINTR) {
continue;
if (!_IO_NOT_READY_ERROR)
}
if (!_IO_NOT_READY_ERROR) {
return -1;
}
/* Wait until the socket becomes writable */
if (st_netfd_poll(fd, POLLOUT, timeout) < 0)
if (st_netfd_poll(fd, POLLOUT, timeout) < 0) {
return -1;
}
}
return n;
}
int st_recvmsg(_st_netfd_t *fd, struct msghdr *msg, int flags,
st_utime_t timeout)
int st_recvmsg(_st_netfd_t *fd, struct msghdr *msg, int flags, st_utime_t timeout)
{
int n;
while ((n = recvmsg(fd->osfd, msg, flags)) < 0) {
if (errno == EINTR)
if (errno == EINTR) {
continue;
if (!_IO_NOT_READY_ERROR)
}
if (!_IO_NOT_READY_ERROR) {
return -1;
}
/* Wait until the socket becomes readable */
if (st_netfd_poll(fd, POLLIN, timeout) < 0)
if (st_netfd_poll(fd, POLLIN, timeout) < 0) {
return -1;
}
}
return n;
}
int st_sendmsg(_st_netfd_t *fd, const struct msghdr *msg, int flags,
st_utime_t timeout)
int st_sendmsg(_st_netfd_t *fd, const struct msghdr *msg, int flags, st_utime_t timeout)
{
int n;
while ((n = sendmsg(fd->osfd, msg, flags)) < 0) {
if (errno == EINTR)
if (errno == EINTR) {
continue;
if (!_IO_NOT_READY_ERROR)
}
if (!_IO_NOT_READY_ERROR) {
return -1;
}
/* Wait until the socket becomes writable */
if (st_netfd_poll(fd, POLLOUT, timeout) < 0)
if (st_netfd_poll(fd, POLLOUT, timeout) < 0) {
return -1;
}
}
return n;
}
/*
* To open FIFOs or other special files.
*/
... ... @@ -762,9 +791,10 @@ _st_netfd_t *st_open(const char *path, int oflags, mode_t mode)
_st_netfd_t *newfd;
while ((osfd = open(path, oflags | O_NONBLOCK, mode)) < 0) {
if (errno != EINTR)
if (errno != EINTR) {
return NULL;
}
}
newfd = _st_netfd_new(osfd, 0, 0);
if (!newfd) {
... ...
... ... @@ -97,8 +97,9 @@ int st_thread_setspecific(int key, void *value)
void *st_thread_getspecific(int key)
{
if (key < 0 || key >= key_max)
if (key < 0 || key >= key_max) {
return NULL;
}
return ((_ST_CURRENT_THREAD())->private_data[key]);
}
... ...