comparison src/dnsbl.cpp @ 146:7278c9766e26

free old configs when last reference goes away
author carl
date Sun, 15 Oct 2006 17:21:07 -0700
parents ecb40aa3eaa5
children 9330b8d6a56b
comparison
equal deleted inserted replaced
145:9b9bab1d3c21 146:7278c9766e26
259 259
260 mlfiPriv::~mlfiPriv() { 260 mlfiPriv::~mlfiPriv() {
261 return_fd(); 261 return_fd();
262 pthread_mutex_lock(&config_mutex); 262 pthread_mutex_lock(&config_mutex);
263 pc->reference_count--; 263 pc->reference_count--;
264 bool last = (!pc->reference_count) && (pc != config);
264 pthread_mutex_unlock(&config_mutex); 265 pthread_mutex_unlock(&config_mutex);
266 if (last) delete pc; // free this config, since we were the last reference to it
265 reset(true); 267 reset(true);
266 } 268 }
267 269
268 void mlfiPriv::reset(bool final) { 270 void mlfiPriv::reset(bool final) {
269 if (mailaddr) free(mailaddr); 271 if (mailaddr) free(mailaddr);
1158 } 1160 }
1159 1161
1160 1162
1161 //////////////////////////////////////////////// 1163 ////////////////////////////////////////////////
1162 // thread to watch the old config files for changes 1164 // thread to watch the old config files for changes
1163 // and reload when needed. we also cleanup old 1165 // and reload when needed.
1164 // configs whose reference count has gone to zero.
1165 // we also clear the SMTP AUTH recipient counts hourly 1166 // we also clear the SMTP AUTH recipient counts hourly
1166 // 1167 //
1167 void* config_loader(void *arg); 1168 void* config_loader(void *arg);
1168 void* config_loader(void *arg) { 1169 void* config_loader(void *arg) {
1169 int loop = 0; 1170 int loop = 0;
1170 typedef set<CONFIG *> configp_set; 1171 typedef set<CONFIG *> configp_set;
1171 configp_set old_configs;
1172 while (loader_run) { 1172 while (loader_run) {
1173 sleep(180); // look for modifications every 3 minutes 1173 sleep(180); // look for modifications every 3 minutes
1174 if (!loader_run) break; 1174 if (!loader_run) break;
1175 loop++; 1175 loop++;
1176 if (loop == 20) { 1176 if (loop == 20) {
1196 if (reload) { 1196 if (reload) {
1197 CONFIG *newc = new_conf(); 1197 CONFIG *newc = new_conf();
1198 if (newc) { 1198 if (newc) {
1199 // replace the global config pointer 1199 // replace the global config pointer
1200 pthread_mutex_lock(&config_mutex); 1200 pthread_mutex_lock(&config_mutex);
1201 CONFIG *old = config; 1201 CONFIG *pc = config;
1202 bool last = pc && (!pc->reference_count);
1202 config = newc; 1203 config = newc;
1203 pthread_mutex_unlock(&config_mutex); 1204 pthread_mutex_unlock(&config_mutex);
1204 if (old) old_configs.insert(old); 1205 if (last) delete pc; // there were no references to this config
1205 } 1206 }
1206 else { 1207 else {
1207 // failed to load new config 1208 // failed to load new config
1208 my_syslog("failed to load new configuration"); 1209 my_syslog("failed to load new configuration");
1209 system("echo 'failed to load new dnsbl configuration from /etc/dnsbl' | mail -s 'error in /etc/dnsbl configuration' root"); 1210 system("echo 'failed to load new dnsbl configuration from /etc/dnsbl' | mail -s 'error in /etc/dnsbl configuration' root");
1210 // update the load time on the current config to prevent complaining every 3 minutes 1211 // update the load time on the current config to prevent complaining every 3 minutes
1211 dc.load_time = time(NULL); 1212 dc.load_time = time(NULL);
1212 } 1213 }
1213 }
1214 // now look for old configs with zero ref counts
1215 for (configp_set::iterator i=old_configs.begin(); i!=old_configs.end(); ) {
1216 CONFIG *old = *i;
1217 if (!old->reference_count) {
1218 if (debug_syslog) {
1219 char buf[maxlen];
1220 snprintf(buf, sizeof(buf), "freeing memory for old configuration generation %d", old->generation);
1221 my_syslog(buf);
1222 }
1223 delete old; // destructor does all the work
1224 old_configs.erase(i++);
1225 }
1226 else i++;
1227 } 1214 }
1228 } 1215 }
1229 return NULL; 1216 return NULL;
1230 } 1217 }
1231 1218