C++ make_xscope_asyncsharedv2acoreadwrite() in SaferCPlusPlus














































C++ make_xscope_asyncsharedv2acoreadwrite() in SaferCPlusPlus



C++ make_xscope_asyncsharedv2acoreadwrite()

in SaferCPlusPlus


The function used to obtain a (scope) access requester to an access-controlled scope object is make_xscope_asyncsharedv2acoreadwrite(). Note that it takes as its argument a scope pointer to the access-controlled object, not a scope pointer to the contained object. Btw, scope access requesters are an example of an object type that can be passed to other scope threads, but does not qualify (i.e. would induce a compile error) to be passed to non-scope threads.

Code:


#include "mseasyncshared.h"
#include "msescope.h"
#include "msemsestring.h"
#include <iostream>
#include <ctime>
#include <ratio>
#include <chrono>
#include <list>

class J {
public:
    template<class _TAsyncSharedReadWriteAccessRequester>
    static double foo7(_TAsyncSharedReadWriteAccessRequester A_ashar) {
        auto t1 = std::chrono::high_resolution_clock::now();
        /* A_ashar.readlock_ptr() will block until it can obtain a read lock. */
        auto ptr1 = A_ashar.readlock_ptr(); // while ptr1 exists it holds a (read) lock on the
shared object
        auto t2 = std::chrono::high_resolution_clock::now();
        std::this_thread::sleep_for(std::chrono::seconds(1));
        auto time_span = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1);
        auto timespan_in_seconds = time_span.count();
        auto thread_id = std::this_thread::get_id();
        //std::cout << "thread_id: " << thread_id << ", time to acquire read pointer: " <<
timespan_in_seconds << " seconds.";
        //std::cout << std::endl;
        return timespan_in_seconds;
    }
};

void main(int argc, char* argv[]) {

    /* Here we demonstrate safely sharing an existing stack allocated object among threads. */

    class A {
    public:
        A(int x) : b(x) {}
        virtual ~A() {}

        int b = 3;
        mse::nii_string s = "some text ";
    };
    /* User-defined classes need to be declared as (safely) shareable in order to be accepted
by the access requesters. */
    typedef mse::rsv::TAsyncShareableAndPassableObj<A> ShareableA;

    std::cout << ": xscope_future_carrier<>";
    std::cout << std::endl;

    /* (Mutable) objects can be shared between threads only if they are "access controlled".
You can make an object "access controlled" by wrapping its type with the
mse::TXScopeAccessControlledObj<> template wrapper. */
    mse::TXScopeObj<mse::TXScopeAccessControlledObj<ShareableA> > a_xscpacobj(7);

    /* Here we obtain a scope access requester for the access controlled object. */
    auto xscope_access_requester = mse::make_xscope_asyncsharedv2acoreadwrite(&a_xscpacobj);

    /* xscope_future_carrier<> is just a container that holds and manages scope futures. */
    mse::xscope_future_carrier<double> xscope_futures;

    std::list<mse::xscope_future_carrier<double>::handle_t> future_handles;
    for (size_t i = 0; i < 3; i += 1) {
        /* You add a future by specifying the async() function and parameters that will return
the future value. */
        auto handle = xscope_futures.new_future(J::foo7<decltype(xscope_access_requester)>,
xscope_access_requester);

        /* You need to store the handle of the added future in order to later retrieve its
value. */
        future_handles.emplace_back(handle);
    }
    int count = 1;
    for (auto it = future_handles.begin(); future_handles.end() != it; it++, count++) {
        std::cout << "thread: " << count << ", time to acquire read pointer: " <<
xscope_futures.xscope_ptr_at(*it)->get() << " seconds.";
        std::cout << std::endl;
    }
    std::cout << std::endl;
}

Comments