- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I was wondering if there was any reason why the condition_variable won't accept a unique lock with a recursive mutex. Compiler gives an error when I try to do that:
[cpp]recursive_mutex rec_mutex;
unique_lock ul(rec_mutex);
condition_variable condVar;
condVar.wait(ul); // <-- compile error saying ul needs tbb::mutex and not tbb::recursive_mutex
[/cpp]
Link Copied
13 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Because 'ul' variable is not declared as 'tbb::mutex'.
Sergey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is a follow up.
>>...I was wondering if there was any reason why the condition_variable won't accept a unique lock with a recursive mutex...
'unique_lock' is a template class and you need to specify a type 'mutex'. Please take a look at a 'condition_variable' source file located at:
..\[ TBBDIR ]\Include\tbb\compat\
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ahh it's a template class. Got it. Thank you. But if I don't provide the type for template it defaults to tbb::mutex? That's why in the above code I get the compile error?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The last comment I made probably doesn't make sense. The problem is not the unique lock, the problem is the condition_variable.
I just noticed the website removes the template defintions. So I put them in brackets. Hopefully there's no confusion.
[cpp] tbb::recursive_mutex rmutex;
std::unique_lock(tbb::recursive_mutex) ul1(rmutex);
std::condition_variable condVar;
condVar.wait(ul1); // <-- compile error here[cpp]
But if I make the unique_lock (tbb::mutex) then it compiles fine. I get 2 different error messages on Win and LX. So my question is why the condition_variable only accepts tbb::mutexe and not tbb::recursive_mutex?
Thank you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
>>But if I don't provide the type for template it defaults to tbb::mutex?
That's a good question.
Since you had a compilation error it didn't. About 2 years ago I had a similar issue with a template class. That is, Microsoft C++ compiler allowed to compile the template with, I would say, a "weaker" declaration. However, MinGW C++ compiler did not and it means that MinGW is a very strict compiler when it comes to declarations. I could provide a small example if interested,
>>...That's why in the above code I get the compile error?
Yes.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>...I just noticed the website removes the template defintions. So I put them in brackets. Hopefully there's no confusion.
It happened again. Honestly, I posted so many messages regarding that problem with arrow-left and arrow-right characters and I don't know what to tell you now.
>>...But if I make the unique_lock (tbb::mutex) then it compiles fine. I get 2 different error messages on Win and LX. So my question is
>>why the condition_variable only accepts tbb::mutexe and not tbb::recursive_mutex?
Let me take a look at a declaration of 'tbb::recursive_mutex' template class.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is a summary of my investigation:
1. This is how a 'wait' method is declared in a 'condition_variable' class:
...
void wait( unique_lock< mutex > & lock );
...
2. These two classes are declared as follows:
** mutex.h **
...
class mutex {
public:
//! Construct unacquired mutex.
mutex() {
...
};
and
** recursive_mutex.h **
...
class recursive_mutex {
public:
//! Construct unacquired recursive_mutex.
recursive_mutex() {
...
};
and the 'recursive_mutex' class is not based on 'mutex'. That is, something like this:
...
class recursive_mutex : public mutex {
public:
...
};
Since there is no a C++ operator '=' to convert from type 'recursive_mutex' to type 'mutex' a C++ compiler reports some error:
Error C2664: ...cannot convert parameter 1 from 'tbb::recursive_mutex' to 'tbb::mutex &'...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>...
>>recursive_mutex rec_mutex;
>>unique_lock ul(rec_mutex);
>>condition_variable condVar;
>>condVar.wait(ul);
>>...
I verified the code with Microsoft C++ compiler and it did not compile it when left-arrow mutex right-arrow not used:
Compiling...
...
..\common\prttests.cpp(42814) : error C2955: 'tbb::interface5::unique_lock' : use of class template requires template argument list
..\include\tbb\compat\condition_variable(113) : see declaration of 'tbb::interface5::unique_lock'
..\common\prttests.cpp(42814) : error C2514: 'tbb::interface5::unique_lock' : class has no constructors
..\include\tbb\compat\condition_variable(113) : see declaration of 'tbb::interface5::unique_lock'
..\common\prttests.cpp(42816) : error C2664: 'void tbb::interface5::condition_variable::wait(tbb::interface5::unique_lock &)' : cannot convert parameter 1 from 'tbb::interface5::unique_lock' to 'tbb::interface5::unique_lock &'
with
[
M=tbb::mutex
]
ScaLibTestApp - 3 error(s), 0 warning(s)
...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here are three small test-cases I tried with Microsoft C++ compiler:
...
// Test-Case 1
{
mutex reg_mutex;
unique_lock[ mutex ] ul( reg_mutex );
condition_variable condVar;
condVar.wait( ul );
}
// Test-Case 2
{
recursive_mutex rec_mutex;
unique_lock[ mutex ] ul( rec_mutex );
condition_variable condVar;
condVar.wait( ul );
// Error C2664: 'tbb::interface5::unique_lock::unique_lock(tbb::mutex &)' :
// cannot convert parameter 1 from 'tbb::recursive_mutex' to 'tbb::mutex &'
}
// Test-Case 3
{
recursive_mutex rec_mutex;
unique_lock[ recursive_mutex ] ul( &rec_mutex );
condition_variable condVar;
condVar.wait( ul );
// Error C2664: 'void tbb::interface5::condition_variable::wait(tbb::interface5::unique_lock &)' :
// cannot convert parameter 1 from 'tbb::interface5::unique_lock' to 'tbb::interface5::unique_lock &'
// with
// [
// M=tbb::mutex
// ]
// and
// [
// M=tbb::recursive_mutex
// ]
// and
// [
// M=tbb::mutex
// ]
}
...
It is clear that another method like:
...
void wait( unique_lock< recursive_mutex > & lock );
...
is needed in the 'condition_variable' class.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
And final answer to your question:
>>...I was wondering if there was any reason why the condition_variable won't accept a unique lock with a recursive mutex...
Another method like:
...
void wait( unique_lock< recursive_mutex > & lock );
...
is needed in the 'condition_variable' class.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Note that condition_variable, like thread, is intentionally implemented exactly as described by the new C++ standard (which seems to have adopted it from boost, a known incubator for new standard features), so this limitation is not unique to TBB (as you will readily find). The problem at hand is that TBB has not also provided compatibility support for condition_variable_any.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>...The problem at hand is that TBB has not also provided compatibility support for condition_variable_any.
Thanks for the note! Does it mean that condition_variable_any could work with mutex and recursive_mutex?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Any type with lock() and unlock() will do, so yes.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page