Fawkes API Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * multi.h - Fawkes multi logger 00004 * 00005 * Created: Mon May 07 16:44:15 2007 00006 * Copyright 2006-2007 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <utils/logging/multi.h> 00025 #include <utils/logging/logger.h> 00026 00027 #include <core/utils/lock_list.h> 00028 #include <core/threading/thread.h> 00029 00030 #include <sys/time.h> 00031 #include <time.h> 00032 00033 namespace fawkes { 00034 00035 /// @cond INTERNALS 00036 class MultiLoggerData 00037 { 00038 public: 00039 MultiLoggerData() 00040 { 00041 mutex = new Mutex(); 00042 } 00043 00044 ~MultiLoggerData() 00045 { 00046 delete mutex; 00047 mutex = NULL; 00048 } 00049 00050 LockList<Logger *> loggers; 00051 LockList<Logger *>::iterator logit; 00052 Mutex *mutex; 00053 Thread::CancelState old_state; 00054 }; 00055 /// @endcond 00056 00057 00058 /** @class MultiLogger <utils/logging/multi.h> 00059 * Log through multiple loggers. 00060 * It can be hand to have the opportunity to log to multiple channels, for 00061 * example log to a file and via network to a remote console. This can be 00062 * done with the MultiLogger. You can add an arbitrary number of loggers 00063 * to log the output to. Use the minimum number of necessary loggers though 00064 * because this can cause a high burden on log users if you have too many 00065 * loggers. 00066 * 00067 * Note that the multi logger takes over the ownership of the logger. That 00068 * means that the multi logger destroys all sub-loggers when it is deleted 00069 * itself. If you want to take over the loggers without destroying them you 00070 * have to properly remove them before destroying the multi logger. 00071 * 00072 * @author Tim Niemueller 00073 */ 00074 00075 /** Constructor. 00076 * This will create the logger without any sub-loggers. Message that are 00077 * logged are simply ignored. 00078 */ 00079 MultiLogger::MultiLogger() 00080 { 00081 data = new MultiLoggerData(); 00082 } 00083 00084 00085 /** Constructor. 00086 * This sets one sub-logger that messages are sent to. 00087 * @param logger sub-logger 00088 */ 00089 MultiLogger::MultiLogger(Logger *logger) 00090 { 00091 data = new MultiLoggerData(); 00092 data->loggers.push_back_locked(logger); 00093 } 00094 00095 00096 /** Destructor. 00097 * This will destroy all sub-data->loggers (they are deleted). 00098 */ 00099 MultiLogger::~MultiLogger() 00100 { 00101 data->loggers.lock(); 00102 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00103 delete (*data->logit); 00104 } 00105 data->loggers.clear(); 00106 data->loggers.unlock(); 00107 delete data; 00108 } 00109 00110 00111 /** Add a logger. 00112 * @param logger new sub-logger to add 00113 */ 00114 void 00115 MultiLogger::add_logger(Logger *logger) 00116 { 00117 data->mutex->lock(); 00118 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00119 data->loggers.lock(); 00120 data->loggers.push_back(logger); 00121 data->loggers.sort(); 00122 data->loggers.unique(); 00123 data->loggers.unlock(); 00124 Thread::set_cancel_state(data->old_state); 00125 data->mutex->unlock(); 00126 } 00127 00128 00129 /** Remove logger. 00130 * @param logger Sub-logger to remove 00131 */ 00132 void 00133 MultiLogger::remove_logger(Logger *logger) 00134 { 00135 data->mutex->lock(); 00136 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00137 00138 data->loggers.remove_locked(logger); 00139 Thread::set_cancel_state(data->old_state); 00140 data->mutex->unlock(); 00141 } 00142 00143 00144 void 00145 MultiLogger::set_loglevel(LogLevel level) 00146 { 00147 data->mutex->lock(); 00148 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00149 00150 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00151 (*data->logit)->set_loglevel(level); 00152 } 00153 Thread::set_cancel_state(data->old_state); 00154 data->mutex->unlock(); 00155 } 00156 00157 00158 void 00159 MultiLogger::log(LogLevel level, const char *component, const char *format, ...) 00160 { 00161 struct timeval now; 00162 gettimeofday(&now, NULL); 00163 data->mutex->lock(); 00164 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00165 00166 va_list va; 00167 va_start(va, format); 00168 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00169 va_list vac; 00170 va_copy(vac, va); 00171 (*data->logit)->vtlog(level, &now, component, format, vac); 00172 va_end(vac); 00173 } 00174 va_end(va); 00175 Thread::set_cancel_state(data->old_state); 00176 data->mutex->unlock(); 00177 } 00178 00179 00180 void 00181 MultiLogger::log_debug(const char *component, const char *format, ...) 00182 { 00183 struct timeval now; 00184 gettimeofday(&now, NULL); 00185 data->mutex->lock(); 00186 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00187 00188 va_list va; 00189 va_start(va, format); 00190 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00191 va_list vac; 00192 va_copy(vac, va); 00193 (*data->logit)->vlog_debug(component, format, vac); 00194 va_end(vac); 00195 } 00196 va_end(va); 00197 Thread::set_cancel_state(data->old_state); 00198 data->mutex->unlock(); 00199 } 00200 00201 00202 void 00203 MultiLogger::log_info(const char *component, const char *format, ...) 00204 { 00205 struct timeval now; 00206 gettimeofday(&now, NULL); 00207 data->mutex->lock(); 00208 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00209 00210 va_list va; 00211 va_start(va, format); 00212 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00213 va_list vac; 00214 va_copy(vac, va); 00215 (*data->logit)->vlog_info(component, format, vac); 00216 va_end(vac); 00217 } 00218 va_end(va); 00219 Thread::set_cancel_state(data->old_state); 00220 data->mutex->unlock(); 00221 } 00222 00223 00224 void 00225 MultiLogger::log_warn(const char *component, const char *format, ...) 00226 { 00227 struct timeval now; 00228 gettimeofday(&now, NULL); 00229 data->mutex->lock(); 00230 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00231 00232 va_list va; 00233 va_start(va, format); 00234 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00235 va_list vac; 00236 va_copy(vac, va); 00237 (*data->logit)->vlog_warn(component, format, vac); 00238 va_end(vac); 00239 } 00240 va_end(va); 00241 Thread::set_cancel_state(data->old_state); 00242 data->mutex->unlock(); 00243 } 00244 00245 00246 void 00247 MultiLogger::log_error(const char *component, const char *format, ...) 00248 { 00249 struct timeval now; 00250 gettimeofday(&now, NULL); 00251 data->mutex->lock(); 00252 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00253 00254 va_list va; 00255 va_start(va, format); 00256 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00257 va_list vac; 00258 va_copy(vac, va); 00259 (*data->logit)->vlog_error(component, format, vac); 00260 va_end(vac); 00261 } 00262 va_end(va); 00263 Thread::set_cancel_state(data->old_state); 00264 data->mutex->unlock(); 00265 } 00266 00267 00268 void 00269 MultiLogger::log(LogLevel level, const char *component, Exception &e) 00270 { 00271 struct timeval now; 00272 gettimeofday(&now, NULL); 00273 data->mutex->lock(); 00274 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00275 00276 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00277 (*data->logit)->log(level, component, e); 00278 } 00279 Thread::set_cancel_state(data->old_state); 00280 data->mutex->unlock(); 00281 } 00282 00283 00284 void 00285 MultiLogger::log_debug(const char *component, Exception &e) 00286 { 00287 struct timeval now; 00288 gettimeofday(&now, NULL); 00289 data->mutex->lock(); 00290 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00291 00292 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00293 (*data->logit)->tlog_debug(&now, component, e); 00294 } 00295 00296 Thread::set_cancel_state(data->old_state); 00297 data->mutex->unlock(); 00298 } 00299 00300 void 00301 MultiLogger::log_info(const char *component, Exception &e) 00302 { 00303 struct timeval now; 00304 gettimeofday(&now, NULL); 00305 data->mutex->lock(); 00306 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00307 00308 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00309 (*data->logit)->tlog_info(&now, component, e); 00310 } 00311 Thread::set_cancel_state(data->old_state); 00312 data->mutex->unlock(); 00313 } 00314 00315 00316 void 00317 MultiLogger::log_warn(const char *component, Exception &e) 00318 { 00319 struct timeval now; 00320 gettimeofday(&now, NULL); 00321 data->mutex->lock(); 00322 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00323 00324 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00325 (*data->logit)->tlog_warn(&now, component, e); 00326 } 00327 Thread::set_cancel_state(data->old_state); 00328 data->mutex->unlock(); 00329 } 00330 00331 00332 void 00333 MultiLogger::log_error(const char *component, Exception &e) 00334 { 00335 struct timeval now; 00336 gettimeofday(&now, NULL); 00337 data->mutex->lock(); 00338 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00339 00340 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00341 (*data->logit)->tlog_error(&now, component, e); 00342 } 00343 Thread::set_cancel_state(data->old_state); 00344 data->mutex->unlock(); 00345 } 00346 00347 00348 void 00349 MultiLogger::vlog(LogLevel level, 00350 const char *component, const char *format, va_list va) 00351 { 00352 struct timeval now; 00353 gettimeofday(&now, NULL); 00354 data->mutex->lock(); 00355 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00356 00357 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00358 va_list vac; 00359 va_copy(vac, va); 00360 (*data->logit)->vlog(level, component, format, vac); 00361 va_end(vac); 00362 } 00363 Thread::set_cancel_state(data->old_state); 00364 data->mutex->unlock(); 00365 } 00366 00367 00368 void 00369 MultiLogger::vlog_debug(const char *component, const char *format, va_list va) 00370 { 00371 struct timeval now; 00372 gettimeofday(&now, NULL); 00373 data->mutex->lock(); 00374 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00375 00376 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00377 va_list vac; 00378 va_copy(vac, va); 00379 (*data->logit)->vtlog_debug(&now, component, format, vac); 00380 va_end(vac); 00381 } 00382 Thread::set_cancel_state(data->old_state); 00383 data->mutex->unlock(); 00384 } 00385 00386 00387 void 00388 MultiLogger::vlog_info(const char *component, const char *format, va_list va) 00389 { 00390 struct timeval now; 00391 gettimeofday(&now, NULL); 00392 data->mutex->lock(); 00393 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00394 00395 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00396 va_list vac; 00397 va_copy(vac, va); 00398 (*data->logit)->vtlog_info(&now, component, format, vac); 00399 va_end(vac); 00400 } 00401 Thread::set_cancel_state(data->old_state); 00402 data->mutex->unlock(); 00403 } 00404 00405 00406 void 00407 MultiLogger::vlog_warn(const char *component, const char *format, va_list va) 00408 { 00409 struct timeval now; 00410 gettimeofday(&now, NULL); 00411 data->mutex->lock(); 00412 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00413 00414 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00415 va_list vac; 00416 va_copy(vac, va); 00417 (*data->logit)->vtlog_warn(&now, component, format, vac); 00418 va_end(vac); 00419 } 00420 Thread::set_cancel_state(data->old_state); 00421 data->mutex->unlock(); 00422 } 00423 00424 00425 void 00426 MultiLogger::vlog_error(const char *component, const char *format, va_list va) 00427 { 00428 struct timeval now; 00429 gettimeofday(&now, NULL); 00430 data->mutex->lock(); 00431 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00432 00433 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00434 va_list vac; 00435 va_copy(vac, va); 00436 (*data->logit)->vtlog_error(&now, component, format, vac); 00437 va_end(vac); 00438 } 00439 Thread::set_cancel_state(data->old_state); 00440 data->mutex->unlock(); 00441 } 00442 00443 void 00444 MultiLogger::tlog(LogLevel level, struct timeval *t, 00445 const char *component, const char *format, ...) 00446 { 00447 data->mutex->lock(); 00448 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00449 va_list va; 00450 va_start(va, format); 00451 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00452 va_list vac; 00453 va_copy(vac, va); 00454 (*data->logit)->vtlog(level, t, component, format, vac); 00455 va_end(vac); 00456 } 00457 va_end(va); 00458 Thread::set_cancel_state(data->old_state); 00459 data->mutex->unlock(); 00460 } 00461 00462 00463 void 00464 MultiLogger::tlog_debug(struct timeval *t, const char *component, const char *format, ...) 00465 { 00466 data->mutex->lock(); 00467 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00468 va_list va; 00469 va_start(va, format); 00470 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00471 va_list vac; 00472 va_copy(vac, va); 00473 (*data->logit)->vlog_debug(component, format, vac); 00474 va_end(vac); 00475 } 00476 va_end(va); 00477 Thread::set_cancel_state(data->old_state); 00478 data->mutex->unlock(); 00479 } 00480 00481 00482 void 00483 MultiLogger::tlog_info(struct timeval *t, const char *component, const char *format, ...) 00484 { 00485 data->mutex->lock(); 00486 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00487 00488 va_list va; 00489 va_start(va, format); 00490 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00491 va_list vac; 00492 va_copy(vac, va); 00493 (*data->logit)->vtlog_info(t, component, format, vac); 00494 va_end(vac); 00495 } 00496 va_end(va); 00497 Thread::set_cancel_state(data->old_state); 00498 data->mutex->unlock(); 00499 } 00500 00501 00502 void 00503 MultiLogger::tlog_warn(struct timeval *t, const char *component, const char *format, ...) 00504 { 00505 data->mutex->lock(); 00506 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00507 00508 va_list va; 00509 va_start(va, format); 00510 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00511 va_list vac; 00512 va_copy(vac, va); 00513 (*data->logit)->vtlog_warn(t, component, format, vac); 00514 va_end(vac); 00515 } 00516 va_end(va); 00517 Thread::set_cancel_state(data->old_state); 00518 data->mutex->unlock(); 00519 } 00520 00521 00522 void 00523 MultiLogger::tlog_error(struct timeval *t, const char *component, const char *format, ...) 00524 { 00525 data->mutex->lock(); 00526 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00527 00528 va_list va; 00529 va_start(va, format); 00530 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00531 va_list vac; 00532 va_copy(vac, va); 00533 (*data->logit)->vtlog_error(t, component, format, vac); 00534 va_end(vac); 00535 } 00536 va_end(va); 00537 Thread::set_cancel_state(data->old_state); 00538 data->mutex->unlock(); 00539 } 00540 00541 00542 void 00543 MultiLogger::tlog(LogLevel level, struct timeval *t, const char *component, Exception &e) 00544 { 00545 data->mutex->lock(); 00546 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00547 00548 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00549 (*data->logit)->tlog(level, t, component, e); 00550 } 00551 Thread::set_cancel_state(data->old_state); 00552 data->mutex->unlock(); 00553 } 00554 00555 00556 void 00557 MultiLogger::tlog_debug(struct timeval *t, const char *component, Exception &e) 00558 { 00559 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00560 (*data->logit)->tlog_error(t, component, e); 00561 } 00562 } 00563 00564 void 00565 MultiLogger::tlog_info(struct timeval *t, const char *component, Exception &e) 00566 { 00567 data->mutex->lock(); 00568 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00569 00570 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00571 (*data->logit)->tlog_error(t, component, e); 00572 } 00573 Thread::set_cancel_state(data->old_state); 00574 data->mutex->unlock(); 00575 } 00576 00577 00578 void 00579 MultiLogger::tlog_warn(struct timeval *t, const char *component, Exception &e) 00580 { 00581 data->mutex->lock(); 00582 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00583 00584 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00585 (*data->logit)->tlog_error(t, component, e); 00586 } 00587 Thread::set_cancel_state(data->old_state); 00588 data->mutex->unlock(); 00589 } 00590 00591 00592 void 00593 MultiLogger::tlog_error(struct timeval *t, const char *component, Exception &e) 00594 { 00595 data->mutex->lock(); 00596 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00597 00598 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00599 (*data->logit)->tlog_error(t, component, e); 00600 } 00601 Thread::set_cancel_state(data->old_state); 00602 data->mutex->unlock(); 00603 } 00604 00605 00606 00607 00608 void 00609 MultiLogger::vtlog(LogLevel level, struct timeval *t, 00610 const char *component, const char *format, va_list va) 00611 { 00612 data->mutex->lock(); 00613 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00614 00615 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00616 va_list vac; 00617 va_copy(vac, va); 00618 (*data->logit)->vtlog(level, t, component, format, vac); 00619 va_end(vac); 00620 } 00621 Thread::set_cancel_state(data->old_state); 00622 data->mutex->unlock(); 00623 } 00624 00625 00626 void 00627 MultiLogger::vtlog_debug(struct timeval *t, const char *component, const char *format, va_list va) 00628 { 00629 data->mutex->lock(); 00630 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00631 00632 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00633 va_list vac; 00634 va_copy(vac, va); 00635 (*data->logit)->vtlog_debug(t, component, format, vac); 00636 va_end(vac); 00637 } 00638 Thread::set_cancel_state(data->old_state); 00639 data->mutex->unlock(); 00640 } 00641 00642 00643 void 00644 MultiLogger::vtlog_info(struct timeval *t, const char *component, const char *format, va_list va) 00645 { 00646 data->mutex->lock(); 00647 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00648 00649 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00650 va_list vac; 00651 va_copy(vac, va); 00652 (*data->logit)->vtlog_info(t, component, format, vac); 00653 va_end(vac); 00654 } 00655 Thread::set_cancel_state(data->old_state); 00656 data->mutex->unlock(); 00657 } 00658 00659 00660 void 00661 MultiLogger::vtlog_warn(struct timeval *t, const char *component, const char *format, va_list va) 00662 { 00663 data->mutex->lock(); 00664 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00665 00666 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00667 va_list vac; 00668 va_copy(vac, va); 00669 (*data->logit)->vtlog_warn(t, component, format, vac); 00670 va_end(vac); 00671 } 00672 Thread::set_cancel_state(data->old_state); 00673 data->mutex->unlock(); 00674 } 00675 00676 00677 void 00678 MultiLogger::vtlog_error(struct timeval *t, const char *component, const char *format, va_list va) 00679 { 00680 data->mutex->lock(); 00681 Thread::set_cancel_state(Thread::CANCEL_DISABLED, &(data->old_state)); 00682 00683 for (data->logit = data->loggers.begin(); data->logit != data->loggers.end(); ++data->logit) { 00684 va_list vac; 00685 va_copy(vac, va); 00686 (*data->logit)->vtlog_error(t, component, format, vac); 00687 va_end(vac); 00688 } 00689 Thread::set_cancel_state(data->old_state); 00690 data->mutex->unlock(); 00691 } 00692 00693 00694 } // end namespace fawkes