blob: a6482329fcf87d460e59a3422d7bbc759ce55037 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "DistributedSystemImpl.hpp"
#if defined(HAVE_PTHREAD_H)
#include <pthread.h>
#elif defined(_WIN32)
#include <windows.h>
#endif
#include <boost/filesystem.hpp>
#include <geode/SystemProperties.hpp>
#include "CacheImpl.hpp"
#include "CacheRegionHelper.hpp"
#include "CppCacheLibrary.hpp"
#include "PoolStatistics.hpp"
#include "RegionStats.hpp"
#include "config.h"
#include "util/Log.hpp"
#include "version.h"
namespace apache {
namespace geode {
namespace client {
volatile bool DistributedSystemImpl::m_isCliCallbackSet = false;
std::map<int, CliCallbackMethod> DistributedSystemImpl::m_cliCallbackMap;
std::recursive_mutex DistributedSystemImpl::m_cliCallbackLock;
DistributedSystemImpl::DistributedSystemImpl(
std::string name, DistributedSystem* implementee,
std::unique_ptr<SystemProperties> sysProps)
: m_name(name),
m_implementee(implementee),
m_sysProps(std::move(sysProps)),
m_connected(false) {
if (!m_sysProps->securityClientDhAlgo().empty()) {
DiffieHellman::initOpenSSLFuncPtrs();
}
logSystemInformation();
}
DistributedSystemImpl::~DistributedSystemImpl() {
LOGFINE("Destroyed DistributedSystemImpl");
}
void DistributedSystemImpl::connect() {
if (m_connected == true) {
throw AlreadyConnectedException(
"DistributedSystem::connect: already connected, call getInstance to "
"get it");
}
m_connected = true;
}
void DistributedSystemImpl::logSystemInformation() const {
auto productDir = CppCacheLibrary::getProductDir();
LOGCONFIG("Using Geode Native Client Product Directory: " + productDir);
// Add version information, source revision, current directory etc.
LOGCONFIG("Product version: %s",
PRODUCT_VENDOR " " PRODUCT_NAME " " PRODUCT_VERSION
" (" PRODUCT_BITS ") " PRODUCT_BUILDDATE);
LOGCONFIG("Source revision: %s", PRODUCT_SOURCE_REVISION);
LOGCONFIG("Source repository: %s", PRODUCT_SOURCE_REPOSITORY);
ACE_utsname u;
ACE_OS::uname(&u);
LOGCONFIG(
"Running on: SystemName=%s Machine=%s Host=%s Release=%s Version=%s",
u.sysname, u.machine, u.nodename, u.release, u.version);
LOGCONFIG("Current directory: %s",
boost::filesystem::current_path().string().c_str());
LOGCONFIG("Current value of PATH: %s", Utils::getEnv("PATH").c_str());
#ifndef _WIN32
LOGCONFIG("Current library path: %s",
Utils::getEnv("LD_LIBRARY_PATH").c_str());
#endif
// Log the Geode system properties
m_sysProps->logSettings();
}
void DistributedSystemImpl::disconnect() {
if (!m_connected) {
throw NotConnectedException(
"DistributedSystem::disconnect: connect "
"not called");
}
LOGCONFIG("Stopped the Geode Native Client");
// TODO global - log stays global so lets move this
Log::close();
m_connected = false;
}
SystemProperties& DistributedSystemImpl::getSystemProperties() const {
return *m_sysProps;
}
const std::string& DistributedSystemImpl::getName() const { return m_name; }
void DistributedSystemImpl::CallCliCallBack(Cache& cache) {
std::lock_guard<decltype(m_cliCallbackLock)> disconnectGuard(
m_cliCallbackLock);
if (m_isCliCallbackSet == true) {
for (const auto& iter : m_cliCallbackMap) {
iter.second(cache);
}
}
}
void DistributedSystemImpl::registerCliCallback(int appdomainId,
CliCallbackMethod clicallback) {
std::lock_guard<decltype(m_cliCallbackLock)> disconnectGuard(
m_cliCallbackLock);
m_cliCallbackMap[appdomainId] = clicallback;
m_isCliCallbackSet = true;
}
void DistributedSystemImpl::unregisterCliCallback(int appdomainId) {
std::lock_guard<decltype(m_cliCallbackLock)> disconnectGuard(
m_cliCallbackLock);
auto iter = m_cliCallbackMap.find(appdomainId);
if (iter != m_cliCallbackMap.end()) {
m_cliCallbackMap.erase(iter);
LOGFINE("Removing cliCallback %d", appdomainId);
}
}
void DistributedSystemImpl::setThreadName(const std::string& threadName) {
if (threadName.empty()) {
throw IllegalArgumentException("Thread name is empty.");
}
#if defined(HAVE_pthread_setname_np)
pthread_setname_np(threadName.c_str());
#elif defined(_WIN32)
const DWORD MS_VC_EXCEPTION = 0x406D1388;
#pragma pack(push, 8)
typedef struct tagTHREADNAME_INFO {
DWORD dwType; // Must be 0x1000.
LPCSTR szName; // Pointer to name (in user addr space).
DWORD dwThreadID; // Thread ID (-1=caller thread).
DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = threadName.c_str();
info.dwThreadID = -1;
info.dwFlags = 0;
__try {
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR),
(ULONG_PTR*)&info);
} __except (EXCEPTION_EXECUTE_HANDLER) {
}
#endif
}
} // namespace client
} // namespace geode
} // namespace apache