AsyncChannel.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. //
  2. // AsyncChannel.cpp
  3. //
  4. // $Id: //poco/1.4/Foundation/src/AsyncChannel.cpp#1 $
  5. //
  6. // Library: Foundation
  7. // Package: Logging
  8. // Module: AsyncChannel
  9. //
  10. // Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // SPDX-License-Identifier: BSL-1.0
  14. //
  15. #include "Poco/AsyncChannel.h"
  16. #include "Poco/Notification.h"
  17. #include "Poco/Message.h"
  18. #include "Poco/Formatter.h"
  19. #include "Poco/AutoPtr.h"
  20. #include "Poco/LoggingRegistry.h"
  21. #include "Poco/Exception.h"
  22. namespace Poco {
  23. class MessageNotification: public Notification
  24. {
  25. public:
  26. MessageNotification(const Message& msg):
  27. _msg(msg)
  28. {
  29. }
  30. ~MessageNotification()
  31. {
  32. }
  33. const Message& message() const
  34. {
  35. return _msg;
  36. }
  37. private:
  38. Message _msg;
  39. };
  40. AsyncChannel::AsyncChannel(Channel* pChannel, Thread::Priority prio):
  41. _pChannel(pChannel),
  42. _thread("AsyncChannel")
  43. {
  44. if (_pChannel) _pChannel->duplicate();
  45. _thread.setPriority(prio);
  46. }
  47. AsyncChannel::~AsyncChannel()
  48. {
  49. try
  50. {
  51. close();
  52. if (_pChannel) _pChannel->release();
  53. }
  54. catch (...)
  55. {
  56. poco_unexpected();
  57. }
  58. }
  59. void AsyncChannel::setChannel(Channel* pChannel)
  60. {
  61. FastMutex::ScopedLock lock(_channelMutex);
  62. if (_pChannel) _pChannel->release();
  63. _pChannel = pChannel;
  64. if (_pChannel) _pChannel->duplicate();
  65. }
  66. Channel* AsyncChannel::getChannel() const
  67. {
  68. return _pChannel;
  69. }
  70. void AsyncChannel::open()
  71. {
  72. FastMutex::ScopedLock lock(_threadMutex);
  73. if (!_thread.isRunning())
  74. _thread.start(*this);
  75. }
  76. void AsyncChannel::close()
  77. {
  78. if (_thread.isRunning())
  79. {
  80. while (!_queue.empty()) Thread::sleep(100);
  81. do
  82. {
  83. _queue.wakeUpAll();
  84. }
  85. while (!_thread.tryJoin(100));
  86. }
  87. }
  88. void AsyncChannel::log(const Message& msg)
  89. {
  90. open();
  91. _queue.enqueueNotification(new MessageNotification(msg));
  92. }
  93. void AsyncChannel::setProperty(const std::string& name, const std::string& value)
  94. {
  95. if (name == "channel")
  96. setChannel(LoggingRegistry::defaultRegistry().channelForName(value));
  97. else if (name == "priority")
  98. setPriority(value);
  99. else
  100. Channel::setProperty(name, value);
  101. }
  102. void AsyncChannel::run()
  103. {
  104. AutoPtr<Notification> nf = _queue.waitDequeueNotification();
  105. while (nf)
  106. {
  107. MessageNotification* pNf = dynamic_cast<MessageNotification*>(nf.get());
  108. {
  109. FastMutex::ScopedLock lock(_channelMutex);
  110. if (pNf && _pChannel) _pChannel->log(pNf->message());
  111. }
  112. nf = _queue.waitDequeueNotification();
  113. }
  114. }
  115. void AsyncChannel::setPriority(const std::string& value)
  116. {
  117. Thread::Priority prio = Thread::PRIO_NORMAL;
  118. if (value == "lowest")
  119. prio = Thread::PRIO_LOWEST;
  120. else if (value == "low")
  121. prio = Thread::PRIO_LOW;
  122. else if (value == "normal")
  123. prio = Thread::PRIO_NORMAL;
  124. else if (value == "high")
  125. prio = Thread::PRIO_HIGH;
  126. else if (value == "highest")
  127. prio = Thread::PRIO_HIGHEST;
  128. else
  129. throw InvalidArgumentException("thread priority", value);
  130. _thread.setPriority(prio);
  131. }
  132. } // namespace Poco