rbb 99/11/15 11:50:48
Modified: src/lib/apr/network_io/unix sendrecv.c sockopt.c
src/modules/mpm/dexter dexter.c
src/modules/mpm/mpmt_pthread mpmt_pthread.c
src/modules/mpm/prefork prefork.c
src/os/unix iol_socket.c iol_socket.h
Log:
Moving Unix socket IOL's to use APR. Also fixed a small bug in ap_recv.
We should NEVER return a status of APR_EAGAIN and say -1 bytes read. This
can cause some strange bugs.
Revision Changes Path
1.5 +4 -0 apache-2.0/src/lib/apr/network_io/unix/sendrecv.c
Index: sendrecv.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/unix/sendrecv.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- sendrecv.c 1999/11/10 15:49:55 1.4
+++ sendrecv.c 1999/11/15 19:49:51 1.5
@@ -169,6 +169,10 @@
} while (rv == -1 && errno == EINTR);
}
}
+ else if (rv == -1 && errno == EAGAIN && sock->timeout == 0) {
+ (*len) = 0;
+ return errno;
+ }
(*len) = rv;
return APR_SUCCESS;
}
1.13 +3 -0 apache-2.0/src/lib/apr/network_io/unix/sockopt.c
Index: sockopt.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/unix/sockopt.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- sockopt.c 1999/11/10 15:49:55 1.12
+++ sockopt.c 1999/11/15 19:49:54 1.13
@@ -176,6 +176,9 @@
}
if (opt & APR_SO_TIMEOUT) {
sock->timeout = on;
+ if ((stat = sononblock(sock->socketdes)) != APR_SUCCESS) {
+ return stat;
+ }
}
return APR_SUCCESS;
}
1.52 +1 -1 apache-2.0/src/modules/mpm/dexter/dexter.c
Index: dexter.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/modules/mpm/dexter/dexter.c,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -r1.51 -r1.52
--- dexter.c 1999/10/30 01:49:53 1.51
+++ dexter.c 1999/11/15 19:50:05 1.52
@@ -750,7 +750,7 @@
}
sock_disable_nagle(csd);
- iol = unix_attach_socket(csd);
+ iol = unix_attach_socket(sock);
if (iol == NULL) {
if (errno == EBADF) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, errno,
NULL,
1.44 +1 -1 apache-2.0/src/modules/mpm/mpmt_pthread/mpmt_pthread.c
Index: mpmt_pthread.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/modules/mpm/mpmt_pthread/mpmt_pthread.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- mpmt_pthread.c 1999/11/11 22:57:19 1.43
+++ mpmt_pthread.c 1999/11/15 19:50:11 1.44
@@ -737,7 +737,7 @@
sock_disable_nagle(csd);
- iol = unix_attach_socket(csd);
+ iol = unix_attach_socket(sock);
if (iol == NULL) {
if (errno == EBADF) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, NULL,
1.51 +1 -1 apache-2.0/src/modules/mpm/prefork/prefork.c
Index: prefork.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/modules/mpm/prefork/prefork.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -r1.50 -r1.51
--- prefork.c 1999/11/09 09:33:52 1.50
+++ prefork.c 1999/11/15 19:50:25 1.51
@@ -2218,7 +2218,7 @@
sock_disable_nagle(sockdes);
- iol = unix_attach_socket(sockdes);
+ iol = unix_attach_socket(csd);
if (iol == NULL) {
if (errno == EBADF) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, NULL,
1.11 +31 -131 apache-2.0/src/os/unix/iol_socket.c
Index: iol_socket.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/os/unix/iol_socket.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- iol_socket.c 1999/10/30 00:25:31 1.10
+++ iol_socket.c 1999/11/15 19:50:31 1.11
@@ -58,19 +58,15 @@
#include "httpd.h"
#include "ap_iol.h"
+#include "apr_network_io.h"
+#include "apr_file_io.h"
#include "iol_socket.h"
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-
#define FD_NONBLOCKING_SET (1)
typedef struct {
ap_iol iol;
- int fd;
- int flags;
- int timeout;
+ ap_socket_t *sock;
} iol_socket;
static ap_status_t unix_setopt(ap_iol *viol, ap_iol_option opt,
@@ -80,10 +76,10 @@
switch (opt) {
case AP_IOL_TIMEOUT:
- iol->timeout = *(const int *)value;
- break;
+ ap_setsocketopt(iol->sock, APR_SO_TIMEOUT, *(const int*)value);
+ break;
default:
- return APR_EINVAL;
+ return APR_EINVAL;
}
return APR_SUCCESS;
}
@@ -94,138 +90,48 @@
switch (opt) {
case AP_IOL_TIMEOUT:
- *(int *)value = iol->timeout;
- break;
+ /* no-op */
+ break;
default:
- return APR_EINVAL;
+ return APR_EINVAL;
}
return APR_SUCCESS;
}
-static ap_status_t set_nonblock(int fd)
-{
- int fd_flags;
- int rv;
- fd_flags = fcntl(fd, F_GETFL, 0);
-#if defined(O_NONBLOCK)
- fd_flags |= O_NONBLOCK;
- rv = fcntl(fd, F_SETFL, fd_flags);
-#elif defined(O_NDELAY)
- fd_flags |= O_NDELAY;
- rv = fcntl(fd, F_SETFL, fd_flags);
-#elif defined(FNDELAY)
- fd_flags |= O_FNDELAY;
- rv = fcntl(fd, F_SETFL, fd_flags);
-#else
-#error "your unix lacks non-blocking i/o, you lose"
-#endif
- if (rv == 0) {
- return APR_SUCCESS;
- }
- return errno;
+ap_status_t unix_write(ap_iol *viol, const char* buf, ap_size_t size,
+ ap_ssize_t *nbytes)
+{
+ *nbytes = size;
+ return ap_send(((iol_socket *)viol)->sock, buf, nbytes);
}
-/* the timeout code is a separate routine because it requires
- a stack frame... and we don't want to pay that setup cost
- on every call */
-
-/* this macro expands into the four basic i/o methods */
-
-#define method(name, args, syscall, selread, selwrite) \
- static ap_status_t unix_##name##_timeout args \
- { \
- iol_socket *iol = (iol_socket *)viol; \
- fd_set fdset; \
- struct timeval tv; \
- int rv; \
- \
- FD_ZERO(&fdset); \
- FD_SET(iol->fd, &fdset); \
- tv.tv_sec = iol->timeout; \
- tv.tv_usec = 0; \
- do { \
- rv = select(iol->fd + 1, selread, selwrite, NULL, iol->timeout < 0
? NULL : &tv); \
- } while (rv == -1 && errno == EINTR); \
- if (!FD_ISSET(iol->fd, &fdset)) { \
- *nbytes = 0; \
- return APR_ETIMEDOUT; \
- } \
- do { \
- rv = syscall(iol->fd, arg1, arg2); \
- } while (rv == -1 && errno == EINTR); \
- if (rv >= 0) { \
- *nbytes = rv; \
- return APR_SUCCESS; \
- } \
- *nbytes = 0; \
- return errno; \
- \
- } \
- \
- static ap_status_t unix_##name args \
- { \
- iol_socket *iol = (iol_socket *)viol; \
- int rv; \
- \
- /* Preset to zero until some bytes are actually written */ \
- *nbytes = 0; \
- if (!(iol->flags & FD_NONBLOCKING_SET)) { \
- if (iol->timeout < 0) { \
- rv = syscall(iol->fd, arg1, arg2); \
- if (rv >= 0) { \
- *nbytes = rv; \
- return APR_SUCCESS; \
- } \
- return errno; \
- } \
- /* must shift descriptor to blocking mode now */ \
- if ((rv = set_nonblock(iol->fd)) != APR_SUCCESS) { \
- return rv; \
- } \
- iol->flags |= FD_NONBLOCKING_SET; \
- } \
- \
- /* try writing, ignoring EINTR, the upper layer has to handle \
- partial read/writes anyhow, so we can return early */ \
- do { \
- rv = syscall(iol->fd, arg1, arg2); \
- } while (rv == -1 && errno == EINTR); \
- if (rv >= 0) { \
- *nbytes = rv; \
- return APR_SUCCESS; \
- } \
- if ((errno == EWOULDBLOCK || errno == EAGAIN) && iol->timeout != 0) { \
- return unix_##name##_timeout(viol, arg1, arg2, nbytes); \
- } \
- return errno; \
- }
+ap_status_t unix_writev(ap_iol *viol, const struct iovec *vec, int nvec,
+ ap_ssize_t *nbytes)
+{
+ *nbytes = vec[0].iov_len;
+ return ap_send(((iol_socket *)viol)->sock, vec[0].iov_base, nbytes);
+}
-method(write, (ap_iol *viol, const char *arg1, ap_size_t arg2, ap_ssize_t
*nbytes), write, NULL, &fdset)
-method(writev, (ap_iol *viol, const struct iovec *arg1, int arg2, ap_ssize_t
*nbytes), writev, NULL, &fdset)
-method(read, (ap_iol *viol, char *arg1, ap_size_t arg2, ap_ssize_t *nbytes),
read, &fdset, NULL)
+ap_status_t unix_read(ap_iol *viol, char* buf, ap_size_t size,
+ ap_ssize_t *nbytes)
+{
+ *nbytes = size;
+ return ap_recv(((iol_socket *)viol)->sock, buf, nbytes);
+}
static ap_status_t unix_close(ap_iol *viol)
{
-
-/* XXX: This is a *temporary* ultra-hack solution to the double-close
problem.
- * APR and buff were both trying to close this socket */
-
- return APR_SUCCESS;
-
-#if 0
iol_socket *iol = (iol_socket *)viol;
- int rv;
int saved_errno;
- rv = close(iol->fd);
- saved_errno = errno;
+ saved_errno = ap_close_socket(iol->sock);
free(iol);
- if (rv == 0) {
+ iol = NULL;
+ if (saved_errno == 0) {
return APR_SUCCESS;
}
return saved_errno;
-#endif
}
static const ap_iol_methods socket_methods = {
@@ -237,18 +143,12 @@
unix_getopt
};
-ap_iol *unix_attach_socket(int fd)
+ap_iol *unix_attach_socket(ap_socket_t *sock)
{
iol_socket *iol;
- if (fd >= FD_SETSIZE) {
- errno = EBADF;
- return NULL;
- }
iol = malloc(sizeof(iol_socket));
iol->iol.methods = &socket_methods;
- iol->fd = fd;
- iol->timeout = -1;
- iol->flags = 0;
+ iol->sock = sock;
return (ap_iol *)iol;
}
1.2 +1 -1 apache-2.0/src/os/unix/iol_socket.h
Index: iol_socket.h
===================================================================
RCS file: /home/cvs/apache-2.0/src/os/unix/iol_socket.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- iol_socket.h 1999/06/24 08:58:04 1.1
+++ iol_socket.h 1999/11/15 19:50:31 1.2
@@ -58,6 +58,6 @@
#ifndef OS_UNIX_IOL_SOCKET_H
#define OS_UNIX_IOL_SOCKET_H
-ap_iol *unix_attach_socket(int fd);
+ap_iol *unix_attach_socket(ap_socket_t *sock);
#endif