My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
Examples  
Shows a few common uses of the library.
Featured
Updated Feb 4, 2010 by eina...@gmail.com

Examples

To obtain an instance of the scheduler, using the included APCPickupPolicy:

The WMPickupPoilcy will notify the target thread through use of UserAPCs, granted that the target enters alertable wait before the specified call timeout runs out.
    CallScheduler<APCPickupPolicy>* scheduler = 
        CallScheduler<APCPickupPolicy>::getInstance();
There's an example of this in the demo project.

To obtain an instance of the scheduler, using the included WMPickupPolicy:

The WMPickupPoilcy will notify the target thread through a user defined window message.
    typedef WMPickupPolicy<WM_USER + 1> WMPickup;
    CallScheduler<WMPickup>* scheduler = 
        CallScheduler<WMPickup>::getInstance();
The template parameter passed to WMPickupPolicy indicates which message to post to the thread. The receiving thread should deal with this message code in its message loop, such as:
    while(GetMessage(&msg, NULL, 0, 0)) 
    { 
        if(msg.message == WMPickup::WM_PICKUP)
        {
            WMPickup::executeCallback(msg.wParam, msg.lParam);
            continue;
        }

        TranslateMessage(&msg);
        DispatchMessage(&msg);
    } 
There's an example of this in the attached ThreadSynchWM project.

To cross-call a function through another thread:

    scheduler->syncCall(dwThreadId, function, timeoutInMS);

To cross-call a class member function which returnins an int, with a const string reference for parameter:

    // Class in which our target function resides
    MyClass classInstance;

    // String parameter
    string myString = "hello world";

    // Init functor
    boost::function<int(const string&)> myFunctor = 
        boost::bind(&MyClass::someFunction,     // Function
                    &classInstance,             // Instance
                    boost::ref(myString));      // Parameter
        
    // Make the call
    // The return value template specification can be ommited
    // in this case, as it's also deduced from the boost functor.
    // I've included it here to show how it can be specified,
    // and how it must be specified if mere function pointers
    // are used in place of the functors.
    int x = scheduler->syncCall
        <
            int            // Return type.
        >
        (
            dwThreadId,    // Target thread
            myFunctor,     // Functor to call from target thread
            timeoutInMS    // Number of milliseconds to wait 
                           // for the call to begin
        );

To cross-call a class member function which returns a string, with a const string reference for parameter, and expect a few exceptions might be thrown:

    // Class in which our target function resides
    MyClass classInstance;

    // String parameter

    string myString = "hello world";

    // String for the return value
    string myReturnedString;

    try
    {
        // Init functor
        boost::function<string(const string&)> myFunctor = 
            boost::bind(&MyClass::someFunction,    // Function
                        &classInstance,            // Instance
                        boost::ref(myString));     // Parameter
        
        // Make the call
        myReturnedString = scheduler->syncCall
            <
                string,        // Return type
                ExceptionTypes<std::exception, MyException>
            >
            (
                dwThreadId,    // Target thread
                myFunctor,     // Functor to call from target thread
                timeoutInMS    // Number of milliseconds to 
                               // wait for the call to begin
            );
    }
    catch(CallTimeoutException&)
    {
        // The call timed out, do some other stuff and try again
    }
    catch(CallSchedulingFailedException&)
    {
        // The call scheduling failed, 
        // probably caused by the pickup policy not doing its job
    }
    catch(std::exception& e)
    {
        // Deal with e
    }
    catch(MyException& e)
    {
        // Deal with e
    }
    catch(UnexpectedException&)
    {
        // We didn't expect this one. 
        // It's time to read someFunction's docs.
    }
You obviously won't have to catch all these exceptions all the time, but if you feel like it, you may. It's up to you, really. Whether or not you want an exception-safe application, that is.

In most cases, you will want to have a function re-call itself in context of the function's "owner thread", rather than call specific functions such as shown above. The ThreadSynchTestWM example attached shows how to do this in the updateText function.


Sign in to add a comment
Powered by Google Project Hosting