/* Licensed to the Apache Software Foundation (ASF) under one or more *contributorlicenseagreements.SeetheNOTICEfiledistributedwith *thisworkforadditionalinformationregardingcopyrightownership. *TheASFlicensesthisfiletoYouundertheApacheLicense,Version2.0 *(the"License");youmaynotusethisfileexceptincompliancewith *theLicense.YoumayobtainacopyoftheLicenseat * *http://www.apache.org/licenses/LICENSE-2.0 * *Unlessrequiredbyapplicablelaworagreedtoinwriting,software *distributedundertheLicenseisdistributedonan"ASIS"BASIS, *WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied. *SeetheLicenseforthespecificlanguagegoverningpermissionsand *limitationsundertheLicense.
*/
/* Number of microseconds to camp out on the mutex */ #define CAMPOUT 10 /* Maximum number of times we camp out before giving up */ #define MAXCAMP 10 /* Number of microseconds the handler sits on the lock once acquired. */ #define SLEEPYTIME 1000
apr_shm_t *exipc_shm; /* Pointer to shared memory block */ char *shmfilename; /* Shared memory file name, used on some systems */
apr_global_mutex_t *exipc_mutex; /* Lock around shared memory segment access */ staticconstchar *exipc_mutex_type = "example-ipc-shm";
/* Data structure for shared memory block */ typedefstruct exipc_data {
apr_uint64_t counter; /* More fields if necessary */
} exipc_data;
/* *First,acquirethelock.Thiscodeisalotmoreinvolvedthan *itusuallyneedstobe,becausetheprocessbasedtrylock *routineisnotimplementedonunixplatforms.Ileftitinto *showhowitwouldworkiftrylockworked,andforsituations *andplatformswheretrylockworks.
*/ for (camped = 0, timecamped = 0; camped < MAXCAMP; camped++) {
rs = apr_global_mutex_trylock(exipc_mutex); if (APR_STATUS_IS_EBUSY(rs)) {
apr_sleep(CAMPOUT);
} elseif (APR_SUCCESS == rs) {
gotlock = 1; break; /* Get out of the loop */
} elseif (APR_STATUS_IS_ENOTIMPL(rs)) { /* If it's not implemented, just hang in the mutex. */
startcamp = apr_time_now();
rs = apr_global_mutex_lock(exipc_mutex);
timecamped = (apr_int64_t) (apr_time_now() - startcamp); if (APR_SUCCESS == rs) {
gotlock = 1; break; /* Out of the loop */
} else { /* Some error, log and bail */
ap_log_error(APLOG_MARK, APLOG_ERR, rs, r->server, APLOGNO(02995) "Child %ld failed to acquire lock",
(longint)getpid()); break; /* Out of the loop without having the lock */
}
} else { /* Some other error, log and bail */
ap_log_error(APLOG_MARK, APLOG_ERR, rs, r->server, APLOGNO(02996) "Child %ld failed to try and acquire lock",
(longint)getpid()); break; /* Out of the loop without having the lock */
}
/* Sleep for a millisecond to make it a little harder for *httpdchildrentoacquirethelock.
*/
apr_sleep(SLEEPYTIME);
r->content_type = "text/html";
if (!r->header_only) {
ap_rputs(HTML_HEADER, r); if (gotlock) { /* Increment the counter */
base = (exipc_data *)apr_shm_baseaddr_get(exipc_shm);
base->counter++; /* Send a page with our pid and the new value of the counter. */
ap_rprintf(r, "<p>Lock acquired after %ld microseoncds.</p>\n",
(longint) timecamped);
ap_rputs("<table border=\"1\">\n", r);
ap_rprintf(r, "<tr><td>Child pid:</td><td>%d</td></tr>\n",
(int) getpid());
ap_rprintf(r, "<tr><td>Counter:</td><td>%u</td></tr>\n",
(unsignedint)base->counter);
ap_rputs("</table>\n", r);
} else { /* *Sendapagesayingthatwecouldn'tgetthelock.Don'tsay *whatthecounteris,becausewithoutthelockthevaluecould *race.
*/
ap_rprintf(r, "<p>Child %d failed to acquire lock " "after camping out for %d microseconds.</p>\n",
(int) getpid(), (int) timecamped);
}
ap_rputs(HTML_FOOTER, r);
} /* r->header_only */
/* Release the lock */ if (gotlock)
rs = apr_global_mutex_unlock(exipc_mutex); /* Swallowing the result because what are we going to do with it at *thisstage?
*/
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.