Linux работает в два прохода, но Windows работает в четыре прохода.
Используя этот метод в посте конфигурации чтения крюка работает для Linux, но не для Windows
// variables for base config start
const char *flag = "some_prefixed_flag_to_mashup_with_other_flags";
void *init_flag = NULL;
int dbl = APLOG_TRACE4;
// logger
logging logger(NULL, s, p);
// determine if this is the first time we have loaded
init_flag = ap_retained_data_get(flag);
// check flag result
if (init_flag == NULL)
{
// breakpoint
stdLog(logger, INFX_LOG_DATA, dbl);
// set first time flag local
ap_retained_data_create(flag, 1);
}
// call initization routine
else
{
// do something here
}
Пожалуйста, обратите внимание, что я экспорт C++ код в моих модулях, следовательно, использование классов. Кроме того, некоторые из объявлений переменных отсутствуют для краткости.
Значит, этого должно быть достаточно для Windows? Неправильно. Мне пришлось учиться этому назад, потому что сначала я основываюсь на Windows, но Windows имеет четыре прохода вместо двух. Там для вашей инициализации все равно будет работать дважды.
Мой следующий раствор следующим образом:
// variables for base config start
const char *flag = "some_prefixed_flag_to_mashup_with_other_flags";
void *init_flag = NULL;
char *pidname;
int dbl = APLOG_TRACE4;
pid_t pidNKey;
apr_file_t *pidfile;
// logger
logging logger(NULL, s, p);
// determine if this is the first time we have loaded
init_flag = ap_retained_data_get(flag);
// check flag result
if (init_flag == NULL)
{
// breakpoint
stdLog(logger, INFX_LOG_DATA, dbl);
// set first time flag local
ap_retained_data_create(flag, 1);
}
else
{
// break point
stdLog(logger, INFX_LOG_DATA, dbl);
// create a pid if not exists
if (ap_read_pid(p, "logs/httpd.pid", &pidNKey) == OK)
{
// break point
stdLog(logger, INFX_LOG_DATA, dbl);
// create a pid especially for our setup
pidname = apr_psprintf(ptemp, "logs/infx.%d.pid", pidNKey);
// if pidfile does not exist then create it
if (!fileExists(pidname, ptemp))
{
// break point
stdLog(logger, INFX_LOG_DATA, dbl);
// create the pid
apr_file_open(&pidfile, pidname, APR_WRITE|APR_APPEND|APR_CREATE, INFX_BASE_PERM, ptemp);
// add nonsensical data to it
apr_file_puts("1", pidfile);
// cllose the file and wait for run 2
apr_file_close(pidfile);
}
// begin work
else
{
// break point
stdLog(logger, INFX_LOG_DATA, dbl);
// we no longer require the pid file
apr_file_remove(pidname, ptemp);
}
}
}
Показалось работать .... Хорошо, я сделал с этой стороны, не так ли? НЕПРАВИЛЬНО! Я перебрался в ящик Linux и город segfault. Я уверен, что многие опытные разработчики Apache, вероятно, сейчас качают головами, но это те же самые парни, которые не документируют эти проблемы.
Мое последнее исправление заключалось в том, чтобы обернуть код Windows в определенные блоки. Я не уверен, был ли лучший способ или нет, но это сработало для меня. Таким образом, на обеих платформах работает без segfault.
// variables for base config start
const char *flag = "some_prefixed_flag_to_mashup_with_other_flags";
void *init_flag = NULL;
int dbl = APLOG_TRACE4;
// logger
logging logger(NULL, s, p);
// determine if this is the first time we have loaded
init_flag = ap_retained_data_get(flag);
// check flag result
if (init_flag == NULL)
{
// breakpoint
stdLog(logger, INFX_LOG_DATA, dbl);
// set first time flag local
ap_retained_data_create(flag, 1);
}
// call initization routine
else
{
// break point
stdLog(logger, INFX_LOG_DATA, dbl);
#if defined(WIN32)
// create a pid if not exists
if (ap_read_pid(p, "logs/httpd.pid", &pidNKey) == OK)
{
// break point
stdLog(logger, INFX_LOG_DATA, dbl);
// create a pid especially for our setup
pidname = apr_psprintf(ptemp, "logs/infx.%d.pid", pidNKey);
// if pidfile does not exist then create it
if (!fileExists(pidname, ptemp))
{
// break point
stdLog(logger, INFX_LOG_DATA, dbl);
// create the pid
apr_file_open(&pidfile, pidname, APR_WRITE|APR_APPEND|APR_CREATE, INFX_BASE_PERM, ptemp);
// add nonsensical data to it
apr_file_puts("1", pidfile);
// cllose the file and wait for run 2
apr_file_close(pidfile);
}
// begin work
else
{
// break point
stdLog(logger, INFX_LOG_DATA, dbl);
// we no longer require the pid file
apr_file_remove(pidname, ptemp);
#endif
// do something here for both platforms
#if defined(WIN32)
}
}
// crash if we do get a proper pid
else
{
// breakpoint
stdLog(logger, INFX_LOG_DATA, APLOG_CRIT, "HTTPD File not found? A Bug?");
// set status
return HTTP_INTERNAL_SERVER_ERROR;
}
#endif
}
Надеюсь, кто-то может воспользоваться этим.
Функция fileExists - это оболочка вокруг различных процедур apr_io, чтобы определить, существует ли файл. –