Linux fonctionne en deux passes, mais Windows fonctionne en quatre étapes.
utilisant cette méthode dans le crochet lire config post fonctionne pour Linux, mais pas 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
}
S'il vous plaît noter que je suis exportation code C++ dans mes modules, d'où l'utilisation des classes. De plus, certaines déclarations de variables sont absentes pour des raisons de concision.
Donc, cela devrait être suffisant pour Windows non? Faux. J'ai dû apprendre cela en arrière parce que je construis d'abord sur Windows, mais Windows a quatre passes au lieu de deux. Là pour votre initialisation fonctionnera encore deux fois.
Ma prochaine solution est la suivante:
// 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);
}
}
}
Semblait travailler .... Ok, je suis fait avec cette partie, non? FAUX! Je suis passé à la boîte Linux et la ville segfault. Je suis sûr que beaucoup de développeurs Apache aguerris secouent probablement la tête en ce moment, mais ce sont les mêmes gars qui ne documentent pas ces problèmes.
Mon dernier correctif était d'envelopper le code Windows dans des blocs définis. Je ne suis pas sûr s'il y avait un meilleur moyen ou pas, mais cela a fonctionné pour moi. Ainsi, les travaux suivants sur les deux plates-formes sans 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
}
Espérons que quelqu'un d'autre puisse en bénéficier.
La fonction fileExists est un wrapper autour des différentes routines apr_io pour déterminer si un fichier existe. –