113 lines
3.1 KiB
C++
113 lines
3.1 KiB
C++
/* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
|
|
|
// First include (the generated) my_config.h, to get correct platform defines.
|
|
#include "my_config.h"
|
|
#include <gtest/gtest.h>
|
|
|
|
#ifdef _WIN32
|
|
#include<Windows.h>
|
|
#else
|
|
#include <pthread.h>
|
|
#endif
|
|
|
|
#include "runtime.hpp"
|
|
#include "yassl_int.hpp"
|
|
|
|
#include "thread_utils.h"
|
|
|
|
namespace {
|
|
|
|
using thread::Notification;
|
|
using thread::Thread;
|
|
|
|
class Yassl_thread : public Thread
|
|
{
|
|
public:
|
|
Yassl_thread(Notification *go, Notification *done)
|
|
: m_sessions_instance(NULL), m_go(go), m_done(done)
|
|
{}
|
|
virtual void run()
|
|
{
|
|
// Wait until my creator tells me to go.
|
|
m_go->wait_for_notification();
|
|
yaSSL::Sessions &sessions= yaSSL::GetSessions();
|
|
m_sessions_instance= &sessions;
|
|
// Tell my creator I'm done.
|
|
m_done->notify();
|
|
}
|
|
yaSSL::Sessions *m_sessions_instance;
|
|
private:
|
|
Notification *m_go;
|
|
Notification *m_done;
|
|
};
|
|
|
|
|
|
/**
|
|
Verify that yaSSL::sessionsInstance is indeed a singleton.
|
|
If any of the EXPECT_EQ below reports an error, it is not.
|
|
We can also run 'valgrind ./yassl-t'. If there are errors,
|
|
valgrind will report a multiple of
|
|
sizeof(yaSSL::Sessions) == 80
|
|
bytes lost.
|
|
*/
|
|
TEST(YasslTest, ManySessions)
|
|
{
|
|
Notification go[5];
|
|
Notification done[5];
|
|
Yassl_thread t0(&go[0], &done[0]);
|
|
Yassl_thread t1(&go[1], &done[1]);
|
|
Yassl_thread t2(&go[2], &done[2]);
|
|
Yassl_thread t3(&go[3], &done[3]);
|
|
Yassl_thread t4(&go[4], &done[4]);
|
|
|
|
t0.start();
|
|
t1.start();
|
|
t2.start();
|
|
t3.start();
|
|
t4.start();
|
|
|
|
for (int ix= 0; ix < 5; ++ix)
|
|
go[ix].notify();
|
|
|
|
for (int ix= 0; ix < 5; ++ix)
|
|
done[ix].wait_for_notification();
|
|
|
|
// These are most likely to fail unless we use pthread_once.
|
|
EXPECT_EQ(t0.m_sessions_instance, t1.m_sessions_instance);
|
|
EXPECT_EQ(t0.m_sessions_instance, t2.m_sessions_instance);
|
|
EXPECT_EQ(t0.m_sessions_instance, t3.m_sessions_instance);
|
|
EXPECT_EQ(t0.m_sessions_instance, t4.m_sessions_instance);
|
|
|
|
// These rarely fail. If they do, we have more than two instances.
|
|
EXPECT_EQ(t1.m_sessions_instance, t2.m_sessions_instance);
|
|
EXPECT_EQ(t1.m_sessions_instance, t3.m_sessions_instance);
|
|
EXPECT_EQ(t1.m_sessions_instance, t4.m_sessions_instance);
|
|
|
|
EXPECT_EQ(t2.m_sessions_instance, t3.m_sessions_instance);
|
|
EXPECT_EQ(t2.m_sessions_instance, t4.m_sessions_instance);
|
|
|
|
EXPECT_EQ(t3.m_sessions_instance, t4.m_sessions_instance);
|
|
|
|
t0.join();
|
|
t1.join();
|
|
t2.join();
|
|
t3.join();
|
|
t4.join();
|
|
yaSSL_CleanUp();
|
|
}
|
|
|
|
}
|