Linux は 2 パスで動作しますが、Windows は 4 パスで動作します。
構成後の読み取りフックでこのメソッドを使用すると、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 には 2 つではなく 4 つのパスがあります。あなたの初期化はまだ2回実行されます。
私の次の解決策は次のとおりです。
// 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 コードをラップすることでした。より良い方法があるかどうかはわかりませんが、うまくいきました。したがって、以下はセグメンテーション違反なしで両方のプラットフォームで機能します。
// 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
}
うまくいけば、他の誰かがこれから恩恵を受けるかもしれません。