313 lines
8.5 KiB
C++
313 lines
8.5 KiB
C++
// Copyright (C) 2007 Davis E. King (davis@dlib.net)
|
|
// License: Boost Software License See LICENSE.txt for the full license.
|
|
|
|
|
|
#include <string>
|
|
#include <sstream>
|
|
|
|
#include <dlib/threads.h>
|
|
#include "tester.h"
|
|
|
|
namespace
|
|
{
|
|
using namespace test;
|
|
using namespace std;
|
|
using namespace dlib;
|
|
|
|
logger dlog("test.multithreaded_object");
|
|
|
|
dlib::mutex cm;
|
|
int count;
|
|
|
|
class test1 : multithreaded_object
|
|
{
|
|
public:
|
|
test1 ()
|
|
{
|
|
DLIB_TEST(number_of_threads_registered() == 0);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
clear();
|
|
DLIB_TEST(number_of_threads_registered() == 0);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
}
|
|
|
|
~test1 ()
|
|
{
|
|
DLIB_TEST(number_of_threads_registered() == 0);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
stop();
|
|
DLIB_TEST(number_of_threads_registered() == 0);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
wait();
|
|
DLIB_TEST(number_of_threads_registered() == 0);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
}
|
|
|
|
private:
|
|
};
|
|
|
|
class test2 : private multithreaded_object
|
|
{
|
|
public:
|
|
test2()
|
|
{
|
|
DLIB_TEST(number_of_threads_registered() == 0);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
register_thread(*this,&test2::thread);
|
|
DLIB_TEST(number_of_threads_registered() == 1);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
clear();
|
|
DLIB_TEST(number_of_threads_registered() == 0);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
register_thread(*this,&test2::thread);
|
|
DLIB_TEST(number_of_threads_registered() == 1);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
}
|
|
|
|
~test2()
|
|
{
|
|
DLIB_TEST(number_of_threads_registered() == 1);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
stop();
|
|
DLIB_TEST(number_of_threads_registered() == 1);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
wait();
|
|
DLIB_TEST(number_of_threads_registered() == 1);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
}
|
|
|
|
private:
|
|
|
|
void thread()
|
|
{
|
|
auto_mutex M(cm);
|
|
++count;
|
|
}
|
|
|
|
};
|
|
|
|
class test3_c1 : private multithreaded_object
|
|
{
|
|
public:
|
|
test3_c1()
|
|
{
|
|
DLIB_TEST(number_of_threads_registered() == 0);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
register_thread(*this,&test3_c1::thread);
|
|
DLIB_TEST(number_of_threads_registered() == 1);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
start();
|
|
DLIB_TEST(number_of_threads_registered() == 1);
|
|
DLIB_TEST(is_running() == true);
|
|
}
|
|
|
|
~test3_c1()
|
|
{
|
|
DLIB_TEST(number_of_threads_registered() == 1);
|
|
stop();
|
|
DLIB_TEST(is_running() == false);
|
|
DLIB_TEST(number_of_threads_registered() == 1);
|
|
wait();
|
|
DLIB_TEST(number_of_threads_registered() == 1);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
}
|
|
|
|
private:
|
|
|
|
void thread()
|
|
{
|
|
cm.lock();
|
|
++count;
|
|
cm.unlock();
|
|
// wait until we are supposed to stop
|
|
while (!should_stop())
|
|
dlib::sleep(1);
|
|
}
|
|
|
|
};
|
|
|
|
class test4_c2 : private multithreaded_object
|
|
{
|
|
public:
|
|
test4_c2()
|
|
{
|
|
DLIB_TEST(number_of_threads_registered() == 0);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
register_thread(*this,&test4_c2::thread);
|
|
DLIB_TEST(number_of_threads_registered() == 1);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
start();
|
|
DLIB_TEST(number_of_threads_registered() == 1);
|
|
DLIB_TEST(number_of_threads_alive() == 1);
|
|
DLIB_TEST(is_running() == true);
|
|
register_thread(*this,&test4_c2::thread);
|
|
DLIB_TEST(number_of_threads_registered() == 2);
|
|
DLIB_TEST(number_of_threads_alive() == 2);
|
|
DLIB_TEST(is_running() == true);
|
|
start();
|
|
DLIB_TEST(number_of_threads_registered() == 2);
|
|
DLIB_TEST(number_of_threads_alive() == 2);
|
|
DLIB_TEST(is_running() == true);
|
|
start();
|
|
DLIB_TEST(number_of_threads_registered() == 2);
|
|
DLIB_TEST(number_of_threads_alive() == 2);
|
|
DLIB_TEST(is_running() == true);
|
|
start();
|
|
DLIB_TEST(number_of_threads_registered() == 2);
|
|
DLIB_TEST(number_of_threads_alive() == 2);
|
|
DLIB_TEST(is_running() == true);
|
|
start();
|
|
DLIB_TEST(number_of_threads_registered() == 2);
|
|
DLIB_TEST(number_of_threads_alive() == 2);
|
|
DLIB_TEST(is_running() == true);
|
|
pause();
|
|
DLIB_TEST(number_of_threads_registered() == 2);
|
|
DLIB_TEST(number_of_threads_alive() == 2);
|
|
DLIB_TEST(is_running() == false);
|
|
}
|
|
|
|
~test4_c2()
|
|
{
|
|
DLIB_TEST(number_of_threads_registered() == 2);
|
|
DLIB_TEST(number_of_threads_alive() == 2);
|
|
DLIB_TEST_MSG(is_running() == false,"is_running(): " << is_running());
|
|
stop();
|
|
DLIB_TEST(number_of_threads_registered() == 2);
|
|
DLIB_TEST(is_running() == false);
|
|
wait();
|
|
DLIB_TEST(number_of_threads_registered() == 2);
|
|
DLIB_TEST(number_of_threads_alive() == 0);
|
|
DLIB_TEST(is_running() == false);
|
|
}
|
|
|
|
private:
|
|
|
|
void thread()
|
|
{
|
|
auto_mutex M(cm);
|
|
++count;
|
|
while (!should_stop())
|
|
dlib::sleep(10);
|
|
}
|
|
|
|
};
|
|
|
|
|
|
class test5 : private multithreaded_object
|
|
{
|
|
public:
|
|
test5()
|
|
{
|
|
register_thread(*this,&test5::thread1);
|
|
register_thread(*this,&test5::thread2);
|
|
register_thread(*this,&test5::thread3);
|
|
register_thread(*this,&test5::thread3);
|
|
start();
|
|
}
|
|
|
|
~test5()
|
|
{
|
|
stop();
|
|
wait();
|
|
}
|
|
|
|
private:
|
|
|
|
void thread1()
|
|
{
|
|
while (!should_stop())
|
|
dlib::sleep(10);
|
|
}
|
|
|
|
void thread2()
|
|
{
|
|
while (!should_stop())
|
|
dlib::sleep(10);
|
|
}
|
|
|
|
void thread3()
|
|
{
|
|
while (!should_stop())
|
|
dlib::sleep(10);
|
|
}
|
|
|
|
};
|
|
|
|
|
|
void multithreaded_object_test (
|
|
)
|
|
/*!
|
|
ensures
|
|
- runs tests on dlib::multithreaded_object for compliance with the specs
|
|
!*/
|
|
{
|
|
|
|
count = 0;
|
|
|
|
for (int i = 0; i < 5; ++i)
|
|
{
|
|
{
|
|
test1 a1;
|
|
test2 a2;
|
|
test3_c1 a3;
|
|
test4_c2 a4;
|
|
test5 a5;
|
|
}
|
|
DLIB_TEST(count == (i+1)*3);
|
|
print_spinner();
|
|
}
|
|
count = 0;
|
|
|
|
for (int i = 0; i < 5; ++i)
|
|
{
|
|
{
|
|
test1 a1;
|
|
test2 a2;
|
|
test3_c1 a3;
|
|
test4_c2 a4;
|
|
test5 a5;
|
|
dlib::sleep(50);
|
|
}
|
|
DLIB_TEST(count == (i+1)*3);
|
|
print_spinner();
|
|
}
|
|
}
|
|
|
|
|
|
class multithreaded_object_tester : public tester
|
|
{
|
|
public:
|
|
multithreaded_object_tester (
|
|
) :
|
|
tester ("test_multithreaded_object",
|
|
"Runs tests on the multithreaded_object component.")
|
|
{}
|
|
|
|
void perform_test (
|
|
)
|
|
{
|
|
multithreaded_object_test();
|
|
}
|
|
} a;
|
|
|
|
}
|
|
|
|
|
|
|