Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Create a simple message passing program in C++ for a UNIX environment utilizing

ID: 665603 • Letter: C

Question

Create a simple message passing program in C++ for a UNIX environment utilizing a circular buffer.

http://wiki.osdev.org/Message_Passing_Tutorial

Create a one-directional circular buffer (ring) of pipes for N processes (N>=1)

Create a one-directional circular buffer (ring) of pipe for N threads

Create a one-directional cicular buffer (ring) of socket for N hosts (or all in one)

You may run N processes in one host.

                        Each process has two designated ports - one for sending and the other for receiving.

                        Each program for each process will be run with an argument telling which process (Nth process)

                        You may assume that each process has a table of process with 2 ports as following:

Process i

IP address

Port# to send

Port# to receive

0

127.0.0.1

9000

9001

1

127.0.0.1

9100

9101

2

127.0.0.1

9200

9201

and so on

When N processes (or threads) in a ring are up and ready, Process 0 sends a message to be received by Process 1, and so on, to back to Process 0 and done. Whenever a process sends or receives a message, it prints its process # (N), "the message", and "sent" or "received".

Process i

IP address

Port# to send

Port# to receive

0

127.0.0.1

9000

9001

1

127.0.0.1

9100

9101

2

127.0.0.1

9200

9201

and so on

Explanation / Answer

#ifndef DMP_HPP
#define DMP_HPP


#include <stdexcept>
#include <boost/unordered_map.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/preprocessor.hpp>


namespace dmp {


class object;


#define DMP_PP_MAX_PARAMS()            9
#define DMP_PP_TYPENAME                class T
#define DMP_PP_TYPE                    T
#define DMP_PP_ARG                     t


namespace detail {


//define message
#define DMP_PP_MESSAGE_N(Z, N, DATA)
        template <class R BOOST_PP_ENUM_TRAILING_PARAMS(N, DMP_PP_TYPENAME)> class message##N :
            public message
    {
        public:
            virtual R invoke(object *obj BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, DMP_PP_TYPE, DMP_PP_ARG)) const = 0;
        };


//define method
#define DMP_PP_METHOD_N(Z, N, DATA)
    template <class R, class C BOOST_PP_ENUM_TRAILING_PARAMS(N, DMP_PP_TYPENAME)> class method##N :
        public message##N<R BOOST_PP_ENUM_TRAILING_PARAMS(N, DMP_PP_TYPE)>
    {
    public:
        typedef R (C::*method)(BOOST_PP_ENUM_PARAMS(N, DMP_PP_TYPE));
        method##N(method mtd) : m_method(mtd) {
        }
        virtual R invoke(object *obj BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, DMP_PP_TYPE, DMP_PP_ARG)) const {
            return (static_cast<C *>(obj)->*m_method)(BOOST_PP_ENUM_PARAMS(N, DMP_PP_ARG));
        }
    private:
        method m_method;
    };


//define message const
#define DMP_PP_MESSAGE_CONST_N(Z, N, DATA)
        template <class R BOOST_PP_ENUM_TRAILING_PARAMS(N, DMP_PP_TYPENAME)> class message_const##N :
            public message
    {
        public:
            virtual R invoke(const object *obj BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, DMP_PP_TYPE, DMP_PP_ARG)) const = 0;
        };


//define const method
#define DMP_PP_METHOD_CONST_N(Z, N, DATA)
    template <class R, class C BOOST_PP_ENUM_TRAILING_PARAMS(N, DMP_PP_TYPENAME)> class method_const##N :
        public message_const##N<R BOOST_PP_ENUM_TRAILING_PARAMS(N, DMP_PP_TYPE)>
    {
    public:
        typedef R (C::*method)(BOOST_PP_ENUM_PARAMS(N, DMP_PP_TYPE)) const;
        method_const##N(method mtd) : m_method(mtd) {
        }
        virtual R invoke(const object *obj BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, DMP_PP_TYPE, DMP_PP_ARG)) const {
            return (static_cast<const C *>(obj)->*m_method)(BOOST_PP_ENUM_PARAMS(N, DMP_PP_ARG));
        }
    private:
        method m_method;
    };


//base class for messages
class message {
public:
    //dtor
    virtual ~message() {
    }
};


BOOST_PP_REPEAT(DMP_PP_MAX_PARAMS(), DMP_PP_MESSAGE_N, BOOST_PP_EMPTY)
BOOST_PP_REPEAT(DMP_PP_MAX_PARAMS(), DMP_PP_METHOD_N, BOOST_PP_EMPTY)
BOOST_PP_REPEAT(DMP_PP_MAX_PARAMS(), DMP_PP_MESSAGE_CONST_N, BOOST_PP_EMPTY)
BOOST_PP_REPEAT(DMP_PP_MAX_PARAMS(), DMP_PP_METHOD_CONST_N, BOOST_PP_EMPTY)


//a pointer to a message
typedef boost::shared_ptr<message> message_ptr;


//a dynamic message map
typedef boost::unordered_map<void *, message_ptr> message_map;


