On Thu, Oct 8, 2009 at 9:42 AM, Florian Link <flori...@gmail.com> wrote:
> Hi,
>
> we started using GoogleTest in our company and I really like it a lot.
> I noticed that include/gtest/internal/gtest-port.h contains some stubs
> for Mutex/etc. to make GoogleTest thread-safe.
> I wondered if you plan to provide a cross-platform implementation for
> these classes in one of the next releases, e.g. using boost.threads?
It's on our radar. You can star this issue
(http://code.google.com/p/googletest/issues/detail?id=148) to vote for
it and get notifications on its progress.
> As a sidenote, I would suggest that you only enable the stubs if
> GTEST_IS_THREADSAFE is 0.
> This would allow people who do their own threading implementation to
> use the original gtest-port.h file instead of
> patching it on each new google test release.
>
> I will probably implement a boost.threads version and would be willing
> to share it with you.
That would be nice!
One thing to note: we would like to avoid depending on Boost if
possible, as most users really don't like having to manage this
heavy-weight dependency. Therefore it's best if the implementation
doesn't depend on Boost. Short of that, we should make it an optional
download that people can get only when they want to. Thanks,
> regards,
> Florian Link
>
--
Zhanyong
2009/10/9 Florian Link <flori...@gmail.com>
>
> Hi,
>
> I ported the files to boost thread, but now I noticed a problem.
> I thought that the multithreading support would mean that I could use
> ASSERT_* and EXPECT_* from other threads and
> the result would be added to the test function that was running in the
> main thread at that time.
This understanding is correct.
> But as far as I can see now, the thread support in google test means
> that you can run different tests in different threads
> (which is actually not what I need).
No, gtest only runs the tests in the main thread. A test method may
start new threads, and any assertion failure in such threads will be
attributed to the current test.
> Or did I misunderstand something?
> What would be needed to associate another thread with the same
> reporter of a running TestImpl, so that ASSERT_ etc. are part of that
> test?
I think your port of thread utilities probably has a different
semantics than what gtest assumes. I wrote this in issue 148:
"ThreadLocal is supposed to be initialized in the main thread only.
Its get() method
will return a different value for each thread that calls it. The
value is created
on-demand. If you call get() twice in the same thread, you get the
same value. If
you call get() from different threads, you get different values.
We use gtest in many multi-threaded tests where we have a full
implementation of
ThreadLocal, and it works fine."
Can this explain it? Thanks,
>
> regards,
> Florian
>
>
> 2009/10/8 Zhanyong Wan (λx.x x) <w...@google.com>:
--
Zhanyong
It returns a pre-set value, which is set on gtest.cc:3744:
per_thread_test_part_result_reporter_(
&default_per_thread_test_part_result_reporter_),
So normally each thread will get the same default per-thread test part
result reporter. And thus test failures on all threads will be
attributed to the current test.
> I think both would be wrong, since I think the asserts from the
> different thread should be added to the result reporter of the main
> thread unit test! Thus, it is wrong to use ThreadLocalStorage for the
> reporter. It is fine to use the mutex lock in the code below to avoid
> races, but the reporter should be shared across threads.
It's neither.
> Below the code that I think is wrong:
>
> void UnitTest::AddTestPartResult(TestPartResultType result_type,
> const char* file_name,
> int line_number,
> const internal::String& message,
> const internal::String&
> os_stack_trace) {
> ...
> const TestPartResult result =
> TestPartResult(result_type, file_name, line_number,
> msg.GetString().c_str());
> impl_->GetTestPartResultReporterForCurrentThread()->
> ReportTestPartResult(result);
> ...
This is correct. The flexibility is needed for implementing macros in
gtest-spi.h.
--
Zhanyong
Sorry for the lack of documentation.
The ctor of ThreadLocal<T> takes a default value (let's call it x).
get() returns a different *copy* for each thread in which it is called
(note that it returns a reference). These copies will all have an
initial value of x.
Example:
// Doesn't matter in which thread this is run:
ThreadLocal<int> x(42); // 42 is the default value.
...
// Called in thread #1:
const int& x1 = x.get(); // x1 has value 42.
// Called in thread #1 too:
const int& x1_too = x.get();
// x1_too references the same int object as x1 does.
...
// Called in thread #2:
const int& x2 = x.get(); // x2 has value 42.
// x2 and x1 reference different int objects.
So ThreadLocal<T> will give you one T object for each thread, which
you can read via get(). To set the initial value of these objects,
pass the value to the ctor of ThreadLocal<T>.
Hth,
--
Zhanyong
Hi,
Any feedback on the pthread code?
Questions:
1. I'm throwing an exception when the pthread api returns an error, is it ok, or should i use GTEST_CHECK_ instead?
2. A lot of code in Mutex is for handling the case where two threads entering the lazyInit() at the same time. It's only possible if we start threads before main - from static globals or we use Mutex(NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX) in a static local. Shall we handle this case at all? (There is also a large/slow testcase testing for this.)
Thanks,
MiklósOn Sun, Oct 11, 2009 at 8:02 PM, mfazekas <fazeka...@gmail.com> wrote:
Hi,
I've uploaded a pthread implementation for review at:
http://codereview.appspot.com/129067/show
To make both default construcible and copy constructable classes work
with ThreadLocal, instead of the
'value = new T(defaultValue_);'
I'm doing:
'value = copyOrConstruct(defaultValue_)'
where the copyOrConstruct is a function pointer, and it's intialized
in the constructor, to either:
static T* copy(const T& default_) { new T(default_); }
or:
static T* construct(const T&) { new T(); }
This way either copy constructor or default constructor is required
but not both.