Index Source Files Annotated Class List Alphabetical Class List Class Hierarchy Graphical Class Hierarchy

# CallStack.cpp

Go to the documentation of this file.

    00001 /****************************************************************************
    00002 ** Copyright (c) quickfixengine.org  All rights reserved.
    00003 **
    00004 ** This file is part of the QuickFIX FIX Engine
    00005 **
    00006 ** This file may be distributed under the terms of the quickfixengine.org
    00007 ** license as defined by quickfixengine.org and appearing in the file
    00008 ** LICENSE included in the packaging of this file.
    00009 **
    00010 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
    00011 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    00012 **
    00013 ** See http://www.quickfixengine.org/LICENSE for licensing information.
    00014 **
    00015 ** Contact ask@quickfixengine.org if any conditions of this licensing are
    00016 ** not clear to you.
    00017 **
    00018 ****************************************************************************/
    00019
    00020 #ifdef _MSC_VER
    00021 #include "stdafx.h"
    00022 #else
    00023 #include "config.h"
    00024 #endif
    00025 #include "CallStack.h"
    00026
    00027 #include <sstream>
    00028 #include <typeinfo>
    00029
    00030 namespace FIX
    00031 {
    00032   std::map<thread_id, CallStack::Context> CallStack::s_stack;
    00033   std::map<thread_id, CallStack::Context> CallStack::s_error;
    00034   Mutex CallStack::s_mutex;
    00035   int CallStack::Ignore::s_count = 0;
    00036
    00037   CallStack::CallStack(const std::string& name, const std::string& file, int line)
    00038   {
    00039     Locker locker(s_mutex);
    00040
    00041     #if TERMINATE_IN_STD
    00042       std::set_terminate(FIX::CallStack::terminate);
    00043     #else
    00044       set_terminate(FIX::CallStack::terminate);
    00045     #endif
    00046
    00047     Context& c = getContext();
    00048     if( !c.ignore )
    00049     {
    00050       c.push(Method(name, file, line));
    00051       getErrorContext() = c;
    00052     }
    00053   }
    00054
    00055   CallStack::~CallStack()
    00056   {
    00057     Locker locker(s_mutex);
    00058     Context& c = getContext();
    00059     if( !c.ignore )
    00060       c.pop();
    00061   }
    00062
    00063   void CallStack::output()
    00064   {
    00065     Locker locker(s_mutex);
    00066     std::map<thread_id, CallStack::Context>::iterator i;
    00067     for( i = s_error.begin(); i != s_error.end(); ++i )
    00068     {
    00069       Context& c = i->second;
    00070       if(c.size())
    00071         std::cerr << "thread(" << i->first << "):" << c.exception << std::endl;
    00072       while(c.size())
    00073       {
    00074         std::cerr << "  at " << c.top() << std::endl;
    00075         c.pop();
    00076       }
    00077     }
    00078   }
    00079
    00080   void CallStack::ignore(bool value)
    00081   {
    00082     Locker locker(s_mutex);
    00083     getContext().ignore = value;
    00084   }
    00085
    00086   void CallStack::caught( std::exception& e )
    00087   {
    00088     Locker locker(s_mutex);
    00089     Context& c = getErrorContext();
    00090     if( c.ignore ) return;
    00091     c.caught(e);
    00092   }
    00093
    00094   void CallStack::caught()
    00095   {
    00096     Locker locker(s_mutex);
    00097     Context& c = getErrorContext();
    00098     if( c.ignore ) return;
    00099     c.caught();
    00100   }
    00101
    00102   CallStack::Context& CallStack::getContext()
    00103   {
    00104     Locker locker(s_mutex);
    00105     return s_stack[thread_self()];
    00106   }
    00107
    00108   CallStack::Context& CallStack::getErrorContext()
    00109   {
    00110     Locker locker(s_mutex);
    00111     return s_error[thread_self()];
    00112   }
    00113
    00114   void CallStack::terminate()
    00115   {
    00116     Locker locker(s_mutex);
    00117     CallStack::output();
    00118     abort();
    00119   }
    00120
    00121   void CallStack::Context::caught( std::exception& e )
    00122   {
    00123 #if TYPEINFO_IN_STD
    00124     const std::type_info&
    00125 #else
    00126     const type_info&
    00127 #endif
    00128     type = typeid(e);
    00129
    00130     std::stringstream s;
    00131     s << type.name() << ": " << std::string(e.what());
    00132     exception = s.str();
    00133   }
    00134
    00135   void CallStack::Context::caught()
    00136   {
    00137     exception = "unknown exception";
    00138   }
    00139 }