imgtools/imglib/boostlibrary/boost/thread/win32/once.hpp
author Richard Taylor <richard.i.taylor@nokia.com>
Tue, 23 Feb 2010 13:15:31 +0000
changeset 244 aba9fdf7e825
parent 0 044383f39525
permissions -rw-r--r--
Added tag stable for changeset 007900c31eef
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     1
#ifndef BOOST_THREAD_WIN32_ONCE_HPP
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     2
#define BOOST_THREAD_WIN32_ONCE_HPP
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     3
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     4
//  once.hpp
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     5
//
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     6
//  (C) Copyright 2005-7 Anthony Williams 
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     7
//  (C) Copyright 2005 John Maddock
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     8
//
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     9
//  Distributed under the Boost Software License, Version 1.0. (See
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    10
//  accompanying file LICENSE_1_0.txt or copy at
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    11
//  http://www.boost.org/LICENSE_1_0.txt)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    12
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    13
#include <cstring>
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    14
#include <cstddef>
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    15
#include <boost/assert.hpp>
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    16
#include <boost/static_assert.hpp>
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    17
#include <boost/detail/interlocked.hpp>
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    18
#include <boost/thread/win32/thread_primitives.hpp>
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    19
#include <boost/thread/win32/interlocked_read.hpp>
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    20
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    21
#include <boost/config/abi_prefix.hpp>
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    22
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    23
#ifdef BOOST_NO_STDC_NAMESPACE
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    24
namespace std
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    25
{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    26
    using ::memcpy;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    27
    using ::ptrdiff_t;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    28
}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    29
#endif
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    30
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    31
namespace boost
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    32
{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    33
    typedef long once_flag;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    34
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    35
#define BOOST_ONCE_INIT 0
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    36
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    37
    namespace detail
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    38
    {
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    39
        struct win32_mutex_scoped_lock
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    40
        {
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    41
            void* const mutex_handle;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    42
            explicit win32_mutex_scoped_lock(void* mutex_handle_):
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    43
                mutex_handle(mutex_handle_)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    44
            {
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    45
                BOOST_VERIFY(!win32::WaitForSingleObject(mutex_handle,win32::infinite));
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    46
            }
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    47
            ~win32_mutex_scoped_lock()
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    48
            {
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    49
                BOOST_VERIFY(win32::ReleaseMutex(mutex_handle)!=0);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    50
            }
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    51
        private:
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    52
            void operator=(win32_mutex_scoped_lock&);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    53
        };
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    54
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    55
#ifdef BOOST_NO_ANSI_APIS
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    56
        template <class I>
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    57
        void int_to_string(I p, wchar_t* buf)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    58
        {
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    59
            for(unsigned i=0; i < sizeof(I)*2; ++i,++buf)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    60
            {
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    61
                *buf = L'A' + static_cast<wchar_t>((p >> (i*4)) & 0x0f);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    62
            }
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    63
            *buf = 0;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    64
        }
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    65
#else
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    66
        template <class I>
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    67
        void int_to_string(I p, char* buf)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    68
        {
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    69
            for(unsigned i=0; i < sizeof(I)*2; ++i,++buf)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    70
            {
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    71
                *buf = 'A' + static_cast<char>((p >> (i*4)) & 0x0f);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    72
            }
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    73
            *buf = 0;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    74
        }
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    75
#endif
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    76
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    77
        // create a named mutex. It doesn't really matter what this name is
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    78
        // as long as it is unique both to this process, and to the address of "flag":
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    79
        inline void* create_once_mutex(void* flag_address)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    80
        {
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    81
        
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    82
#ifdef BOOST_NO_ANSI_APIS
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    83
            typedef wchar_t char_type;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    84
            static const char_type fixed_mutex_name[]=L"{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    85
#else
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    86
            typedef char char_type;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    87
            static const char_type fixed_mutex_name[]="{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    88
#endif
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    89
            unsigned const once_mutex_name_fixed_buffer_size=sizeof(fixed_mutex_name)/sizeof(char_type);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    90
            unsigned const once_mutex_name_fixed_length=once_mutex_name_fixed_buffer_size-1;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    91
            unsigned const once_mutex_name_length=once_mutex_name_fixed_buffer_size+sizeof(void*)*2+sizeof(unsigned long)*2;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    92
            char_type mutex_name[once_mutex_name_length];
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    93
            
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    94
            std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name));
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    95
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    96
            BOOST_STATIC_ASSERT(sizeof(void*) == sizeof(std::ptrdiff_t));
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    97
            detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address), mutex_name + once_mutex_name_fixed_length);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    98
            detail::int_to_string(win32::GetCurrentProcessId(), mutex_name + once_mutex_name_fixed_length + sizeof(void*)*2);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    99
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   100
#ifdef BOOST_NO_ANSI_APIS
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   101
            return win32::CreateMutexW(0, 0, mutex_name);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   102
#else
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   103
            return win32::CreateMutexA(0, 0, mutex_name);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   104
#endif
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   105
        }
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   106
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   107
        
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   108
    }
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   109
    
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   110
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   111
    template<typename Function>
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   112
    void call_once(once_flag& flag,Function f)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   113
    {
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   114
        // Try for a quick win: if the procedure has already been called
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   115
        // just skip through:
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   116
        long const function_complete_flag_value=0xc15730e2;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   117
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   118
        if(::boost::detail::interlocked_read_acquire(&flag)!=function_complete_flag_value)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   119
        {
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   120
            void* const mutex_handle(::boost::detail::create_once_mutex(&flag));
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   121
            BOOST_ASSERT(mutex_handle);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   122
            detail::win32::handle_manager const closer(mutex_handle);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   123
            detail::win32_mutex_scoped_lock const lock(mutex_handle);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   124
      
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   125
            if(flag!=function_complete_flag_value)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   126
            {
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   127
                f();
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   128
                BOOST_INTERLOCKED_EXCHANGE(&flag,function_complete_flag_value);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   129
            }
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   130
        }
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   131
    }
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   132
}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   133
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   134
#include <boost/config/abi_suffix.hpp>
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   135
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   136
#endif