Click here to Skip to main content
15,893,381 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.
//*****************************************************************************
// RCF - Remote Call Framework
// Copyright (c) 2005. All rights reserved.
// Developed by Jarl Lindrud.
// Contact: jlindrud@hotmail.com .
//*****************************************************************************

#ifndef INCLUDE_RCF_TOOLS_HPP
#define INCLUDE_RCF_TOOLS_HPP

// Various utilities

#include <time.h>

#include <deque>
#include <iostream>
#include <iterator>
#include <memory>
#include <stdexcept>
#include <typeinfo>
#include <vector>

#include <boost/bind.hpp>
#include <boost/current_function.hpp>
#include <boost/function.hpp>
#include <boost/noncopyable.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>

#include <RCF/Exception.hpp>
#include <RCF/ScopeGuard.h>
#include <RCF/ThreadLibrary.hpp>
#include <RCF/util/Meta.hpp>
#include <RCF/util/UnusedVariable.hpp>

// Assertion mechanism
#include <RCF/util/Assert.hpp>
#define RCF_ASSERT(x) UTIL_ASSERT(x, RCF::AssertionFailureException)

// Verification mechanism
#include <RCF/util/Throw.hpp>
#define RCF_VERIFY(x, msg) UTIL_VERIFY(x, RCF::VerificationFailureException, msg)

// Trace mechanism
#include <RCF/util/Trace.hpp>
//#define RCF_TRACE(x) DUMMY_VARIABLE_ARG_MACRO()
#define RCF_TRACE(x)  UTIL_TRACE(x, (*::RCF::pTraceChannels[0]))
#define RCF1_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[1]))
#define RCF2_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[2]))
#define RCF3_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[3]))
#define RCF4_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[4]))
#define RCF5_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[5]))
#define RCF6_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[6]))
#define RCF7_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[7]))
#define RCF8_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[8]))
#define RCF9_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[9]))

namespace RCF {
    extern util::TraceChannel *pTraceChannels[10];
}

// Throw mechanism
#include <RCF/util/Throw.hpp>
#define RCF_THROW UTIL_THROW

// Scope guard mechanism
namespace RCF {

    class SharedPtrScopeGuard : boost::noncopyable
    {
    public:
        template<typename T>
        SharedPtrScopeGuard(T &t) : 
            spv(static_cast<void*>(NULL), t)
        {}

        template<typename T, typename R>
        SharedPtrScopeGuard(T &t, R (T::*pfn)() ) : 
            spv(static_cast<void*>(NULL), boost::bind(pfn, &t))
        {}

        template<typename T, typename R, typename A>
        SharedPtrScopeGuard(T &t, R (T::*pfn)(A), A a) : 
            spv(static_cast<void*>(NULL), boost::bind(pfn, &t, a))
        {}

        void dismiss()
        {
            spv.reset();
        }

    private:
        boost::shared_ptr<void> spv;
    };
/*
    template<typename PFN>
    void trigger0(void *pv)
    {
        ((PFN) pv)();
    }

    template<typename T, typename PMFN>
    void trigger1(void *pvt, void *pvmfn)
    {
        PMFN pmfn = (PMFN) pvmfn;
        T *pt = (T *) pvt;
        pt->*pmfn();
    }
  
    class AlexandrescuScopeGuard
    {
    public:

        template<typename PFN>
        AlexandrescuScopeGuard(PFN pfn) :
            mTrigger0( trigger0<PFN> ),
            mTrigger1(),
            mpv0(pfn),
            mpv1(),
            mDismissed()
        {}

        template<typename T, typename PMFN>
        AlexandrescuScopeGuard(T &t, PMFN pmfn) :
            mTrigger1( trigger1<T, PMFN> ),
            mpv0(&t),
            mpv1( (void *) pmfn)
        {}

        ~AlexandrescuScopeGuard()
        {
            if (!mDismissed)
            {
                try
                {
                    if (mTrigger0)
                    {
                        mTrigger0(mpv0);
                    }
                    else if (mTrigger1)
                    {
                        mTrigger1(mpv0, mpv1);
                    }
                }
                catch(...)
                {}
            }
        }

        void dismiss()
        {
            mDismissed = true;
        }

    private:
        bool mDismissed;
        void (*mTrigger0)(void *pv0);
        void (*mTrigger1)(void *pv0, void *pv1);
        void *mpv0;
        void *mpv1;
    };

//#ifdef __BORLANDC__
//    typedef SharedPtrScopeGuard         ScopeGuard;
//#else
    typedef AlexandrescuScopeGuard      ScopeGuard;
//#endif
*/
}

#ifndef __BORLANDC__
namespace std {
#endif

    // Trace std::vector
    template<typename T>
    std::ostream &operator<<(std::ostream &os, const std::vector<T> &v)
    {
        os << "(";
        std::copy(v.begin(), v.end(), std::ostream_iterator<T>(os, ", "));
        os << ")";
        return os;
    }

    // Trace std::deque
    template<typename T>
    std::ostream &operator<<(std::ostream &os, const std::deque<T> &d)
    {
        os << "(";
        std::copy(d.begin(), d.end(), std::ostream_iterator<T>(os, ", "));
        os << ")";
        return os;
    }


    // Trace type_info
    inline std::ostream &operator<<(std::ostream &os, const std::type_info &ti) 
    { 
        return os << ti.name(); 
    }
    
    // Trace exception
    inline std::ostream &operator<<(std::ostream &os, const std::exception &e) 
    { 
        return os << "Type: " << typeid(e).name() << ", What: " << e.what(); 
    }

#ifndef __BORLANDC__
} // namespace std
#endif

namespace RCF {

    // Time in ms since ca 1970, modulo 65536 s (turns over every ~18.2 hrs).
    unsigned int getCurrentTimeMs();
    
    // Generate a timeout value for the given ending time.
    // Returns zero if endTime <= current time <= endTime+10%of timer resolution, otherwise returns a nonzero duration in ms.
    // Timer resolution as above (18.2 hrs).
    unsigned int generateTimeoutMs(unsigned int endTimeMs);

} // namespace RCF

#endif // ! INCLUDE_RCF_TOOLS_HPP

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