message_queue.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:8k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: message_queue.cpp,v $
  4.  * PRODUCTION Revision 1000.5  2004/06/01 20:44:07  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.17
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: message_queue.cpp,v 1000.5 2004/06/01 20:44:07 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Authors:  Mati Shomrat
  35.  *
  36.  * File Description:
  37.  *    CMessageQueue - GBench message queue
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <corelib/ncbistd.hpp>
  41. #include <corelib/ncbifile.hpp>
  42. #include <util/thread_pool.hpp>
  43. #include <gui/core/plugin_handle.hpp>
  44. #include <gui/core/plugin_registry.hpp>
  45. #include <gui/core/obj_convert.hpp>
  46. #include <gui/core/message_queue.hpp>
  47. #include <gui/plugin/PluginMessage.hpp>
  48. #include <gui/plugin/PluginReply.hpp>
  49. #include <gui/plugin/PluginReplyAction.hpp>
  50. #include <gui/core/message_history.hpp>
  51. #include <gui/core/plugin_utils.hpp>
  52. #include <gui/utils/message_box.hpp>
  53. #include <objects/seqset/Seq_entry.hpp>
  54. #include <serial/serial.hpp>
  55. #include <serial/objostrasn.hpp>
  56. #include "plugin_thread.hpp"
  57. BEGIN_NCBI_SCOPE
  58. USING_SCOPE(objects);
  59. // static variables
  60. static const SIZE_TYPE          QUEUE_SIZE = 100;
  61. // static mutex guarding access to the message queue
  62. DEFINE_STATIC_MUTEX(s_MessageQueueLock);
  63. // the one and only message queue
  64. CPluginMessageQueue::TMessageQueue CPluginMessageQueue::sm_Queue(QUEUE_SIZE);
  65. // a parallel task queue to hold messages in progress
  66. CPluginMessageQueue::TTasks CPluginMessageQueue::sm_TaskList;
  67. SIZE_TYPE CPluginMessageQueue::Size(void) THROWS_NONE
  68. {
  69.     return sm_Queue.GetSize();
  70. }
  71. SIZE_TYPE CPluginMessageQueue::Capacity(void) THROWS_NONE
  72. {
  73.     return sm_Queue.GetMaxSize();
  74. }
  75. bool CPluginMessageQueue::IsEmpty(void) THROWS_NONE
  76. {
  77.     return sm_Queue.IsEmpty();
  78. }
  79. bool CPluginMessageQueue::IsFull(void) THROWS_NONE
  80. {
  81.     return sm_Queue.IsFull();
  82. }
  83. // clear the message queue
  84. void CPluginMessageQueue::Clear(void) THROWS_NONE
  85. {
  86.     CMutexGuard GUARD(s_MessageQueueLock);
  87.     while ( !sm_Queue.IsEmpty() ) {
  88.         Get();
  89.     }
  90.     CPluginMessageHistory::Instance().Clear();
  91. }
  92. //
  93. // process a single message off of the queue
  94. //
  95. void CPluginMessageQueue::ProcessMessage(size_t timeout_sec,
  96.                                          size_t timeout_nsec) THROWS_NONE
  97. {
  98.     CMutexGuard GUARD(s_MessageQueueLock);
  99.     // first, see if we can get a message off of the queue
  100.     CRef<CPluginMessage> msg(Get(timeout_sec, timeout_nsec));
  101.     if (msg) {
  102.         ProcessMessage(*msg);
  103.     }
  104.     // next, reclaim our finished tasks
  105.     if (sm_TaskList.size() != 0) {
  106.         TTasks::iterator iter;
  107.         for (iter = sm_TaskList.begin();  iter != sm_TaskList.end();  ) {
  108.             if ( (*iter)->IsCompleted() ) {
  109.                 (*iter)->Finalize();
  110.                 sm_TaskList.erase(iter++);
  111.             } else {
  112.                 ++iter;
  113.             }
  114.         }
  115.     }
  116. }
  117. void CPluginMessageQueue::ProcessMessage(CPluginMessage& msg)
  118. {
  119.     CMutexGuard GUARD(s_MessageQueueLock);
  120.     // write to log and history
  121.     CPluginMessageHistory::Instance().AddMessage(msg);
  122.     const CPluginMessage::TDestination* dest = 0;
  123.     // Resolve the destination of the message:
  124.     //  - if destination specified use it, otherwise
  125.     //  - if it's a reply return to sender.
  126.     //  - in other cases drop the message
  127.     if ( msg.CanGetDestination() ) {
  128.         dest = &msg.GetDestination();
  129.     } 
  130.     CPluginHandle handle;
  131.     if ( dest != 0 ) {
  132.         handle = CPluginRegistry::GetPlugin(*dest);
  133.         if ( !handle ) {
  134.             x_DropMessage(msg);
  135.             return;
  136.         }
  137.     }
  138.     // call the plugin
  139.     try {
  140.         CRef<CPluginTask> new_task(new CPluginTask(handle, msg));
  141.         if (new_task->IsCompleted() ) {
  142.             new_task->Finalize();
  143.         } else {
  144.             sm_TaskList.push_back(new_task);
  145.         }
  146.     }
  147.     catch (CException& e) {
  148.         string str("Error running plugin ");
  149.         str += *dest;
  150.         str += "n";
  151.         str += e.GetMsg();
  152.         LOG_POST(Error << str);
  153.         NcbiMessageBox(str);
  154.     }
  155. }
  156. void CPluginMessageQueue::x_DropMessage(const CPluginMessage& msg)
  157. {
  158.     LOG_POST(Info << "Unhandled message: "  << msg.ToString());
  159. }
  160. CPluginMessage*
  161. CPluginMessageQueue::Get(size_t timeout_sec,
  162.                          size_t timeout_nsec) THROWS_NONE
  163. {
  164.     if ( !IsEmpty() ) {
  165.         try {
  166.             CRef<CPluginMessage> msg = sm_Queue.Get(timeout_sec, timeout_nsec);
  167.             // !!! HISTORY: time message left queue
  168.             return msg.Release();
  169.         }
  170.         catch ( exception& ) {
  171.             //  
  172.         }
  173.     }
  174.     return NULL;
  175. }
  176. bool CPluginMessageQueue::Add(CPluginMessage& msg) THROWS_NONE
  177. {
  178.     try {
  179.         while ( sm_Queue.IsFull() ) {
  180.             sm_Queue.WaitForRoom();
  181.         }
  182.         CRef<CPluginMessage> ref(&msg);
  183.         sm_Queue.Put(ref);
  184.         return true;
  185.     }
  186.     catch (exception&) {
  187.     }
  188.     
  189.     return false;
  190. }
  191. END_NCBI_SCOPE
  192. /*
  193.  * ===========================================================================
  194.  * $Log: message_queue.cpp,v $
  195.  * Revision 1000.5  2004/06/01 20:44:07  gouriano
  196.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.17
  197.  *
  198.  * Revision 1.17  2004/05/21 22:27:40  gorelenk
  199.  * Added PCH ncbi_pch.hpp
  200.  *
  201.  * Revision 1.16  2004/04/07 12:45:38  dicuccio
  202.  * Dropped unnecessary _TRACE().  Don't add a task to the task list if it has
  203.  * completed immediately
  204.  *
  205.  * Revision 1.15  2004/03/23 13:37:14  dicuccio
  206.  * Always use the task queue for processing messages, whether they are threaded or
  207.  * not
  208.  *
  209.  * Revision 1.14  2004/01/21 12:35:13  dicuccio
  210.  * Deleted unused variables.  Changed to no object converter API.
  211.  *
  212.  * Revision 1.13  2004/01/13 21:03:34  ucko
  213.  * Tweak to fix compilation when set::iterator yields only const access
  214.  * to elements (as GCC 3 does to ensure that they're always in correct order).
  215.  *
  216.  * Revision 1.12  2004/01/13 20:33:33  dicuccio
  217.  * Be smarted about calling UpdateAllViews() - call only once per document instead
  218.  * of once per object
  219.  *
  220.  * Revision 1.11  2003/12/31 20:27:07  dicuccio
  221.  * Code clean-up - deleted dead code
  222.  *
  223.  * Revision 1.10  2003/12/22 19:19:40  dicuccio
  224.  * Removed internal singleton
  225.  *
  226.  * Revision 1.9  2003/12/09 15:44:04  dicuccio
  227.  * Use CExpcetion::GetMsg() instead of what()
  228.  *
  229.  * Revision 1.8  2003/11/18 17:40:44  dicuccio
  230.  * Added default processing of plugin replies
  231.  *
  232.  * ===========================================================================
  233.  */