Boost logo

Boost :

From: vicente.botet (vicente.botet_at_[hidden])
Date: 2008-04-28 16:41:03


Hi,

I'm starting a library providing synchronized execution of objects,
something like Ada 'rendez-vous'.

A component Sender may request execution of a member function of a
concurrent component Reveiver. The component Receiver must accept that the
request can be fulfilled. Synchronized communication is described in a
generic class concurrent_component. A concurrent_component defines the
notion of a port for controlling the communication. A port has a nested
entry class for defining operations controlled by the port; it also has an
accept operation for signaling that an operation associated with the port
can be executed.

The concurrent_component and port classes interface will be the following:

struct concurrent_component {
    class port {
      public:
        class entry_synchronizer {
        public:
            entry_synchronizer(port&);
            ~entry_synchronizer();
        };
        static void accept(port& p);
    };
};

In the following example, two concurrent components prod (Producer) and cons
(Consumer) communicate via a single element buffer represented by a buf
(SingleBuffer) concurrent component. The SingleBuffer class alternates
between accepting a Push and a Pull:

class SingleBuffer : concurrent_component {
    port PutPort_;
    port GetPort_;
    char bufCh_;
public:
    void Put(char ch) {
        port::entry_synchronizer _(PutPort_);
        bufCh_ = ch;
    }
    char Get() {
        port::entry_synchronizer _(GetPort_);
        return bufCh_;
    }
    void operator()() {
        for(;;) {
            port::accept(PutPort_);
            port::accept(GetPort_);
        }
    }
};
struct Producer : concurrent_component {
    SingleBuf& buf_;
    Producer(SingleBuf& buf) : buf_(buf) {}
    void operator()()
    {
        for(;;) {
            char ch;
            std::cin >> ch;
            buf_.Put(ch);
        }
    }
};
struct Consumer : concurrent_component {
    SingleBuf& buf_;
    Consumer(SingleBuf& buf) : buf_(buf) {}
    void operator()() {
        for(;;) {
            char ch = buf_.Get();
            std::cout << ch << std::endl;
        }
    }
};

concurrent_component defines also a template class concurrent_execution<n>
which is used to group the concurrent execution of n concurrent components.

int main()
{
    SingleBuffer buf;
    Producer prod(buf);
    Consumer cons(buf);
    concurrent_execution<3> conc(buf, prod, cons);
    conc.join_all();
    return 0;
}

Other kind of ports can also be defined to restrict the instances that can
do a request:
* object_port which only accepts request from a given instance, or
* qualified_port which only accepts request from instances of a given class.

These classes can be extended allowing concurrent_component to open more
that one port at the same time, and wait until all ports have been
requested.

    class port {
      public:
        port(concurrent_component&);
        class entry_synchronizer {
        public:
            entry_synchronizer(port&);
            ~entry_synchronizer();
        };
        static void accept(port&);
        static void accept_all(port& p1, ..., port& pn);
    };

Do you think that this concurrent_component library could have a place in
Boost?

Best regards
_____________________
Vicente Juan Botet Escriba


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk