#include <sys/types.h> /* dev_t FreeBSD 2.1 */
#include <time.h>
+#include <isc/atomic.h>
#include <isc/dir.h>
#include <isc/file.h>
#include <isc/log.h>
int debug_level;
isc_mutex_t lock;
/* Locked by isc_log lock. */
- isc_logconfig_t *logconfig;
+ atomic_uintptr_t logconfig;
char buffer[LOG_BUFFER_SIZE];
ISC_LIST(isc_logmessage_t) messages;
};
}
if (result == ISC_R_SUCCESS) {
- lctx->logconfig = lcfg;
+ atomic_init(&lctx->logconfig, (uintptr_t)lcfg);
*lctxp = lctx;
if (lcfgp != NULL) {
return (result);
}
- LOCK(&lctx->lock);
-
- old_cfg = lctx->logconfig;
- lctx->logconfig = lcfg;
-
- UNLOCK(&lctx->lock);
+ old_cfg = (isc_logconfig_t *)atomic_exchange_acq_rel(&lctx->logconfig,
+ (uintptr_t)lcfg);
isc_logconfig_destroy(&old_cfg);
*lctxp = NULL;
mctx = lctx->mctx;
- if (lctx->logconfig != NULL) {
- lcfg = lctx->logconfig;
- lctx->logconfig = NULL;
+ lcfg = (isc_logconfig_t *)atomic_exchange_acq_rel(&lctx->logconfig,
+ (uintptr_t)NULL);
+ if (lcfg != NULL) {
isc_logconfig_destroy(&lcfg);
}
* This function cannot be called with a logconfig that is in
* use by a log context.
*/
- REQUIRE(lcfg->lctx != NULL && lcfg->lctx->logconfig != lcfg);
+ REQUIRE(lcfg->lctx != NULL &&
+ atomic_load_acquire(&lcfg->lctx->logconfig) != (uintptr_t)lcfg);
mctx = lcfg->lctx->mctx;
isc_logchannel_t *channel;
REQUIRE(VALID_CONTEXT(lctx));
+ REQUIRE(atomic_load_acquire(&lctx->logconfig) != (uintptr_t)NULL);
LOCK(&lctx->lock);
* Close ISC_LOG_DEBUGONLY channels if level is zero.
*/
if (lctx->debug_level == 0) {
- for (channel = ISC_LIST_HEAD(lctx->logconfig->channels);
- channel != NULL; channel = ISC_LIST_NEXT(channel, link))
- {
- if (channel->type == ISC_LOG_TOFILE &&
- (channel->flags & ISC_LOG_DEBUGONLY) != 0 &&
- FILE_STREAM(channel) != NULL)
+ isc_logconfig_t *lcfg = (isc_logconfig_t *)atomic_load_acquire(
+ &lctx->logconfig);
+ if (lcfg != NULL) {
+ for (channel = ISC_LIST_HEAD(lcfg->channels);
+ channel != NULL;
+ channel = ISC_LIST_NEXT(channel, link))
{
+ if (channel->type == ISC_LOG_TOFILE &&
+ (channel->flags & ISC_LOG_DEBUGONLY) != 0 &&
+ FILE_STREAM(channel) != NULL)
{
(void)fclose(FILE_STREAM(channel));
FILE_STREAM(channel) = NULL;
REQUIRE(VALID_CONTEXT(lctx));
LOCK(&lctx->lock);
- for (channel = ISC_LIST_HEAD(lctx->logconfig->channels);
- channel != NULL; channel = ISC_LIST_NEXT(channel, link))
- {
- if (channel->type == ISC_LOG_TOFILE &&
- FILE_STREAM(channel) != NULL) {
- {
+ isc_logconfig_t *lcfg =
+ (isc_logconfig_t *)atomic_load_acquire(&lctx->logconfig);
+ if (lcfg != NULL) {
+ for (channel = ISC_LIST_HEAD(lcfg->channels); channel != NULL;
+ channel = ISC_LIST_NEXT(channel, link))
+ {
+ if (channel->type == ISC_LOG_TOFILE &&
+ FILE_STREAM(channel) != NULL) {
(void)fclose(FILE_STREAM(channel));
FILE_STREAM(channel) = NULL;
}
* because that's a risk anyway if the logconfig is being
* dynamically changed.
*/
+ if (lctx == NULL) {
+ return (false);
+ }
- if (lctx == NULL || lctx->logconfig == NULL) {
+ isc_logconfig_t *lcfg =
+ (isc_logconfig_t *)atomic_load_acquire(&lctx->logconfig);
+ if (lcfg == NULL) {
return (false);
}
- return (level <= lctx->logconfig->highest_level ||
- (lctx->logconfig->dynamic && level <= lctx->debug_level));
+ return (level <= lcfg->highest_level ||
+ (lcfg->dynamic && level <= lctx->debug_level));
}
static void
lctx->buffer[0] = '\0';
- lcfg = lctx->logconfig;
+ lcfg = (isc_logconfig_t *)atomic_load_acquire(&lctx->logconfig);
category_channels = ISC_LIST_HEAD(lcfg->channellists[category->id]);