Click here to Skip to main content
15,891,136 members
Articles / Programming Languages / C++

Cross thread calls in native C++

Rate me:
Please Sign up or sign in to vote.
4.85/5 (38 votes)
19 Jul 2007Apache20 min read 117.9K   1.2K   96  
An article which discusses the need for synchronization in multi-threaded applications, and features a generic framework for making calls across threads: ThreadSynch.
/************************************************************************
** Copyright 2007 Einar Otto Stangvik
** 
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** 
**    http://www.apache.org/licenses/LICENSE-2.0
** 
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

#pragma once

namespace ThreadSynch
{
    /*!@class FunctorRetvalBinder 
    ** @brief A helper functor and return value class.
    ** A helper class which stores the call functor, and attempts to
    ** grab the return value after a successful call. CallHandler
    ** cannot be templated without major pain in the rest of the code,
    ** so this templated type does the work.
    */
    template<typename T>
    class FunctorRetvalBinder
    {
    public:
        /************************************************************************
        ** Functions
        */

        FunctorRetvalBinder(boost::function<T()> functor, BYTE* pReturnValueBuffer)
            : m_functor(functor),
              m_pReturnValueBuffer(pReturnValueBuffer)
        {}

        FunctorRetvalBinder(boost::function<void()> functor)
            : m_functor(functor),
              m_pReturnValueBuffer(NULL)
        {}

        ~FunctorRetvalBinder();

        /*! 
        ** @brief executes the callback.
        ** @remark 
        **   This function has one variation for T which are non-void,
        **   in which case the return value is saved at the address passed to
        **   the constructor. For T which is void, the return value is
        **   obviously not stored -- or rather, there is no return value.
        */
        inline void execute();

        /*! 
        ** @brief releases any resources currently held by an FunctorRetvalBinder
        **   instance, and deletes the instance itself.
        */
        inline void free()
        { delete this; }

    private:
        /************************************************************************
        ** Variables
        */

        boost::function<T(void)> m_functor;
        BYTE* m_pReturnValueBuffer;
    };

    /************************************************************************
    ** Implementation of non-inline and specialized template member functions
    */

    template<typename T>
    FunctorRetvalBinder<T>::~FunctorRetvalBinder()
    {
        // Destroy the bound return value
        reinterpret_cast<T*>(m_pReturnValueBuffer)->~T();
    }

    template<>
    FunctorRetvalBinder<void>::~FunctorRetvalBinder()
    {
    }

    template<typename T>
    void FunctorRetvalBinder<T>::execute()
    {
        // Copy-construct the object into the allocated buffer, from the return 
        // value of the functor. 
        // The copy constructor of T is as such a requirement for the mechanism to work.
        new (m_pReturnValueBuffer) T(m_functor());
    }

    template<>
    void FunctorRetvalBinder<void>::execute()
    {
        m_functor();
    }
}

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 Apache License, Version 2.0


Written By
Software Developer
Norway Norway
My name is Einar Otto Stangvik, and I'm a programmer based in Oslo, Norway. I mainly develop applications and software architectures targetting C++ on the Windows platform, but I have also got experience doing the same on Unix and Linux. The last few years I've used C# a lot, but native C++ is still my main focus.


As of July 2008, I'm a Microsoft MVP for Visual C++.


Follow me on Twitter: @einaros
My code blog: einaros.blogspot.com
My site: www.indev.no

Comments and Discussions