Return-Path: Delivered-To: apache-cvs-archive@hyperreal.org Received: (qmail 13512 invoked by uid 6000); 6 Nov 1997 10:47:05 -0000 Received: (qmail 13505 invoked by uid 143); 6 Nov 1997 10:47:03 -0000 Date: 6 Nov 1997 10:47:03 -0000 Message-ID: <19971106104703.13504.qmail@hyperreal.org> From: dgaudet@hyperreal.org To: apache-cvs@hyperreal.org Subject: cvs commit: apachen/src/main conf.h http_main.c Sender: apache-cvs-owner@apache.org Precedence: bulk Reply-To: new-httpd@apache.org dgaudet 97/11/06 02:47:03 Modified: src CHANGES src/main conf.h http_main.c Log: Papa Roy said I could commit this. Fix USE_PTHREAD_SERIALIZED_ACCEPT, I totally didn't do it right the first time. Reviewed by: Roy Fielding Revision Changes Path 1.488 +3 -6 apachen/src/CHANGES Index: CHANGES =================================================================== RCS file: /export/home/cvs/apachen/src/CHANGES,v retrieving revision 1.487 retrieving revision 1.488 diff -u -r1.487 -r1.488 --- CHANGES 1997/11/06 03:03:08 1.487 +++ CHANGES 1997/11/06 10:46:58 1.488 @@ -1,10 +1,7 @@ Changes with Apache 1.3b3 - - *) Restored USE_FCNTL_SERIALIZED_ACCEPT as the default for Solaris2, - since the PTHREAD mechanism was losing locks on Solaris 2.5.0. - You can now set -DUSE_SYSVSEM_SERIALIZED_ACCEPT or - -DUSE_PTHREAD_SERIALIZED_ACCEPT in Configuration if you want to - test the other two methods. [Roy Fielding] + + *) Solaris >= 2.5 was totally broken due to a mess up using pthread + mutexes. [Roy Fielding, Dean Gaudet] *) OS/2 Port updated; it should be possible to build OS/2 from the same sources as Unix now. [Brian Havard ] 1.153 +2 -2 apachen/src/main/conf.h Index: conf.h =================================================================== RCS file: /export/home/cvs/apachen/src/main/conf.h,v retrieving revision 1.152 retrieving revision 1.153 diff -u -r1.152 -r1.153 --- conf.h 1997/11/06 02:57:23 1.152 +++ conf.h 1997/11/06 10:47:00 1.153 @@ -125,8 +125,8 @@ #define HAVE_SYS_RESOURCE_H #define bzero(a,b) memset(a,0,b) #if !defined(USE_SYSVSEM_SERIALIZED_ACCEPT) && \ - !defined(USE_PTHREAD_SERIALIZED_ACCEPT) -#define USE_FCNTL_SERIALIZED_ACCEPT + !defined(USE_FCNTL_SERIALIZED_ACCEPT) +#define USE_PTHREAD_SERIALIZED_ACCEPT #endif #define NEED_UNION_SEMUN #define HAVE_MMAP 1.245 +47 -3 apachen/src/main/http_main.c Index: http_main.c =================================================================== RCS file: /export/home/cvs/apachen/src/main/http_main.c,v retrieving revision 1.244 retrieving revision 1.245 diff -u -r1.244 -r1.245 --- http_main.c 1997/11/05 12:48:17 1.244 +++ http_main.c 1997/11/06 10:47:01 1.245 @@ -333,18 +333,33 @@ #elif defined (USE_PTHREAD_SERIALIZED_ACCEPT) /* This code probably only works on Solaris ... but it works really fast - * on Solaris + * on Solaris. Note that pthread mutexes are *NOT* released when a task + * dies ... the task has to free it itself. So we block signals and + * try to be nice about releasing the mutex. */ #include -static pthread_mutex_t *accept_mutex; +static pthread_mutex_t *accept_mutex = (void *)(caddr_t) -1; +static int have_accept_mutex; +static sigset_t accept_block_mask; +static sigset_t accept_previous_mask; + +static void accept_mutex_child_cleanup(void *data) +{ + if (accept_mutex != (void *)(caddr_t)-1 + && have_accept_mutex) { + pthread_mutex_unlock(accept_mutex); + } +} static void accept_mutex_cleanup(void) { - if (munmap((caddr_t) accept_mutex, sizeof(*accept_mutex))) { + if (accept_mutex != (void *)(caddr_t)-1 + && munmap((caddr_t) accept_mutex, sizeof(*accept_mutex))) { perror("munmap"); } + accept_mutex = (void *)(caddr_t)-1; } static void accept_mutex_init(pool *p) @@ -376,14 +391,25 @@ perror("pthread_mutex_init"); exit(1); } + sigfillset(&accept_block_mask); + sigdelset(&accept_block_mask, SIGHUP); + sigdelset(&accept_block_mask, SIGTERM); + sigdelset(&accept_block_mask, SIGUSR1); + register_cleanup(pconf, NULL, accept_mutex_child_cleanup, + accept_mutex_child_cleanup); } static void accept_mutex_on() { + if (sigprocmask(SIG_BLOCK, &accept_block_mask, &accept_previous_mask)) { + perror("sigprocmask(SIG_BLOCK)"); + exit (1); + } if (pthread_mutex_lock(accept_mutex)) { perror("pthread_mutex_lock"); exit(1); } + have_accept_mutex = 1; } static void accept_mutex_off() @@ -391,6 +417,24 @@ if (pthread_mutex_unlock(accept_mutex)) { perror("pthread_mutex_unlock"); exit(1); + } + /* There is a slight race condition right here... if we were to die right + * now, we'd do another pthread_mutex_unlock. Now, doing that would let + * another process into the mutex. pthread mutexes are designed to be + * fast, as such they don't have protection for things like testing if the + * thread owning a mutex is actually unlocking it (or even any way of + * testing who owns the mutex). + * + * If we were to unset have_accept_mutex prior to releasing the mutex + * then the race could result in the server unable to serve hits. Doing + * it this way means that the server can continue, but an additional + * child might be in the critical section ... at least it's still serving + * hits. + */ + have_accept_mutex = 0; + if (sigprocmask(SIG_SETMASK, &accept_previous_mask, NULL)) { + perror("sigprocmask(SIG_SETMASK)"); + exit (1); } }