manoj 99/05/09 01:39:32
Modified: pthreads/src/include acceptlock.h pthreads/src/main acceptlock.c http_accept.c Log: Partial solution for the graceful restart during accept locking problem. Make sure that each thread checks the shutdown flag before attempting to get the cross-process accept lock, so that if one thread notices that it's time to die, the rest will soon after. Revision Changes Path 1.5 +7 -2 apache-apr/pthreads/src/include/acceptlock.h Index: acceptlock.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/acceptlock.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -u -r1.4 -r1.5 --- acceptlock.h 1999/04/17 03:35:53 1.4 +++ acceptlock.h 1999/05/09 08:39:29 1.5 @@ -62,6 +62,11 @@ extern "C" { #endif +/* Prototypes for the intraprocess accept mutex functions */ +void intra_mutex_init(pool *p, int); +void intra_mutex_on(int); +void intra_mutex_off(int); + /* Prototyps for the accept mutex functions. */ #if defined (USE_USLOCK_SERIALIZED_ACCEPT) #define accept_mutex_child_init(x) @@ -79,13 +84,13 @@ #elif defined (USE_SYSVSEM_SERIALIZED_ACCEPT) void accept_mutex_cleanup(void *); -void accept_mutex_child_init(pool *); +#define accept_mutex_child_init(x) void accept_mutex_init(pool *, int); void accept_mutex_on(int); void accept_mutex_off(int); #elif defined(USE_FCNTL_SERIALIZED_ACCEPT) -void accept_mutex_child_init(pool *); +#define accept_mutex_child_init(x) void accept_mutex_init(pool *, int); void accept_mutex_on(int); void accept_mutex_off(int); 1.9 +10 -29 apache-apr/pthreads/src/main/acceptlock.c Index: acceptlock.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/acceptlock.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -u -r1.8 -r1.9 --- acceptlock.c 1999/04/22 19:09:01 1.8 +++ acceptlock.c 1999/05/09 08:39:30 1.9 @@ -83,25 +83,28 @@ /* Number of cross-process locks we're managing */ static int lock_count; +/* Number of intra-process locks we're managing */ +static int intra_lock_count; + /* Intraprocess locking used by other serialization techniques */ -#ifdef NEED_INTRAPROCESS_SERIALIZED_ACCEPT static pthread_mutex_t *intra_mutex = NULL; static void intra_mutex_cleanup(void *foo) { int i; - for (i = 0; i < lock_count; i++) { + for (i = 0; i < intra_lock_count; i++) { (void) pthread_mutex_destroy(&intra_mutex[i]); } } -static void intra_mutex_init(pool *p) +void intra_mutex_init(pool *p, int number_of_locks) { int i; - intra_mutex = (pthread_mutex_t *)ap_palloc(p, lock_count * sizeof(pthread_mutex_t )); - for (i = 0; i < lock_count; i++) { + intra_lock_count = number_of_locks; + intra_mutex = (pthread_mutex_t *)ap_palloc(p, intra_lock_count * sizeof(pthread_mutex_t )); + for (i = 0; i < intra_lock_count; i++) { if (pthread_mutex_init(&intra_mutex[i], NULL) != 0) { perror("intra_mutex_init"); clean_child_exit(APEXIT_CHILDFATAL); @@ -110,7 +113,7 @@ ap_register_cleanup(p, NULL, intra_mutex_cleanup, ap_null_cleanup); } -static void intra_mutex_on(int locknum) +void intra_mutex_on(int locknum) { if ((errno = pthread_mutex_lock(&intra_mutex[locknum])) != 0) { ap_log_error(APLOG_MARK, APLOG_EMERG, @@ -119,7 +122,7 @@ } } -static void intra_mutex_off(int locknum) +void intra_mutex_off(int locknum) { if (pthread_mutex_unlock(&intra_mutex[locknum]) != 0) { ap_log_error(APLOG_MARK, APLOG_EMERG, @@ -127,11 +130,6 @@ "Error releasing intraprocess lock. Exiting!"); } } -#else /* NEED_INTRAPROCESS_SERIALIZED_ACCEPT */ -#define intra_mutex_init(x) -#define intra_mutex_on(x) -#define intra_mutex_off(x) -#endif /* NEED_INTRAPROCESS_SERIALIZED_ACCEPT */ #if defined(USE_FCNTL_SERIALIZED_ACCEPT) || defined(USE_FLOCK_SERIALIZED_ACCEPT) static void init_lock_fname(pool *p) @@ -454,14 +452,8 @@ } } -void accept_mutex_child_init(pool *p) -{ - intra_mutex_init(p); -} - void accept_mutex_on(int locknum) { - intra_mutex_on(locknum); if (semop(sem_id[locknum], &op_on, 1) < 0) { perror("accept_mutex_on"); clean_child_exit(APEXIT_CHILDFATAL); @@ -474,7 +466,6 @@ perror("accept_mutex_off"); clean_child_exit(APEXIT_CHILDFATAL); } - intra_mutex_off(locknum); } #elif defined(USE_FCNTL_SERIALIZED_ACCEPT) @@ -519,16 +510,10 @@ } } -void accept_mutex_child_init(pool *p) -{ - intra_mutex_init(p); -} - void accept_mutex_on(int locknum) { int ret; - intra_mutex_on(locknum); while ((ret = fcntl(lock_fd[locknum], F_SETLKW, &lock_it)) < 0 && errno == EINTR) { /* nop */ @@ -558,7 +543,6 @@ "your lock file on a local disk!"); clean_child_exit(APEXIT_CHILDFATAL); } - intra_mutex_off(locknum); } #elif defined(USE_FLOCK_SERIALIZED_ACCEPT) @@ -584,7 +568,6 @@ { int i; - intra_mutex_init(p); for (i = 0; i < lock_count; i++) { char *lock_fname = expand_lock_fname(p, i); @@ -629,7 +612,6 @@ { int ret; - intra_mutex_on(locknum); while ((ret = flock(lock_fd[locknum], LOCK_EX)) < 0 && errno == EINTR) continue; @@ -649,7 +631,6 @@ "flock: LOCK_UN: Error freeing accept lock. Exiting!"); clean_child_exit(APEXIT_CHILDFATAL); } - intra_mutex_off(locknum); } #elif defined(USE_OS2SEM_SERIALIZED_ACCEPT) 1.12 +16 -0 apache-apr/pthreads/src/main/http_accept.c Index: http_accept.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_accept.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -u -r1.11 -r1.12 --- http_accept.c 1999/04/29 19:34:20 1.11 +++ http_accept.c 1999/05/09 08:39:31 1.12 @@ -109,9 +109,15 @@ (void) ap_update_child_status(my_pid, my_tid, SERVER_ACCEPTING, (request_rec *) NULL); /* lock around the accept if necessary */ + SAFE_ACCEPT(intra_mutex_on(my_tid - ap_threads_per_child)); + if (workers_may_exit) { + SAFE_ACCEPT(intra_mutex_off(my_tid - ap_threads_per_child)); + break; + } SAFE_ACCEPT(accept_mutex_on(my_tid - ap_threads_per_child)); if (queue_full(&csd_queue)) { SAFE_ACCEPT(accept_mutex_off(my_tid - ap_threads_per_child)); + SAFE_ACCEPT(intra_mutex_off(my_tid - ap_threads_per_child)); block_on_queue(&csd_queue); csd = -1; } @@ -119,6 +125,7 @@ csd = accept(sd, &sa_client, &len); requests_this_child--; SAFE_ACCEPT(accept_mutex_off(my_tid - ap_threads_per_child)); + SAFE_ACCEPT(intra_mutex_off(my_tid - ap_threads_per_child)); } (void) ap_update_child_status(my_pid, my_tid, SERVER_QUEUEING, (request_rec *) NULL); @@ -211,6 +218,7 @@ int worker_threads_per_child) { int queue_capacity = worker_threads_per_child + ap_acceptors_per_child; + SAFE_ACCEPT(intra_mutex_init(pchild, ap_acceptors_per_child)); SAFE_ACCEPT(accept_mutex_child_init(pchild)); requests_this_child = ap_max_requests_per_child; queue_init(&csd_queue, queue_capacity, pchild); @@ -338,6 +346,7 @@ int pipe_pair_of_death[2]; listen_rec *lr; + SAFE_ACCEPT(intra_mutex_init(pchild, 1)); SAFE_ACCEPT(accept_mutex_child_init(pchild)); requests_this_child = ap_max_requests_per_child; head_listener = ap_listeners; @@ -377,6 +386,11 @@ while ((ap_max_requests_per_child != 0 && requests_this_child > 0) || (ap_max_requests_per_child == 0)) { + SAFE_ACCEPT(intra_mutex_on(0)); + if (workers_may_exit) { + SAFE_ACCEPT(intra_mutex_off(0)); + return -1; + } SAFE_ACCEPT(accept_mutex_on(0)); for (;;) { @@ -398,6 +412,7 @@ continue; } SAFE_ACCEPT(accept_mutex_off(0)); + SAFE_ACCEPT(intra_mutex_off(0)); /* Single Unix documents select as returning errnos * EBADF, EINTR, and EINVAL... and in none of those * cases does it make sense to continue. In fact @@ -459,6 +474,7 @@ SAFE_ACCEPT(accept_mutex_off(0)); + SAFE_ACCEPT(intra_mutex_off(0)); if (csd >= 0) { return csd;