//message map ptr
typedef boost::shared_ptr<message_map> message_map_ptr;


} //namespace detail


//define the invoke function
#define DMP_PP_INVOKE(Z, N, DATA)
    template <class R BOOST_PP_ENUM_TRAILING_PARAMS(N, DMP_PP_TYPENAME)> R invoke(R (*sig)(BOOST_PP_ENUM_PARAMS(N, DMP_PP_TYPE)) BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, DMP_PP_TYPE, DMP_PP_ARG)) {
        detail::message_map::iterator it = m_messages->find(sig);
        if (it == m_messages->end()) throw message_not_understood();
        return static_cast<detail::message##N<R BOOST_PP_ENUM_TRAILING_PARAMS(N, DMP_PP_TYPE)> *>(it->second.get())->invoke(this BOOST_PP_ENUM_TRAILING_PARAMS(N, DMP_PP_ARG));
    }

  
//define the adds message implementation function
#define DMP_PP_ADD_MESSAGE(Z, N, DATA)
    template <class R, class C BOOST_PP_ENUM_TRAILING_PARAMS(N, DMP_PP_TYPENAME)> void add_message(R (*sig)(BOOST_PP_ENUM_PARAMS(N, DMP_PP_TYPE)), R (C::*mtd)(BOOST_PP_ENUM_PARAMS(N, DMP_PP_TYPE))) {
        static_cast<C *>(this);
        _add_message(sig, detail::message_ptr(new detail::method##N<R, C BOOST_PP_ENUM_TRAILING_PARAMS(N, DMP_PP_TYPE)>(mtd)));
    }


//define the invoke const function
#define DMP_PP_INVOKE_CONST(Z, N, DATA)
    template <class R BOOST_PP_ENUM_TRAILING_PARAMS(N, DMP_PP_TYPENAME)> R invoke(R (*sig)(BOOST_PP_ENUM_PARAMS(N, DMP_PP_TYPE)) BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, DMP_PP_TYPE, DMP_PP_ARG)) const {
        detail::message_map::const_iterator it = m_messages->find(sig);
        if (it == m_messages->end()) throw message_not_understood();
        return static_cast<detail::message_const##N<R BOOST_PP_ENUM_TRAILING_PARAMS(N, DMP_PP_TYPE)> *>(it->second.get())->invoke(this BOOST_PP_ENUM_TRAILING_PARAMS(N, DMP_PP_ARG));
    }

  
//define the adds const message implementation function
#define DMP_PP_ADD_MESSAGE_CONST(Z, N, DATA)
    template <class R, class C BOOST_PP_ENUM_TRAILING_PARAMS(N, DMP_PP_TYPENAME)> void add_message(R (*sig)(BOOST_PP_ENUM_PARAMS(N, DMP_PP_TYPE)), R (C::*mtd)(BOOST_PP_ENUM_PARAMS(N, DMP_PP_TYPE)) const) {
        static_cast<const C *>(this);
        _add_message(sig, detail::message_ptr(new detail::method_const##N<R, C BOOST_PP_ENUM_TRAILING_PARAMS(N, DMP_PP_TYPE)>(mtd)));
    }


//exception thrown when a message is not understood
class message_not_understood : public std::exception {
public:
    //the default ctor
    message_not_understood(const char *msg = "message not understood") : std::exception(msg) {
    }
};


//base class for objects that support dynamic message passing;
//uses copy-on-write for the message map
class object {
public:
    //the default ctor; it creates an empty msg map
    object() : m_messages(new detail::message_map) {
    }
  
    //the copy ctor: shallow copy of the message map
    object(const object &o) : m_messages(o.m_messages) {
    }
  
    //the ctor from a specific message map
    object(const detail::message_map_ptr &mp) : m_messages(mp) {
    }
  
    //destructor
    ~object() {
    }
  
    //the message map is not copied
    object &operator = (const object &o) {
        return *this;
    }
  
    //do message
    BOOST_PP_REPEAT(DMP_PP_MAX_PARAMS(), DMP_PP_INVOKE, BOOST_PP_EMPTY)
    BOOST_PP_REPEAT(DMP_PP_MAX_PARAMS(), DMP_PP_INVOKE_CONST, BOOST_PP_EMPTY)
  
protected:
    //add message
    BOOST_PP_REPEAT(DMP_PP_MAX_PARAMS(), DMP_PP_ADD_MESSAGE, BOOST_PP_EMPTY)  
    BOOST_PP_REPEAT(DMP_PP_MAX_PARAMS(), DMP_PP_ADD_MESSAGE_CONST, BOOST_PP_EMPTY)  

private:
    //message map
    detail::message_map_ptr m_messages;
  
    //add message
    void _add_message(void *sig, const detail::message_ptr &msg) {
        if (!m_messages.unique()) m_messages = detail::message_map_ptr(new detail::message_map(*m_messages.get()));
        (*m_messages)[sig] = msg;
    }
};


} //namespace dmp


#endif //DMP_HPP

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote