This source file includes following definitions.
- VarToString
- ppb_var_
- TEST_F
- size_
- ThreadMain
- ThreadMain
- ThreadMain
- TEST_F
#include <string>
#include <vector>
#include "base/strings/string_number_conversions.h"
#include "base/threading/platform_thread.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/c/ppb_var.h"
#include "ppapi/proxy/ppapi_proxy_test.h"
#include "ppapi/shared_impl/ppb_var_shared.h"
namespace {
std::string VarToString(const PP_Var& var, const PPB_Var* ppb_var) {
uint32_t len = 0;
const char* utf8 = ppb_var->VarToUtf8(var, &len);
return std::string(utf8, len);
}
const size_t kNumStrings = 100;
const size_t kNumThreads = 20;
const int kRefsToAdd = 20;
}
namespace ppapi {
namespace proxy {
class PPB_VarTest : public PluginProxyTest {
public:
PPB_VarTest()
: test_strings_(kNumStrings), vars_(kNumStrings),
ppb_var_(ppapi::PPB_Var_Shared::GetVarInterface1_2()) {
for (size_t i = 0; i < kNumStrings; ++i)
test_strings_[i] = base::IntToString(i);
}
protected:
std::vector<std::string> test_strings_;
std::vector<PP_Var> vars_;
const PPB_Var* ppb_var_;
};
TEST_F(PPB_VarTest, Strings) {
for (size_t i = 0; i < kNumStrings; ++i) {
vars_[i] = ppb_var_->VarFromUtf8(test_strings_[i].c_str(),
test_strings_[i].length());
EXPECT_EQ(test_strings_[i], VarToString(vars_[i], ppb_var_));
}
for (int ref = 0; ref < kRefsToAdd; ++ref) {
for (size_t i = 0; i < kNumStrings; ++i) {
ppb_var_->AddRef(vars_[i]);
EXPECT_EQ(test_strings_[i], VarToString(vars_[i], ppb_var_));
}
}
for (int ref = 0; ref < kRefsToAdd; ++ref) {
for (size_t i = 0; i < kNumStrings; ++i) {
ppb_var_->Release(vars_[i]);
EXPECT_EQ(test_strings_[i], VarToString(vars_[i], ppb_var_));
}
}
for (size_t i = 0; i < kNumStrings; ++i) {
ppb_var_->Release(vars_[i]);
uint32_t len = 10;
const char* utf8 = ppb_var_->VarToUtf8(vars_[i], &len);
EXPECT_EQ(NULL, utf8);
EXPECT_EQ(0u, len);
}
}
namespace {
class CreateVarThreadDelegate : public base::PlatformThread::Delegate {
public:
CreateVarThreadDelegate(PP_Module pp_module, const std::string* strings_in,
PP_Var* vars_out, std::string* strings_out,
size_t size)
: pp_module_(pp_module), strings_in_(strings_in), vars_out_(vars_out),
strings_out_(strings_out), size_(size) {
}
virtual ~CreateVarThreadDelegate() {}
virtual void ThreadMain() {
const PPB_Var* ppb_var = ppapi::PPB_Var_Shared::GetVarInterface1_2();
for (size_t i = 0; i < size_; ++i) {
vars_out_[i] = ppb_var->VarFromUtf8(strings_in_[i].c_str(),
strings_in_[i].length());
strings_out_[i] = VarToString(vars_out_[i], ppb_var);
}
}
private:
PP_Module pp_module_;
const std::string* strings_in_;
PP_Var* vars_out_;
std::string* strings_out_;
size_t size_;
};
class ChangeRefVarThreadDelegate : public base::PlatformThread::Delegate {
public:
ChangeRefVarThreadDelegate(const std::vector<PP_Var>& vars) : vars_(vars) {
}
virtual ~ChangeRefVarThreadDelegate() {}
virtual void ThreadMain() {
const PPB_Var* ppb_var = ppapi::PPB_Var_Shared::GetVarInterface1_2();
for (int ref = 0; ref < kRefsToAdd; ++ref) {
for (size_t i = 0; i < kNumStrings; ++i) {
ppb_var->AddRef(vars_[i]);
ppb_var->Release(vars_[i]);
}
}
for (size_t i = 0; i < kNumStrings; ++i) {
ppb_var->AddRef(vars_[i]);
}
}
private:
std::vector<PP_Var> vars_;
};
class RemoveRefVarThreadDelegate : public base::PlatformThread::Delegate {
public:
RemoveRefVarThreadDelegate(const std::vector<PP_Var>& vars) : vars_(vars) {
}
virtual ~RemoveRefVarThreadDelegate() {}
virtual void ThreadMain() {
const PPB_Var* ppb_var = ppapi::PPB_Var_Shared::GetVarInterface1_2();
for (size_t i = 0; i < kNumStrings; ++i) {
ppb_var->Release(vars_[i]);
}
}
private:
std::vector<PP_Var> vars_;
};
}
TEST_F(PPB_VarTest, Threads) {
std::vector<base::PlatformThreadHandle> create_var_threads(kNumThreads);
std::vector<CreateVarThreadDelegate> create_var_delegates;
std::vector<std::string> strings_out(kNumStrings);
size_t strings_per_thread = kNumStrings/kNumThreads;
for (size_t slice_start= 0; slice_start < kNumStrings;
slice_start += strings_per_thread) {
create_var_delegates.push_back(
CreateVarThreadDelegate(pp_module(),
&test_strings_[slice_start],
&vars_[slice_start],
&strings_out[slice_start],
std::min(strings_per_thread,
kNumStrings - slice_start)));
}
for (size_t i = 0; i < kNumThreads; ++i)
base::PlatformThread::Create(0, &create_var_delegates[i],
&create_var_threads[i]);
for (size_t i = 0; i < kNumThreads; ++i)
base::PlatformThread::Join(create_var_threads[i]);
EXPECT_EQ(test_strings_, strings_out);
std::vector<base::PlatformThreadHandle> change_ref_var_threads(kNumThreads);
std::vector<ChangeRefVarThreadDelegate> change_ref_var_delegates;
for (size_t i = 0; i < kNumThreads; ++i)
change_ref_var_delegates.push_back(ChangeRefVarThreadDelegate(vars_));
for (size_t i = 0; i < kNumThreads; ++i) {
base::PlatformThread::Create(0, &change_ref_var_delegates[i],
&change_ref_var_threads[i]);
}
for (size_t i = 0; i < kNumThreads; ++i)
base::PlatformThread::Join(change_ref_var_threads[i]);
for (size_t i = 0; i < kNumStrings; ++i) {
ppb_var_->Release(vars_[i]);
}
for (size_t i = 0; i < kNumStrings; ++i)
EXPECT_EQ(test_strings_[i], VarToString(vars_[i], ppb_var_));
std::vector<base::PlatformThreadHandle> remove_ref_var_threads(kNumThreads);
std::vector<RemoveRefVarThreadDelegate> remove_ref_var_delegates;
for (size_t i = 0; i < kNumThreads; ++i)
remove_ref_var_delegates.push_back(RemoveRefVarThreadDelegate(vars_));
for (size_t i = 0; i < kNumThreads; ++i) {
base::PlatformThread::Create(0, &remove_ref_var_delegates[i],
&remove_ref_var_threads[i]);
}
for (size_t i = 0; i < kNumThreads; ++i)
base::PlatformThread::Join(remove_ref_var_threads[i]);
for (size_t i = 0; i < kNumStrings; ++i) {
uint32_t len = 10;
const char* utf8 = ppb_var_->VarToUtf8(vars_[i], &len);
EXPECT_EQ(NULL, utf8);
EXPECT_EQ(0u, len);
}
}
}
}