cvs commit: apache-2.0/mpm/src/os/unix iol_socket.c
rse 99/08/13 08:52:03 Modified:mpm/src/os/unix iol_socket.c Log: Hell, what a subtle problem which caused me four hours this afternoon to find. It's not exactly specified (even POSIX does it once this time and once this time) whether read() returns EWOULDBLOCK or EAGAIN. SysV usually returns EAGAIN, BSD usually EWOULDBLOCK. So we have to check for _both_ errno values, of course. This occured for me the first time after I've tried ``ab -n 1000 en1:8080/index.txt'' where index.txt is a very large file (3MB). Then the sockets block often even for write operations and then the return value was not recognized correctly... :-( Revision ChangesPath 1.3 +1 -1 apache-2.0/mpm/src/os/unix/iol_socket.c Index: iol_socket.c === RCS file: /home/cvs/apache-2.0/mpm/src/os/unix/iol_socket.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- iol_socket.c 1999/06/28 19:00:50 1.2 +++ iol_socket.c 1999/08/13 15:52:01 1.3 @@ -176,7 +176,7 @@ if (rv = 0) { \ return rv; \ } \ - if (errno == EWOULDBLOCK iol-timeout != 0) { \ + if ((errno == EWOULDBLOCK || errno == EAGAIN) iol-timeout != 0) { \ return unix_##name##_timeout(viol, arg1, arg2); \ } \ return -1; \
cvs commit: apache-2.0/mpm/src/os/unix iol_socket.c
dgaudet 99/06/28 12:00:50 Modified:mpm/src/include ap_iol.h mpm/src/main iol_file.c mpm/src/os/unix iol_socket.c Log: - eliminate readv -- it's mostly useful with a full zero-copy setup - document the simple writev possible when system has no writev Revision ChangesPath 1.4 +8 -4 apache-2.0/mpm/src/include/ap_iol.h Index: ap_iol.h === RCS file: /home/cvs/apache-2.0/mpm/src/include/ap_iol.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- ap_iol.h 1999/06/24 08:57:58 1.3 +++ ap_iol.h 1999/06/28 19:00:48 1.4 @@ -68,7 +68,7 @@ } ap_iol_option; /* -write, writev, read, readv guarantee they won't return EINTR. +write, writev, read guarantee they won't return EINTR. If no error occurs, they return the number of bytes read/written. @@ -88,12 +88,18 @@ Just to drive the point home again -- none of these functions guarantee they will read/write the entire length specified. -Note: timeout == 0 is non-blocking operation... which requires a lot +Note: timeout == 0 is non-blocking operation... which requires a lot of care if you're implementing filters. It may mean you have to keep state from one call to the next. The chunking filter will have an example of this. If you're not sure how to handle the state sitatuation you will want to return EINVAL when the timeout is set to 0. This may break various things... hopefully we'll be able to recover gracefully. + +Note: implementation tip: if your system doesn't have writev(), you +still have to implement a writev() method. However, since the +iol writev() is allowed to return a partial write, you can essentially +treat all writev()s as write(fd, vec[0].iov_base, vec[0].iov_len), +and the layers above will loop over the entire vector for you. */ struct ap_iol_methods { @@ -101,7 +107,6 @@ int (*write)(ap_iol *fd, const char *buf, int len); int (*writev)(ap_iol *fd, const struct iovec *vec, int nvec); int (*read)(ap_iol *fd, char *buf, int len); -int (*readv)(ap_iol *fd, struct iovec *vec, int nvec); int (*setopt)(ap_iol *fd, ap_iol_option opt, const void *value); int (*getopt)(ap_iol *fd, ap_iol_option opt, void *value); /* TODO: accept, connect, ... */ @@ -118,7 +123,6 @@ #define iol_write(iol, a, b) ((iol)-methods-write((iol), (a), (b))) #define iol_writev(iol, a, b) ((iol)-methods-writev((iol), (a), (b))) #define iol_read(iol, a, b) ((iol)-methods-read((iol), (a), (b))) -#define iol_readv(iol, a, b) ((iol)-methods-readv((iol), (a), (b))) #define iol_setopt(iol, a, b) ((iol)-methods-setopt((iol), (a), (b))) #define iol_getopt(iol, a, b) ((iol)-methods-getopt((iol), (a), (b))) 1.2 +0 -2 apache-2.0/mpm/src/main/iol_file.c Index: iol_file.c === RCS file: /home/cvs/apache-2.0/mpm/src/main/iol_file.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- iol_file.c1999/06/24 08:58:00 1.1 +++ iol_file.c1999/06/28 19:00:49 1.2 @@ -81,7 +81,6 @@ method(write, (ap_iol *viol, const char *arg1, int arg2)) method(writev, (ap_iol *viol, const struct iovec *arg1, int arg2)) method(read, (ap_iol *viol, char *arg1, int arg2)) -method(readv, (ap_iol *viol, struct iovec *arg1, int arg2)) static int file_close(ap_iol *viol) { @@ -113,7 +112,6 @@ file_write, file_writev, file_read, -file_readv, file_setopt, file_getopt }; 1.2 +0 -2 apache-2.0/mpm/src/os/unix/iol_socket.c Index: iol_socket.c === RCS file: /home/cvs/apache-2.0/mpm/src/os/unix/iol_socket.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- iol_socket.c 1999/06/24 08:58:04 1.1 +++ iol_socket.c 1999/06/28 19:00:50 1.2 @@ -185,7 +185,6 @@ method(write, (ap_iol *viol, const char *arg1, int arg2), write, NULL, fdset) method(writev, (ap_iol *viol, const struct iovec *arg1, int arg2), writev, NULL, fdset) method(read, (ap_iol *viol, char *arg1, int arg2), read, fdset, NULL) -method(readv, (ap_iol *viol, struct iovec *arg1, int arg2), readv, fdset, NULL) static int unix_close(ap_iol *viol) { @@ -205,7 +204,6 @@ unix_write, unix_writev, unix_read, -unix_readv, unix_setopt, unix_getopt };
cvs commit: apache-2.0/mpm/src/os/unix iol_socket.c iol_socket.h Makefile.tmpl
dgaudet 99/06/24 01:58:06 Modified:mpm/src/include ap_iol.h buff.h mpm/src/main Makefile.tmpl alloc.c buff.c mpm/src/modules/mpm/prefork prefork.c mpm/src/os/unix Makefile.tmpl Added: mpm/src/main iol_file.c mpm/src/os/unix iol_socket.c iol_socket.h Removed: mpm/src/main iol_unix.c Log: I think this is a better i/o layer interface. - move main/iol_unix.c to os/unix/iol_socket.c - create main/iol_file.c ... use APR methods eventually - remove iol_data from ap_iol, instead the ap_iol is just embedded into the private data of the i/o layer - remove ap_bpushfd(), replace with ap_bpush_iol() Revision ChangesPath 1.3 +6 -4 apache-2.0/mpm/src/include/ap_iol.h Index: ap_iol.h === RCS file: /home/cvs/apache-2.0/mpm/src/include/ap_iol.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ap_iol.h 1999/06/19 20:40:16 1.2 +++ ap_iol.h 1999/06/24 08:57:58 1.3 @@ -107,8 +107,10 @@ /* TODO: accept, connect, ... */ }; +/* it is expected that each io layer will extend this structure as they +require; they must only ensure that the methods pointer remains in +the indicated position. */ struct ap_iol { -void *iol_data; const ap_iol_methods *methods; }; @@ -120,8 +122,8 @@ #define iol_setopt(iol, a, b) ((iol)-methods-setopt((iol), (a), (b))) #define iol_getopt(iol, a, b) ((iol)-methods-getopt((iol), (a), (b))) -/* clean this up later as well */ - -void unix_attach_fd(ap_iol *, int fd); +/* the file iol */ +/* TODO: use APR instead of unix semantics for this */ +ap_iol *ap_open_file(const char *name, int flags, int mask); #endif 1.5 +3 -2 apache-2.0/mpm/src/include/buff.h Index: buff.h === RCS file: /home/cvs/apache-2.0/mpm/src/include/buff.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- buff.h1999/06/24 07:29:29 1.4 +++ buff.h1999/06/24 08:57:58 1.5 @@ -145,7 +145,7 @@ ap_pool *pool; -ap_iol iol; +ap_iol *iol; }; /* Options to bset/getopt */ @@ -155,7 +155,8 @@ /* Stream creation and modification */ API_EXPORT(BUFF *) ap_bcreate(pool *p, int flags); -API_EXPORT(void) ap_bpushfd(BUFF *fb, int fd); + +API_EXPORT(void) ap_bpush_iol(BUFF *fb, ap_iol *iol); /* XXX - unused right now - mvsk */ API_EXPORT(BUFF *) ap_bopenf(pool *a, const char *name, int flg, int mode); 1.6 +1 -1 apache-2.0/mpm/src/main/Makefile.tmpl Index: Makefile.tmpl === RCS file: /home/cvs/apache-2.0/mpm/src/main/Makefile.tmpl,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- Makefile.tmpl 1999/06/20 23:49:32 1.5 +++ Makefile.tmpl 1999/06/24 08:58:00 1.6 @@ -11,7 +11,7 @@ http_config.o http_core.o http_log.o \ http_main.o http_protocol.o http_request.o http_vhost.o \ util.o util_date.o util_script.o util_uri.o util_md5.o \ - rfc1413.o http_connection.o iol_unix.o + rfc1413.o http_connection.o iol_file.o .c.o: $(CC) -c $(INCLUDES) $(CFLAGS) $ 1.5 +4 -0 apache-2.0/mpm/src/main/alloc.c Index: alloc.c === RCS file: /home/cvs/apache-2.0/mpm/src/main/alloc.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- alloc.c 1999/06/22 22:26:10 1.4 +++ alloc.c 1999/06/24 08:58:00 1.5 @@ -2370,6 +2370,9 @@ enum kill_conditions kill_how, BUFF **pipe_in, BUFF **pipe_out, BUFF **pipe_err) { +return 0; +/* TODO: need to abstract the spawning stuff in a more clean manner */ +#if 0 #ifdef WIN32 SECURITY_ATTRIBUTES sa = {0}; HANDLE hPipeOutputRead = NULL; @@ -2588,6 +2591,7 @@ #endif return pid; +#endif } static void free_proc_chain(struct process_chain *procs) 1.6 +13 -14apache-2.0/mpm/src/main/buff.c Index: buff.c === RCS file: /home/cvs/apache-2.0/mpm/src/main/buff.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- buff.c1999/06/24 07:29:31 1.5 +++ buff.c1999/06/24 08:58:00 1.6 @@ -177,17 +177,16 @@ { BUFF *fb = v; -iol_close(fb-iol); +iol_close(fb-iol); } /* * Push some I/O file descriptors onto the stream */ -API_EXPORT(void) ap_bpushfd(BUFF *fb, APRFile fd) +API_EXPORT(void)