Click here to Skip to main content
15,892,927 members
Articles / Programming Languages / C++

RCF - Interprocess Communication for C++

Rate me:
Please Sign up or sign in to vote.
4.94/5 (147 votes)
25 Oct 2011CPOL20 min read 4.6M   8.4K   331  
A server/client IPC framework, using the C++ preprocessor as an IDL compiler.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>RCF: Tools.hpp Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="tabs.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.4.5 -->
<div class="tabs">
  <ul>
    <li><a href="main.html"><span>Main&nbsp;Page</span></a></li>
    <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
    <li id="current"><a href="files.html"><span>Files</span></a></li>
    <li><a href="dirs.html"><span>Directories</span></a></li>
  </ul></div>
<div class="nav">
<a class="el" href="dir_G_3A_2FDevelopment_2Fbuild_2Fscripts_2Fwin_2FBuildRcf2_5FOutput_2FRCF_2D0_2E4_2Finclude_2F.html">include</a>&nbsp;&raquo&nbsp;<a class="el" href="dir_G_3A_2FDevelopment_2Fbuild_2Fscripts_2Fwin_2FBuildRcf2_5FOutput_2FRCF_2D0_2E4_2Finclude_2FRCF_2F.html">RCF</a></div>
<h1>Tools.hpp</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 
<a name="l00002"></a>00002 <span class="comment">//*****************************************************************************</span>
<a name="l00003"></a>00003 <span class="comment">// RCF - Remote Call Framework</span>
<a name="l00004"></a>00004 <span class="comment">// Copyright (c) 2005. All rights reserved.</span>
<a name="l00005"></a>00005 <span class="comment">// Developed by Jarl Lindrud.</span>
<a name="l00006"></a>00006 <span class="comment">// Contact: jlindrud@hotmail.com .</span>
<a name="l00007"></a>00007 <span class="comment">//*****************************************************************************</span>
<a name="l00008"></a>00008 
<a name="l00009"></a>00009 <span class="preprocessor">#ifndef INCLUDE_RCF_TOOLS_HPP</span>
<a name="l00010"></a>00010 <span class="preprocessor"></span><span class="preprocessor">#define INCLUDE_RCF_TOOLS_HPP</span>
<a name="l00011"></a>00011 <span class="preprocessor"></span>
<a name="l00012"></a>00012 <span class="comment">// Various utilities</span>
<a name="l00013"></a>00013 
<a name="l00014"></a>00014 <span class="preprocessor">#include &lt;time.h&gt;</span>
<a name="l00015"></a>00015 
<a name="l00016"></a>00016 <span class="preprocessor">#include &lt;deque&gt;</span>
<a name="l00017"></a>00017 <span class="preprocessor">#include &lt;iostream&gt;</span>
<a name="l00018"></a>00018 <span class="preprocessor">#include &lt;iterator&gt;</span>
<a name="l00019"></a>00019 <span class="preprocessor">#include &lt;memory&gt;</span>
<a name="l00020"></a>00020 <span class="preprocessor">#include &lt;stdexcept&gt;</span>
<a name="l00021"></a>00021 <span class="preprocessor">#include &lt;typeinfo&gt;</span>
<a name="l00022"></a>00022 <span class="preprocessor">#include &lt;vector&gt;</span>
<a name="l00023"></a>00023 
<a name="l00024"></a>00024 <span class="preprocessor">#include &lt;boost/bind.hpp&gt;</span>
<a name="l00025"></a>00025 <span class="preprocessor">#include &lt;boost/current_function.hpp&gt;</span>
<a name="l00026"></a>00026 <span class="preprocessor">#include &lt;boost/function.hpp&gt;</span>
<a name="l00027"></a>00027 <span class="preprocessor">#include &lt;boost/noncopyable.hpp&gt;</span>
<a name="l00028"></a>00028 <span class="preprocessor">#include &lt;boost/static_assert.hpp&gt;</span>
<a name="l00029"></a>00029 <span class="preprocessor">#include &lt;boost/type_traits.hpp&gt;</span>
<a name="l00030"></a>00030 
<a name="l00031"></a>00031 <span class="preprocessor">#include &lt;RCF/Exception.hpp&gt;</span>
<a name="l00032"></a>00032 <span class="preprocessor">#include &lt;RCF/ScopeGuard.h&gt;</span>
<a name="l00033"></a>00033 <span class="preprocessor">#include &lt;RCF/ThreadLibrary.hpp&gt;</span>
<a name="l00034"></a>00034 <span class="preprocessor">#include &lt;RCF/util/Meta.hpp&gt;</span>
<a name="l00035"></a>00035 <span class="preprocessor">#include &lt;RCF/util/UnusedVariable.hpp&gt;</span>
<a name="l00036"></a>00036 
<a name="l00037"></a>00037 <span class="comment">// Assertion mechanism</span>
<a name="l00038"></a>00038 <span class="preprocessor">#include &lt;RCF/util/Assert.hpp&gt;</span>
<a name="l00039"></a>00039 <span class="preprocessor">#define RCF_ASSERT(x) UTIL_ASSERT(x, RCF::AssertionFailureException)</span>
<a name="l00040"></a>00040 <span class="preprocessor"></span>
<a name="l00041"></a>00041 <span class="comment">// Verification mechanism</span>
<a name="l00042"></a>00042 <span class="preprocessor">#include &lt;RCF/util/Throw.hpp&gt;</span>
<a name="l00043"></a>00043 <span class="preprocessor">#define RCF_VERIFY(x, msg) UTIL_VERIFY(x, RCF::VerificationFailureException, msg)</span>
<a name="l00044"></a>00044 <span class="preprocessor"></span>
<a name="l00045"></a>00045 <span class="comment">// Trace mechanism</span>
<a name="l00046"></a>00046 <span class="preprocessor">#include &lt;RCF/util/Trace.hpp&gt;</span>
<a name="l00047"></a>00047 <span class="comment">//#define RCF_TRACE(x) DUMMY_VARIABLE_ARG_MACRO()</span>
<a name="l00048"></a>00048 <span class="preprocessor">#define RCF_TRACE(x)  UTIL_TRACE(x, (*::RCF::pTraceChannels[0]))</span>
<a name="l00049"></a>00049 <span class="preprocessor"></span><span class="preprocessor">#define RCF1_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[1]))</span>
<a name="l00050"></a>00050 <span class="preprocessor"></span><span class="preprocessor">#define RCF2_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[2]))</span>
<a name="l00051"></a>00051 <span class="preprocessor"></span><span class="preprocessor">#define RCF3_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[3]))</span>
<a name="l00052"></a>00052 <span class="preprocessor"></span><span class="preprocessor">#define RCF4_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[4]))</span>
<a name="l00053"></a>00053 <span class="preprocessor"></span><span class="preprocessor">#define RCF5_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[5]))</span>
<a name="l00054"></a>00054 <span class="preprocessor"></span><span class="preprocessor">#define RCF6_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[6]))</span>
<a name="l00055"></a>00055 <span class="preprocessor"></span><span class="preprocessor">#define RCF7_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[7]))</span>
<a name="l00056"></a>00056 <span class="preprocessor"></span><span class="preprocessor">#define RCF8_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[8]))</span>
<a name="l00057"></a>00057 <span class="preprocessor"></span><span class="preprocessor">#define RCF9_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[9]))</span>
<a name="l00058"></a>00058 <span class="preprocessor"></span>
<a name="l00059"></a>00059 <span class="keyword">namespace </span>RCF {
<a name="l00060"></a>00060     <span class="keyword">extern</span> util::TraceChannel *pTraceChannels[10];
<a name="l00061"></a>00061 }
<a name="l00062"></a>00062 
<a name="l00063"></a>00063 <span class="comment">// Throw mechanism</span>
<a name="l00064"></a>00064 <span class="preprocessor">#include &lt;RCF/util/Throw.hpp&gt;</span>
<a name="l00065"></a>00065 <span class="preprocessor">#define RCF_THROW UTIL_THROW</span>
<a name="l00066"></a>00066 <span class="preprocessor"></span>
<a name="l00067"></a>00067 <span class="comment">// Scope guard mechanism</span>
<a name="l00068"></a>00068 <span class="keyword">namespace </span>RCF {
<a name="l00069"></a>00069 
<a name="l00070"></a>00070     <span class="keyword">class </span>SharedPtrScopeGuard : boost::noncopyable
<a name="l00071"></a>00071     {
<a name="l00072"></a>00072     <span class="keyword">public</span>:
<a name="l00073"></a>00073         <span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;
<a name="l00074"></a>00074         SharedPtrScopeGuard(T &amp;t) : 
<a name="l00075"></a>00075             spv(static_cast&lt;void*&gt;(NULL), t)
<a name="l00076"></a>00076         {}
<a name="l00077"></a>00077 
<a name="l00078"></a>00078         <span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> R&gt;
<a name="l00079"></a>00079         SharedPtrScopeGuard(T &amp;t, R (T::*pfn)() ) : 
<a name="l00080"></a>00080             spv(static_cast&lt;void*&gt;(NULL), boost::bind(pfn, &amp;t))
<a name="l00081"></a>00081         {}
<a name="l00082"></a>00082 
<a name="l00083"></a>00083         <span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> R, <span class="keyword">typename</span> A&gt;
<a name="l00084"></a>00084         SharedPtrScopeGuard(T &amp;t, R (T::*pfn)(A), A a) : 
<a name="l00085"></a>00085             spv(static_cast&lt;void*&gt;(NULL), boost::bind(pfn, &amp;t, a))
<a name="l00086"></a>00086         {}
<a name="l00087"></a>00087 
<a name="l00088"></a>00088         <span class="keywordtype">void</span> dismiss()
<a name="l00089"></a>00089         {
<a name="l00090"></a>00090             spv.reset();
<a name="l00091"></a>00091         }
<a name="l00092"></a>00092 
<a name="l00093"></a>00093     <span class="keyword">private</span>:
<a name="l00094"></a>00094         boost::shared_ptr&lt;void&gt; spv;
<a name="l00095"></a>00095     };
<a name="l00096"></a>00096 <span class="comment">/*</span>
<a name="l00097"></a>00097 <span class="comment">    template&lt;typename PFN&gt;</span>
<a name="l00098"></a>00098 <span class="comment">    void trigger0(void *pv)</span>
<a name="l00099"></a>00099 <span class="comment">    {</span>
<a name="l00100"></a>00100 <span class="comment">        ((PFN) pv)();</span>
<a name="l00101"></a>00101 <span class="comment">    }</span>
<a name="l00102"></a>00102 <span class="comment"></span>
<a name="l00103"></a>00103 <span class="comment">    template&lt;typename T, typename PMFN&gt;</span>
<a name="l00104"></a>00104 <span class="comment">    void trigger1(void *pvt, void *pvmfn)</span>
<a name="l00105"></a>00105 <span class="comment">    {</span>
<a name="l00106"></a>00106 <span class="comment">        PMFN pmfn = (PMFN) pvmfn;</span>
<a name="l00107"></a>00107 <span class="comment">        T *pt = (T *) pvt;</span>
<a name="l00108"></a>00108 <span class="comment">        pt-&gt;*pmfn();</span>
<a name="l00109"></a>00109 <span class="comment">    }</span>
<a name="l00110"></a>00110 <span class="comment">  </span>
<a name="l00111"></a>00111 <span class="comment">    class AlexandrescuScopeGuard</span>
<a name="l00112"></a>00112 <span class="comment">    {</span>
<a name="l00113"></a>00113 <span class="comment">    public:</span>
<a name="l00114"></a>00114 <span class="comment"></span>
<a name="l00115"></a>00115 <span class="comment">        template&lt;typename PFN&gt;</span>
<a name="l00116"></a>00116 <span class="comment">        AlexandrescuScopeGuard(PFN pfn) :</span>
<a name="l00117"></a>00117 <span class="comment">            mTrigger0( trigger0&lt;PFN&gt; ),</span>
<a name="l00118"></a>00118 <span class="comment">            mTrigger1(),</span>
<a name="l00119"></a>00119 <span class="comment">            mpv0(pfn),</span>
<a name="l00120"></a>00120 <span class="comment">            mpv1(),</span>
<a name="l00121"></a>00121 <span class="comment">            mDismissed()</span>
<a name="l00122"></a>00122 <span class="comment">        {}</span>
<a name="l00123"></a>00123 <span class="comment"></span>
<a name="l00124"></a>00124 <span class="comment">        template&lt;typename T, typename PMFN&gt;</span>
<a name="l00125"></a>00125 <span class="comment">        AlexandrescuScopeGuard(T &amp;t, PMFN pmfn) :</span>
<a name="l00126"></a>00126 <span class="comment">            mTrigger1( trigger1&lt;T, PMFN&gt; ),</span>
<a name="l00127"></a>00127 <span class="comment">            mpv0(&amp;t),</span>
<a name="l00128"></a>00128 <span class="comment">            mpv1( (void *) pmfn)</span>
<a name="l00129"></a>00129 <span class="comment">        {}</span>
<a name="l00130"></a>00130 <span class="comment"></span>
<a name="l00131"></a>00131 <span class="comment">        ~AlexandrescuScopeGuard()</span>
<a name="l00132"></a>00132 <span class="comment">        {</span>
<a name="l00133"></a>00133 <span class="comment">            if (!mDismissed)</span>
<a name="l00134"></a>00134 <span class="comment">            {</span>
<a name="l00135"></a>00135 <span class="comment">                try</span>
<a name="l00136"></a>00136 <span class="comment">                {</span>
<a name="l00137"></a>00137 <span class="comment">                    if (mTrigger0)</span>
<a name="l00138"></a>00138 <span class="comment">                    {</span>
<a name="l00139"></a>00139 <span class="comment">                        mTrigger0(mpv0);</span>
<a name="l00140"></a>00140 <span class="comment">                    }</span>
<a name="l00141"></a>00141 <span class="comment">                    else if (mTrigger1)</span>
<a name="l00142"></a>00142 <span class="comment">                    {</span>
<a name="l00143"></a>00143 <span class="comment">                        mTrigger1(mpv0, mpv1);</span>
<a name="l00144"></a>00144 <span class="comment">                    }</span>
<a name="l00145"></a>00145 <span class="comment">                }</span>
<a name="l00146"></a>00146 <span class="comment">                catch(...)</span>
<a name="l00147"></a>00147 <span class="comment">                {}</span>
<a name="l00148"></a>00148 <span class="comment">            }</span>
<a name="l00149"></a>00149 <span class="comment">        }</span>
<a name="l00150"></a>00150 <span class="comment"></span>
<a name="l00151"></a>00151 <span class="comment">        void dismiss()</span>
<a name="l00152"></a>00152 <span class="comment">        {</span>
<a name="l00153"></a>00153 <span class="comment">            mDismissed = true;</span>
<a name="l00154"></a>00154 <span class="comment">        }</span>
<a name="l00155"></a>00155 <span class="comment"></span>
<a name="l00156"></a>00156 <span class="comment">    private:</span>
<a name="l00157"></a>00157 <span class="comment">        bool mDismissed;</span>
<a name="l00158"></a>00158 <span class="comment">        void (*mTrigger0)(void *pv0);</span>
<a name="l00159"></a>00159 <span class="comment">        void (*mTrigger1)(void *pv0, void *pv1);</span>
<a name="l00160"></a>00160 <span class="comment">        void *mpv0;</span>
<a name="l00161"></a>00161 <span class="comment">        void *mpv1;</span>
<a name="l00162"></a>00162 <span class="comment">    };</span>
<a name="l00163"></a>00163 <span class="comment"></span>
<a name="l00164"></a>00164 <span class="comment">//#ifdef __BORLANDC__</span>
<a name="l00165"></a>00165 <span class="comment">//    typedef SharedPtrScopeGuard         ScopeGuard;</span>
<a name="l00166"></a>00166 <span class="comment">//#else</span>
<a name="l00167"></a>00167 <span class="comment">    typedef AlexandrescuScopeGuard      ScopeGuard;</span>
<a name="l00168"></a>00168 <span class="comment">//#endif</span>
<a name="l00169"></a>00169 <span class="comment">*/</span>
<a name="l00170"></a>00170 }
<a name="l00171"></a>00171 
<a name="l00172"></a>00172 <span class="preprocessor">#ifndef __BORLANDC__</span>
<a name="l00173"></a>00173 <span class="preprocessor"></span><span class="keyword">namespace </span>std {
<a name="l00174"></a>00174 <span class="preprocessor">#endif</span>
<a name="l00175"></a>00175 <span class="preprocessor"></span>
<a name="l00176"></a>00176     <span class="comment">// Trace std::vector</span>
<a name="l00177"></a>00177     <span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;
<a name="l00178"></a>00178     std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, const std::vector&lt;T&gt; &amp;v)
<a name="l00179"></a>00179     {
<a name="l00180"></a>00180         os &lt;&lt; <span class="stringliteral">"("</span>;
<a name="l00181"></a>00181         std::copy(v.begin(), v.end(), std::ostream_iterator&lt;T&gt;(os, <span class="stringliteral">", "</span>));
<a name="l00182"></a>00182         os &lt;&lt; <span class="stringliteral">")"</span>;
<a name="l00183"></a>00183         <span class="keywordflow">return</span> os;
<a name="l00184"></a>00184     }
<a name="l00185"></a>00185 
<a name="l00186"></a>00186     <span class="comment">// Trace std::deque</span>
<a name="l00187"></a>00187     <span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;
<a name="l00188"></a>00188     std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, const std::deque&lt;T&gt; &amp;d)
<a name="l00189"></a>00189     {
<a name="l00190"></a>00190         os &lt;&lt; <span class="stringliteral">"("</span>;
<a name="l00191"></a>00191         std::copy(d.begin(), d.end(), std::ostream_iterator&lt;T&gt;(os, <span class="stringliteral">", "</span>));
<a name="l00192"></a>00192         os &lt;&lt; <span class="stringliteral">")"</span>;
<a name="l00193"></a>00193         <span class="keywordflow">return</span> os;
<a name="l00194"></a>00194     }
<a name="l00195"></a>00195 
<a name="l00196"></a>00196 
<a name="l00197"></a>00197     <span class="comment">// Trace type_info</span>
<a name="l00198"></a>00198     <span class="keyword">inline</span> std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, <span class="keyword">const</span> std::type_info &amp;ti) 
<a name="l00199"></a>00199     { 
<a name="l00200"></a>00200         <span class="keywordflow">return</span> os &lt;&lt; ti.name(); 
<a name="l00201"></a>00201     }
<a name="l00202"></a>00202     
<a name="l00203"></a>00203     <span class="comment">// Trace exception</span>
<a name="l00204"></a>00204     <span class="keyword">inline</span> std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, <span class="keyword">const</span> std::exception &amp;e) 
<a name="l00205"></a>00205     { 
<a name="l00206"></a>00206         <span class="keywordflow">return</span> os &lt;&lt; <span class="stringliteral">"Type: "</span> &lt;&lt; <span class="keyword">typeid</span>(e).name() &lt;&lt; <span class="stringliteral">", What: "</span> &lt;&lt; e.what(); 
<a name="l00207"></a>00207     }
<a name="l00208"></a>00208 
<a name="l00209"></a>00209 <span class="preprocessor">#ifndef __BORLANDC__</span>
<a name="l00210"></a>00210 <span class="preprocessor"></span>} <span class="comment">// namespace std</span>
<a name="l00211"></a>00211 <span class="preprocessor">#endif</span>
<a name="l00212"></a>00212 <span class="preprocessor"></span>
<a name="l00213"></a>00213 <span class="keyword">namespace </span>RCF {
<a name="l00214"></a>00214 
<a name="l00215"></a>00215     <span class="comment">// Time in ms since ca 1970, modulo 65536 s (turns over every ~18.2 hrs).</span>
<a name="l00216"></a>00216     <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> getCurrentTimeMs();
<a name="l00217"></a>00217     
<a name="l00218"></a>00218     <span class="comment">// Generate a timeout value for the given ending time.</span>
<a name="l00219"></a>00219     <span class="comment">// Returns zero if endTime &lt;= current time &lt;= endTime+10%of timer resolution, otherwise returns a nonzero duration in ms.</span>
<a name="l00220"></a>00220     <span class="comment">// Timer resolution as above (18.2 hrs).</span>
<a name="l00221"></a>00221     <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> generateTimeoutMs(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> endTimeMs);
<a name="l00222"></a>00222 
<a name="l00223"></a>00223 } <span class="comment">// namespace RCF</span>
<a name="l00224"></a>00224 
<a name="l00225"></a>00225 <span class="preprocessor">#endif // ! INCLUDE_RCF_TOOLS_HPP</span>
</pre></div><hr size="1"><address style="align: right;"><small>Generated on Tue Sep 19 19:02:37 2006 for RCF by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.5 </small></address>
</body>
</html>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Australia Australia
Software developer, from Sweden and now living in Canberra, Australia, working on distributed C++ applications. When he is not programming, Jarl enjoys skiing and playing table tennis. He derives immense satisfaction from referring to himself in third person.

Comments and Discussions