diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2010-08-26 14:52:12 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2010-08-26 14:52:12 +0200 |
commit | 6fb470a39ef8900b71634333b0a2227dc8b62799 (patch) | |
tree | 6d782be7a2b25c3f21e9d25f7c7251bde2699994 /odb/details/win32/thread.cxx | |
parent | c883d0ba2f4450f35de6767355555fa83e6262ea (diff) |
Add support for creating other build systems (meta-building)
Add support for automake, VC++ 9, and VC++ 10. Also add the Win32 and
'NULL' threading model implementations.
Diffstat (limited to 'odb/details/win32/thread.cxx')
-rw-r--r-- | odb/details/win32/thread.cxx | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/odb/details/win32/thread.cxx b/odb/details/win32/thread.cxx new file mode 100644 index 0000000..610980d --- /dev/null +++ b/odb/details/win32/thread.cxx @@ -0,0 +1,91 @@ +// file : odb/details/win32/thread.cxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include <windows.h> +#include <process.h> // _beginthreadex, _endthreadex + +#include <memory> // std::auto_ptr + +#include <odb/details/win32/thread.hxx> +#include <odb/details/win32/exceptions.hxx> + +unsigned int __stdcall +odb_thread_thunk (void* arg) +{ + odb::details::thread::thread_thunk (arg); + _endthreadex (0); + return 0; +} + +namespace odb +{ + namespace details + { + void thread:: + thread_thunk (void* arg) + { + data* d (static_cast<data*> (arg)); + d->ret = d->func (d->arg); + d->mutex.lock (); + unsigned char count = --d->count; + d->mutex.unlock (); + + if (count == 0) + delete d; + } + + thread:: + ~thread () + { + if (handle_ != 0) + { + CloseHandle (handle_); + + // Win32 mutex implementation does not throw. + // + data_->mutex.lock (); + unsigned char count = --data_->count; + data_->mutex.unlock (); + + if (count == 0) + delete data_; + } + } + + thread:: + thread (void* (*func) (void*), void* arg) + { + std::auto_ptr<data> d (new data); + d->func = func; + d->arg = arg; + d->count = 2; // One for the thread and one for us. + + handle_ = (HANDLE)_beginthreadex ( + 0, 0, &odb_thread_thunk, d.get (), 0, 0); + + if (handle_ == 0) + throw win32_exception (); + + data_ = d.release (); + } + + void* thread:: + join () + { + void* r; + + if (WaitForSingleObject (handle_, INFINITE) != 0) + throw win32_exception (); + + r = data_->ret; + + CloseHandle (handle_); + delete data_; + handle_ = 0; + data_ = 0; + return r; + } + } +} |