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();
}
}