C++/CLI is known to block the mutex header when a project is compiled using the -clr:pure or clr flag.
The error is reported here
https://social.msdn.microsoft.com/Forums/vstudio/en-US/d4d082ff-ce43-478d-8386-0effed04b108/ccli-and-stdmutex?forum=vclanguage
The recommended solution seems to be to use the pimpI pattern. See here
Turn off clr option for header file with std::mutex
The problem I see is when using other std functions.
For example consider the std::condition_variable
mutexPimpI _mut;
std::unique_lock<mutexPimpI> lk(_mut); //Fine std::unique_lock is templated.
std::condition_variable _gate1;
_gate1.wait(lk); //Error wait expects std::unique_lock<std::mutex> as argument
Is there any easy way to resolve / work around this problem?
you can try using recursive__mutex class since objects wont be locked.
https://msdn.microsoft.com/en-us/library/hh921466.aspx refer this as well.
I solved it by forward declare std::condition_variable.
The problem with Visual Studio's compiler for mutex includes is only for headers.
Including in the source files still worked.
Related
I am getting the warning
warning C4640: '_entries': construction of local static object is not thread-safe
from the ATL macro END_CONNECTION_POINT_MAP, for example
BEGIN_CONNECTION_POINT_MAP(CMBusInclinometerTemChannel)
CONNECTION_POINT_ENTRY(__uuidof(IChannelEvents))
END_CONNECTION_POINT_MAP()
in a C++ ATL/COM project.
I think that this has started happening since installing Visual Studio 2015 update 2.
Does anybody have a solution to this problem?
I thought it might be a new warning, but no - it was earlier just turned off by default. I suppose it is a long standing "problem", however it might be not so easy to convert it to a real bug (if at all possible and has side effects).
The problem is about the map of connection points using static local variable _entries internally, which is initialized on first use in a thread-unsafe manner. It is however an initialization of a pointer with fixed values the pointer refers to. The problem might possibly be that thread #1 treats map as initialized while thread #2 is just in the middle of initialization. Pretty rare condition, no wonder there has been no complaints so far.
Solution might be in surrounding the static variable initialization with global critical section lock, such as
ATLASSERT(_pAtlModule);
CComCritSecLock<CComCriticalSection> Lock(_pAtlModule->m_csStaticDataInitAndTypeInfo);
static ...
in the map macros, and suppression of the warning using #pragma. This should be a fix in ATL headers code (atlcom.h).
I have a property which is similar to the following:
private:
Foo* myFoo_m;
public:
Foo getMyFoo() const
{
if (myFoo_m == NULL)
{
myFoo_m = new Foo();
// perform initialization
This works well in a single-threaded environment, but how do I handle this in a multi-threaded environment? Most of the info I've found deals with static singletons, but in this case, myFoo is a public instance property.
I am porting this over from C# (where I can use Lazy) and Java (where I can use double check locking), but it doesn't seem that there is a straightforward way to do this in C++. I cannot rely on any external libraries (no BOOST), and this needs to work on windows and linux. I also cannot use C++11.
Any insight would be good. I am new to C++.
If you have access to c++11 you can use std::mutex to lock prevent multiple threads from initializing the lazy section. (Note: std::mutex only became available on Windows with VS2012)
You can even perform a scoped aquisition of the mutex with std::lock_guard:
private:
std::mutex m_init_mutex;
public:
Foo getMyFoo() const
{
{
std::lock_guard<std::mutex> lock(m_init_mutex);
if (myFoo_m == NULL)
{
myFoo_m = new Foo();
// perform initialization
}
}
EDIT: The OPs now stated that C++11 isn't an option, but perhaps this answer will be useful in the future
By saying "no C++11", "no Boost or other third-party code", "must work on Windows and Linux", you have restricted yourself to using implementation-specific locking mechanisms.
I think your best option is to define a simple lock class for yourself, and implement it to use pthread_mutex on Linux and a CriticalSection on Windows. Possibly you already have some platform-specific code, to start the threads in the first place.
You could try something like Windows Services for UNIX to avoid writing platform-specific code, but it's probably not worth it for one lock. And although it's supplied by Microsoft, you'd probably consider it an external library anyway.
Warning: I didn't see the "no C++11" requirement, so please disregard the answer.
Since C++11 mandates that static variable initialization be thread-safe, here's a simple way that you might consider "cheating":
Foo init_foo()
{
// initialize and return a Foo
}
Foo & get_instance_lazily()
{
static Foo impl = init_foo();
return impl;
}
The instance will be initialized the first time that you call get_instance_lazily(), and thread-safely so.
I'm trying to refactor a DLL to control a OPOS device. After the device is claimed and enabled it starts a thread to constantly check for data received from the OPOS device. I declare the method in OposReader.h
But I figured it would be a better idea to pull out said method, and move it to a helper. So I created a class ReaderThreadHelper.h put it in... but in the thread I have to adjust values in OposReader.
So in the OposReader I call #include ReaderThreadHelper.h and in the ReaderThreadHelper.h I have to do a #include OposReader.h... and that starts the problem with the circular reference... and I'm too new to C++ to know how to fix it.
Should I even have done this to begin with? Is there a more proper way to do this?
Short answer: use forward declarations and include headers to .cpp files only.
Detailed explanation is here: Resolve circular dependencies in C++
What is the differance between boost::details::pool::pthread_mutex and boost::details::pool::null_mutex.
I see that in latest boost version - 1.42, the class boost::details::pool::pthread_mutex was deleted. What should I use instead?
boost::details::pool::null_mutex is a mutex that does nothing (a lock always succeeds immediately). It's appropriate when you're not using threads. The Boost pool library selects what kind of mutex it will use to synchronize access to critical sections with a typedef for the mutex type based on the following snippet from boost\pool\detail\mutex.hpp:
#if !defined(BOOST_HAS_THREADS) || defined(BOOST_NO_MT) || defined(BOOST_POOL_NO_MT)
typedef null_mutex default_mutex;
#else
typedef boost::mutex default_mutex;
#endif
In other words, if the configuration says that no threading is involved (either for Boost as a whole, or for the pool library in particular), then the null_mutex will be used (which is basically a nop).
If threading is to be supported, then the boost::mutex type will be used, which comes from the Boost thread library (and will be a pthread-based mutex if your system uses pthreads).
I am so frustrated right now after several hours trying to find where shared_ptr is located. None of the examples I see show complete code to include the headers for shared_ptr (and working). Simply stating std, tr1 and <memory> is not helping at all! I have downloaded boosts and all but still it doesn't show up! Can someone help me by telling exactly where to find it?
Thanks for letting me vent my frustrations!
EDIT:
I see my title has been changed. Sorry about that.
So... it was also because it was not clear to me that shared_ptr is "C++ version dependant" --> that's why I did not state my environment --> therefore probably why it was so difficult for me to find it.
I am working on MSVS2008.
EDIT 2:
I don't know why, but I was including [memory] and [boost/tr1/memory.hpp] and [boost/tr1/tr1/memory] while looking everywhere for the shared_ptr.. of course, i couldn't.
Thanks for all the responses.
There are at least three places where you may find shared_ptr:
If your C++ implementation supports C++11 (or at least the C++11 shared_ptr), then std::shared_ptr will be defined in <memory>.
If your C++ implementation supports the C++ TR1 library extensions, then std::tr1::shared_ptr will likely be in <memory> (Microsoft Visual C++) or <tr1/memory> (g++'s libstdc++). Boost also provides a TR1 implementation that you can use.
Otherwise, you can obtain the Boost libraries and use boost::shared_ptr, which can be found in <boost/shared_ptr.hpp>.
Boost Getting Started
If you want to use it from Boost TR1 instead
shared_ptr Example
for VS2008 with feature pack update, shared_ptr can be found under namespace std::tr1.
std::tr1::shared_ptr<int> MyIntSmartPtr = new int;
of
if you had boost installation path (for example # C:\Program Files\Boost\boost_1_40_0) added to your IDE settings:
#include <boost/shared_ptr.hpp>
If your'e looking bor boost's shared_ptr, you could have easily found the answer by googling shared_ptr, following the links to the docs, and pulling up a complete working example such as this.
In any case, here is a minimalistic complete working example for you which I just hacked up:
#include <boost/shared_ptr.hpp>
struct MyGizmo
{
int n_;
};
int main()
{
boost::shared_ptr<MyGizmo> p(new MyGizmo);
return 0;
}
In order for the #include to find the header, the libraries obviously need to be in the search path. In MSVC, you set this in Project Settings>Configuration Properties>C/C++>Additional Include Directories. In my case, this is set to C:\Program Files (x86)\boost\boost_1_42