APACHE 2.0 STATUS: -*-text-*-
-Last modified at [$Date: 2004/03/03 10:51:49 $]
+Last modified at [$Date: 2004/03/03 11:07:48 $]
Release:
nd replies: But if it can't be 0 the alternatives thereafter make no
sense anymore, right?
- * Fix corruption of buffered logs with threaded MPMs. PR 25520.
- http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/loggers/mod_log_config.c?r1=1.108&r2=1.109
- http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/loggers/mod_log_config.c?r1=1.109&r2=1.110
- [gosh nd, must have lost the commit message for that second one;
- I need to stop using silly gcc 3.2 I think]
- oops, 2 additional fixes needed:
- http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/loggers/mod_log_config.c?r1=1.113&r2=1.114
- [maybe nd didn't do such a big favor after all ;) ]
- Fix existing bug that leads to segfault with this fix if
- "BufferedLogs Off" is used:
- http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/loggers/mod_log_config.c?r1=1.114&r2=1.115
- +1: trawick, stoddard, jerenkrantz
-
* mod_isapi: GetServerVariable("ALL_RAW") returned the wrong buffer
size. PR 20617 [Jesse Pelton <jsp pkc.com>]
http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/arch/win32/mod_isapi.c?r1=1.96&r2=1.97
#include "apr_lib.h"
#include "apr_hash.h"
#include "apr_optional.h"
+#include "apr_anylock.h"
#define APR_WANT_STRFUNC
#include "apr_want.h"
#include "http_log.h"
#include "http_protocol.h"
#include "util_time.h"
+#include "ap_mpm.h"
#if APR_HAVE_UNISTD_H
#include <unistd.h>
static ap_log_writer *log_writer = ap_default_log_writer;
static ap_log_writer_init *log_writer_init = ap_default_log_writer_init;
static int buffered_logs = 0; /* default unbuffered */
+static apr_array_header_t *all_buffered_logs = NULL;
/* POSIX.1 defines PIPE_BUF as the maximum number of bytes that is
* guaranteed to be atomic when writing a pipe. And PIPE_BUF >= 512
apr_file_t *handle;
apr_size_t outcnt;
char outbuf[LOG_BUFSIZE];
+ apr_anylock_t mutex;
} buffered_log;
typedef struct {
static const char *set_buffered_logs_on(cmd_parms *parms, void *dummy, int flag)
{
buffered_logs = flag;
- ap_log_set_writer_init(ap_buffered_log_writer_init);
- ap_log_set_writer(ap_buffered_log_writer);
+ if (buffered_logs) {
+ ap_log_set_writer_init(ap_buffered_log_writer_init);
+ ap_log_set_writer(ap_buffered_log_writer);
+ }
return NULL;
}
static const command_rec config_log_cmds[] =
static int init_config_log(apr_pool_t *pc, apr_pool_t *p, apr_pool_t *pt, server_rec *s)
{
- /* First, do "physical" server, which gets default log fd and format
+ int res;
+
+ /* First init the buffered logs array, which is needed when opening the logs. */
+ if (buffered_logs) {
+ all_buffered_logs = apr_array_make(p, 5, sizeof(buffered_log *));
+ }
+
+ /* Next, do "physical" server, which gets default log fd and format
* for the virtual servers, if they don't override...
*/
- int res = open_multi_logs(s, p);
+ res = open_multi_logs(s, p);
/* Then, virtual servers */
static void init_child(apr_pool_t *p, server_rec *s)
{
+ int mpm_threads;
+
+ ap_mpm_query(AP_MPMQ_MAX_THREADS, &mpm_threads);
+
/* Now register the last buffer flush with the cleanup engine */
if (buffered_logs) {
+ int i;
+ buffered_log **array = (buffered_log **)all_buffered_logs->elts;
+
apr_pool_cleanup_register(p, s, flush_all_logs, flush_all_logs);
+
+ for (i = 0; i < all_buffered_logs->nelts; i++) {
+ buffered_log *this = array[i];
+
+#if APR_HAS_THREADS
+ if (mpm_threads > 1) {
+ apr_status_t rv;
+
+ this->mutex.type = apr_anylock_threadmutex;
+ rv = apr_thread_mutex_create(&this->mutex.lock.tm,
+ APR_THREAD_MUTEX_DEFAULT,
+ p);
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
+ "could not initialize buffered log mutex, "
+ "transfer log may become corrupted");
+ this->mutex.type = apr_anylock_none;
+ }
+ }
+ else
+#endif
+ {
+ this->mutex.type = apr_anylock_none;
+ }
+ }
}
}
const char* name)
{
buffered_log *b;
- b = apr_palloc(p, sizeof(buffered_log));
+ b = apr_pcalloc(p, sizeof(buffered_log));
b->handle = ap_default_log_writer_init(p, s, name);
- b->outcnt = 0;
- if (b->handle)
+ if (b->handle) {
+ *(buffered_log **)apr_array_push(all_buffered_logs) = b;
return b;
+ }
else
return NULL;
}
apr_status_t rv;
buffered_log *buf = (buffered_log*)handle;
+ if ((rv = APR_ANYLOCK_LOCK(&buf->mutex)) != APR_SUCCESS) {
+ return rv;
+ }
if (len + buf->outcnt > LOG_BUFSIZE) {
flush_log(buf);
buf->outcnt += len;
rv = APR_SUCCESS;
}
+
+ APR_ANYLOCK_UNLOCK(&buf->mutex);
return rv;
}