mputil.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #ifndef MPUTIL_HPP
  14. #define MPUTIL_HPP
  15. #include "jtime.hpp"
  16. #include "mpbase.hpp"
  17. #include "mpbuff.hpp"
  18. #include "mpcomm.hpp"
  19. // Template to handle a message on another thread
  20. template <class PARENT>
  21. class CMessageHandler: public CInterface, public IThreadFactory
  22. {
  23. PARENT *parent;
  24. void (PARENT::*handler)(CMessageBuffer &_mb);
  25. IThreadPool *pool;
  26. bool hasexceptionhandler;
  27. char *name;
  28. public:
  29. virtual void Link(void) const { CInterface::Link(); }
  30. virtual bool Release(void) const
  31. {
  32. //Note: getLinkCount() is not thread safe
  33. if (pool&&(CInterface::getLinkCount()==2)) { // circular dependancy
  34. pool->Release();
  35. const_cast<CMessageHandler *>(this)->pool = NULL;
  36. }
  37. return CInterface::Release();
  38. }
  39. CMessageHandler(const char *_name,PARENT *_parent,void (PARENT::*_handler)(CMessageBuffer &_mb), IExceptionHandler *exceptionHandler=NULL, unsigned maxthreads=40, unsigned timeoutOnRelease=INFINITE, unsigned lowThreadsDelay=1000)
  40. {
  41. parent = _parent;
  42. handler = _handler;
  43. name = strdup(_name);
  44. pool = createThreadPool(name,this,exceptionHandler,maxthreads,lowThreadsDelay,0,timeoutOnRelease); // this will cause this to be linked
  45. hasexceptionhandler = exceptionHandler!=NULL;
  46. }
  47. ~CMessageHandler()
  48. {
  49. if (pool) {
  50. IThreadPool *p = pool;
  51. pool = NULL;
  52. p->Release();
  53. }
  54. free(name);
  55. }
  56. void threadmain(CMessageBuffer &mb)
  57. {
  58. if (hasexceptionhandler)
  59. (parent->*handler)(mb);
  60. else {
  61. try {
  62. (parent->*handler)(mb);
  63. }
  64. catch (IException *e) {
  65. EXCLOG(e, name);
  66. e->Release();
  67. }
  68. }
  69. mb.resetBuffer();
  70. }
  71. class Chandler: implements IPooledThread, public CInterface
  72. {
  73. CMessageBuffer mb;
  74. CMessageHandler<PARENT> *owner;
  75. public:
  76. IMPLEMENT_IINTERFACE;
  77. Chandler(CMessageHandler<PARENT> *_owner)
  78. {
  79. owner = _owner;
  80. }
  81. void init(void *_mb)
  82. {
  83. mb.transferFrom(*(CMessageBuffer *)_mb);
  84. }
  85. virtual void threadmain() override
  86. {
  87. owner->threadmain(mb);
  88. }
  89. virtual bool canReuse() const override
  90. {
  91. return true;
  92. }
  93. virtual bool stop() override
  94. {
  95. return true;
  96. }
  97. };
  98. IPooledThread *createNew()
  99. {
  100. return new Chandler(this);
  101. }
  102. void handleMessage (CMessageBuffer &mb)
  103. {
  104. StringBuffer runname(name);
  105. runname.append(" Message:");
  106. byte *b = (byte *)mb.toByteArray();
  107. size32_t l = mb.length();
  108. if (l>32)
  109. l = 32;
  110. while (l--)
  111. runname.append(' ').appendhex(*(b++),true);
  112. pool->start(&mb,runname.str());
  113. }
  114. void setThreadPoolTracing(unsigned secs)
  115. {
  116. if (pool)
  117. pool->setStartDelayTracing(secs);
  118. }
  119. };
  120. #endif