\r
#include "executor.h"\r
\r
+#include "../log/log.h"\r
+#include "../exception/exceptions.h"\r
+\r
+#define NOMINMAX\r
+#define WIN32_LEAN_AND_MEAN\r
+\r
#include <Windows.h>\r
\r
#include <boost/noncopyable.hpp>\r
+#include <boost/thread/future.hpp>\r
\r
#include <functional>\r
\r
\r
~com_context()\r
{\r
- executor::invoke([&]\r
+ if(!executor::begin_invoke([&]\r
{\r
instance_.reset(nullptr);\r
::CoUninitialize();\r
- });\r
+ }).timed_wait(boost::posix_time::milliseconds(500)))\r
+ {\r
+ CASPAR_LOG(error) << L"[com_contex] Timer expired, deadlock detected and released, leaking resources.";\r
+ }\r
}\r
\r
- void reset(const std::function<T*()>& factory)\r
+ void reset(const std::function<T*()>& factory = nullptr)\r
{\r
executor::invoke([&]\r
{\r
+ instance_.reset();\r
if(factory)\r
instance_.reset(factory());\r
- else\r
- instance_.reset(nullptr);\r
});\r
}\r
\r
- T& operator*() const { return *instance_.get();} // noexcept\r
+ T& operator*() const \r
+ {\r
+ if(instance_ == nullptr)\r
+ BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Tried to access null context."));\r
+\r
+ return *instance_.get();\r
+ } // noexcept\r
\r
- T* operator->() const { return instance_.get();} // noexcept\r
+ T* operator->() const \r
+ {\r
+ if(instance_ == nullptr)\r
+ BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Tried to access null context."));\r
+ return instance_.get();\r
+ } // noexcept\r
\r
- T* get() const { return instance_.get();} // noexcept\r
+ T* get() const\r
+ {\r
+ return instance_.get();\r
+ } // noexcept\r
\r
operator bool() const {return get() != nullptr;}\r
};\r