- Reduced size of cppcms_boost as many parts were replaced by booster ones.master
@@ -22,24 +22,20 @@ option(DISABLE_SHARED "Disable shared libraries build" OFF) | |||
option(DISABLE_STATIC "Disable static libraries build" OFF) | |||
option(DISABLE_ICONV "Disable usage iconv library - use ICU for conversion" OFF) | |||
option(DISABLE_GCRYPT "Disable usage of gcrypt library, no AES cookies encryption would be available" OFF) | |||
option(USE_EXTERNAL_BOOST "Use external Boost library and not internal one, boost version provided by BOOST_SUFFIX variable" OFF) | |||
option(DISABLE_FCGI "Disable fastcgi web server api" OFF) | |||
option(DISABLE_SCGI "Disable scgi web server api" OFF) | |||
option(DISABLE_HTTP "Disable http web server" OFF) | |||
if(DISABLE_ICU_LOCALIZATION OR USE_EXTERNAL_BOOST) | |||
set(CPPCMS_SUFFIX "-c") | |||
endif() | |||
if(DISABLE_ICU_LOCALIZATION) | |||
set(BOOSTER_NO_LOCALE ON) | |||
set(CPPCMS_SUFFIX "-c") | |||
endif() | |||
add_subdirectory(booster) | |||
include_directories(booster) | |||
include_directories(src) | |||
include_directories(private) | |||
include_directories(cppcms_boost) | |||
@@ -120,24 +116,6 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") | |||
endif() | |||
if(USE_EXTERNAL_BOOST) | |||
set(CPPCMS_USE_EXTERNAL_BOOST 1) | |||
endif(USE_EXTERNAL_BOOST) | |||
if(NOT USE_EXTERNAL_BOOST) | |||
add_subdirectory(cppcms_boost) | |||
include_directories(cppcms_boost) | |||
else(NOT USE_EXTERNAL_BOOST) | |||
find_path(BOOST_INCLUDE_DIR boost/shared_ptr.hpp) | |||
find_library(BOOST_SYSTEM boost_system-${BOOST_SUFFIX} NAMES boost_system boost_system-mt) | |||
find_library(BOOST_FILESYSTEM boost_filesystem-${BOOST_SUFFIX} NAMES boost_filesystem boost_filesystem-mt) | |||
find_library(BOOST_IOSTREAMS boost_iostreams-${BOOST_SUFFIX} NAMES boost_iostreams boost_iostreams-mt) | |||
find_library(BOOST_ZLIB boost_zlib-${BOOST_SUFFIX} NAMES boost_zlib boost_zlib) | |||
include_directories(${BOOST_INCLUDE_DIR}) | |||
endif(NOT USE_EXTERNAL_BOOST) | |||
if(NOT DISABLE_ICU_LOCALIZATION) | |||
find_library(ICU_UC icuuc${ICU_SUFFIX}) | |||
find_library(ICU_DATA icudata NAMES icudt) | |||
@@ -243,6 +221,11 @@ check_cxx_source_compiles( | |||
int main(){std::list<int> l; __typeof__(l.begin()) p=l.begin();}" | |||
HAVE_UNDERSCORE_TYPEOF) | |||
find_library(ZLIB z NAMES zdll zlib) | |||
find_path(ZLIB_INCLUDE_DIR zlib.h) | |||
include_directories(${ZLIB_INCLUDE_DIR}) | |||
if(${CMAKE_HOST_WIN32}) | |||
find_library(WS2_32 ws2_32) | |||
find_library(WSOCK32 wsock32) | |||
@@ -284,23 +267,7 @@ endif(${CMAKE_HOST_WIN32}) | |||
check_function_exists(canonicalize_file_name HAVE_CANONICALIZE_FILE_NAME) | |||
if(USE_EXTERNAL_BOOST) | |||
if(WIN32) | |||
add_definitions(-DBOOST_ALL_NO_LIB) | |||
add_definitions(-DBOOST_REGEX_DYN_LINK) | |||
add_definitions(-DBOOST_FILESYSTEM_DYN_LINK) | |||
add_definitions(-DBOOST_SYSTEM_DYN_LINK) | |||
add_definitions(-DBOOST_IOSTREAMS_DYN_LINK) | |||
add_definitions(-DBOOST_THREAD_DYN_LINK) | |||
add_definitions(-DBOOST_DATE_TIME_DYN_LINK) | |||
add_definitions(-DBOOST_ZLIB_DYN_LINK) | |||
endif(WIN32) | |||
else(USE_EXTERNAL_BOOST) | |||
add_definitions(-DCPPCMS_BOOST_ALL_NO_LIB) | |||
if(NOT DISABLE_SHARED) | |||
add_definitions(-DCPPCMS_BOOST_ALL_DYN_LINK) | |||
endif(NOT DISABLE_SHARED) | |||
endif(USE_EXTERNAL_BOOST) | |||
add_definitions(-DCPPCMS_BOOST_ALL_NO_LIB) | |||
set(CPPCMS_PUBLIC_HEADERS | |||
application.h | |||
@@ -389,6 +356,8 @@ set(CPPCMS_SOURCES | |||
src/session_interface.cpp | |||
src/session_memory_storage.cpp | |||
src/rpc_json.cpp | |||
cppcms_boost/src/zlib.cpp | |||
cppcms_boost/src/gzip.cpp | |||
) | |||
if(DISABLE_ICU_LOCALIZATION) | |||
@@ -479,24 +448,6 @@ foreach(ALIB ${CPPCMS_LIBS}) | |||
else(DISABLE_SHARED) | |||
target_link_libraries(${ALIB} booster) | |||
endif(DISABLE_SHARED) | |||
if(NOT USE_EXTERNAL_BOOST) | |||
if(DISABLE_SHARED) | |||
target_link_libraries(${ALIB} boost-static) | |||
else(DISABLE_SHARED) | |||
target_link_libraries(${ALIB} boost) | |||
endif(DISABLE_SHARED) | |||
else(NOT USE_EXTERNAL_BOOST) | |||
target_link_libraries(${ALIB} ${BOOST_REGEX}) | |||
target_link_libraries(${ALIB} ${BOOST_IOSTREAMS}) | |||
target_link_libraries(${ALIB} ${BOOST_DATE_TIME}) | |||
target_link_libraries(${ALIB} ${BOOST_THREAD}) | |||
target_link_libraries(${ALIB} ${BOOST_FILESYSTEM}) | |||
target_link_libraries(${ALIB} ${BOOST_SYSTEM}) | |||
if(BOOST_ZLIB) | |||
target_link_libraries(${ALIB} ${BOOST_ZLIB}) | |||
endif(BOOST_ZLIB) | |||
endif(NOT USE_EXTERNAL_BOOST) | |||
if(LIB_GCRYPT) | |||
target_link_libraries(${ALIB} ${LIB_GCRYPT}) | |||
endif(LIB_GCRYPT) | |||
@@ -524,6 +475,10 @@ foreach(ALIB ${CPPCMS_LIBS}) | |||
if(LIB_DL) | |||
target_link_libraries(${ALIB} ${LIB_DL}) | |||
endif(LIB_DL) | |||
if(ZLIB) | |||
target_link_libraries(${ALIB} ${ZLIB}) | |||
endif(ZLIB) | |||
endforeach(ALIB) | |||
@@ -1,420 +0,0 @@ | |||
Index: proc_acceptor.cpp | |||
=================================================================== | |||
--- proc_acceptor.cpp (revision 1153) | |||
+++ proc_acceptor.cpp (working copy) | |||
@@ -1,5 +1,6 @@ | |||
#define CPPCMS_SOURCE | |||
#include "proc_acceptor.h" | |||
+#include <iostream> | |||
namespace cppcms { namespace impl { | |||
process_shared_acceptor::process_shared_acceptor(cppcms::service &srv) | |||
@@ -12,15 +13,30 @@ | |||
service_=&srv.impl().get_io_service(); | |||
srv.after_fork(boost::bind(&process_shared_acceptor::on_fork,this)); | |||
} | |||
+ | |||
+ void process_shared_acceptor::start() | |||
+ { | |||
+ worker_.reset(new boost::thread(boost::bind(&process_shared_acceptor::run,this))); | |||
+ } | |||
+ | |||
+ void process_shared_acceptor::stop() | |||
+ { | |||
+ stop_ = true; | |||
+ wake(); | |||
+ worker_->join(); | |||
+ } | |||
void process_shared_acceptor::on_fork() | |||
{ | |||
int fds[2]; | |||
- pipe(fds); | |||
+ if(::pipe(fds) < 0) { | |||
+ throw cppcms_error(errno,"Creation of pipe failed"); | |||
+ } | |||
break_fd_=fds[0]; | |||
wake_fd_=fds[1]; | |||
max_1_=std::max(break_fd_,wake_fd_)+1; | |||
FD_SET(break_fd_,&wait_set); | |||
+ start(); | |||
} | |||
void process_shared_acceptor::wake() | |||
{ | |||
@@ -32,6 +48,26 @@ | |||
} | |||
} | |||
+ struct assigner_and_caller { | |||
+ function<void(int)> assigner; | |||
+ function<void(boost::system::error_code const &e)> callback; | |||
+ int fd; | |||
+ boost::system::error_code e; | |||
+ void operator()() | |||
+ { | |||
+ std::cout << "Assigning and calling" << std::endl; | |||
+ try { | |||
+ if(!assigner.empty()) | |||
+ assigner(fd); | |||
+ callback(e); | |||
+ } | |||
+ catch(std::exception const &e) | |||
+ { | |||
+ std::cerr << "Assigning and calling failed " << e.what() << std::endl; | |||
+ } | |||
+ } | |||
+ }; | |||
+ | |||
bool process_shared_acceptor::run_one() | |||
{ | |||
fd_set rd; | |||
@@ -42,7 +78,9 @@ | |||
int n; | |||
{ | |||
mutex::guard guard(process_mutex_); | |||
+ std::cout << "Selecting " << getpid() << std::endl; | |||
n=::select(max_1_,&rd,0,0,0); | |||
+ std::cout << "Selected " << n << std::endl; | |||
if(n < 0 && errno==EINTR) | |||
return true; | |||
if(n < 0) | |||
@@ -63,19 +101,22 @@ | |||
int fd=::accept(afd,0,0); | |||
int err=errno; | |||
+ std::cout << "Accepted " << afd << " as " << fd << " in " << getpid() <<std::endl; | |||
+ | |||
thread_guard tguard(thread_mutex_); | |||
- boost::system::error_code e; | |||
- if(fd > 0) { | |||
- assigners_[afd](fd); | |||
- assigners_[afd]=assign_function(); | |||
+ assigner_and_caller anc; | |||
+ if(fd >= 0) { | |||
+ anc.assigner.swap(assigners_[afd]); | |||
+ anc.fd=fd; | |||
} | |||
else { | |||
- e=boost::system::error_code(err,boost::system::errno_ecat); | |||
+ anc.e=boost::system::error_code(err,boost::system::errno_ecat); | |||
} | |||
- service_->post(boost::bind(callbacks_[afd],e)); | |||
- callbacks_[afd]=on_accept_function(); | |||
+ anc.callback.swap(callbacks_[afd]); | |||
FD_CLR(afd,&wait_set); | |||
+ std::cout << "Posting " << std::endl; | |||
+ service_->post(anc); | |||
} | |||
} | |||
} | |||
@@ -83,8 +124,10 @@ | |||
} | |||
void process_shared_acceptor::run() | |||
{ | |||
+ std::cout << "Running " << getpid() << std::endl; | |||
while(run_one()) | |||
; | |||
+ std::cout << "Done " << getpid() << std::endl; | |||
} | |||
process_shared_acceptor::~process_shared_acceptor() | |||
Index: service.cpp | |||
=================================================================== | |||
--- service.cpp (revision 1153) | |||
+++ service.cpp (working copy) | |||
@@ -49,7 +49,11 @@ | |||
#include "views_pool.h" | |||
#include "session_pool.h" | |||
+#ifndef CPPCMS_WIN32 | |||
+#include "proc_acceptor.h" | |||
+#endif | |||
+ | |||
#ifdef CPPCMS_POSIX | |||
#include <sys/wait.h> | |||
#endif | |||
@@ -304,6 +308,17 @@ | |||
#endif | |||
} | |||
+void service::reset_service() | |||
+{ | |||
+ #ifndef CPPCMS_WIN32 | |||
+ std::auto_ptr<boost::asio::io_service> new_service(new boost::asio::io_service()); | |||
+ for(unsigned i=0;i<impl_->acceptors_.size();i++) | |||
+ impl_->acceptors_[i]=impl_->acceptors_[i]->clone(*new_service); | |||
+ impl_->io_service_ = new_service; | |||
+ | |||
+ #endif | |||
+} | |||
+ | |||
void service::after_fork(function<void()> const &cb) | |||
{ | |||
impl_->on_fork_.push_back(cb); | |||
@@ -313,27 +328,46 @@ | |||
{ | |||
generator(); | |||
session_pool().init(); | |||
+ | |||
+ #ifndef CPPCMS_WIN32 | |||
+ //if(procs_no() > 1) { | |||
+ impl_->process_shared_acceptor_.reset(new impl::process_shared_acceptor(*this)); | |||
+ //} | |||
+ #endif | |||
+ | |||
start_acceptor(); | |||
if(settings().get("file_server.enable",false)) | |||
applications_pool().mount(applications_factory<cppcms::impl::file_server>(),""); | |||
+ std::cout << "FORKING" << std::endl; | |||
+ | |||
if(prefork()) { | |||
return; | |||
} | |||
thread_pool(); // make sure we start it | |||
+ | |||
for(unsigned i=0;i<impl_->on_fork_.size();i++) | |||
impl_->on_fork_[i](); | |||
impl_->on_fork_.clear(); | |||
+ | |||
+ #ifndef CPPCMS_WIN32 | |||
+ //if(procs_no() > 1) { | |||
+ reset_service(); | |||
+ //} | |||
+ #endif | |||
for(unsigned i=0;i<impl_->acceptors_.size();i++) | |||
impl_->acceptors_[i]->async_accept(); | |||
setup_exit_handling(); | |||
+ | |||
+ std::cout << "LOOPING" << std::endl; | |||
impl_->get_io_service().run(); | |||
+ std::cout << "Exitting " << std::endl; | |||
} | |||
int service::procs_no() | |||
@@ -668,6 +702,12 @@ | |||
service::~service() | |||
{ | |||
acceptors_.clear(); | |||
+ #ifndef CPPCMS_WIN32 | |||
+ if(process_shared_acceptor_.get()) { | |||
+ process_shared_acceptor_->stop(); | |||
+ process_shared_acceptor_.reset(); | |||
+ } | |||
+ #endif | |||
thread_pool_.reset(); | |||
sig_.reset(); | |||
breaker_.reset(); | |||
Index: cgi_api.h | |||
=================================================================== | |||
--- cgi_api.h (revision 1153) | |||
+++ cgi_api.h (working copy) | |||
@@ -24,6 +24,7 @@ | |||
#include "intrusive_ptr.h" | |||
#include <vector> | |||
#include <map> | |||
+#include <memory> | |||
#include "function.h" | |||
#include "config.h" | |||
#ifdef CPPCMS_USE_EXTERNAL_BOOST | |||
@@ -58,6 +59,7 @@ | |||
public: | |||
virtual void async_accept() = 0; | |||
virtual void stop() = 0; | |||
+ virtual std::auto_ptr<acceptor> clone(boost::asio::io_service &) = 0; | |||
virtual ~acceptor(){} | |||
}; | |||
Index: cgi_acceptor.h | |||
=================================================================== | |||
--- cgi_acceptor.h (revision 1153) | |||
+++ cgi_acceptor.h (working copy) | |||
@@ -32,7 +32,13 @@ | |||
# include <cppcms_boost/bind.hpp> | |||
namespace boost = cppcms_boost; | |||
#endif | |||
+#ifndef CPPCMS_WIN32 | |||
+#include "proc_acceptor.h" | |||
+#include <unistd.h> | |||
+#endif | |||
+ | |||
+ | |||
namespace cppcms { | |||
namespace impl { | |||
namespace cgi { | |||
@@ -40,12 +46,33 @@ | |||
template<typename Proto,class ServerAPI> | |||
class socket_acceptor : public acceptor { | |||
public: | |||
+ socket_acceptor(cppcms::service &srv,boost::asio::io_service &iosrv) : | |||
+ srv_(srv), | |||
+ acceptor_(iosrv), | |||
+ stopped_(false) | |||
+ { | |||
+ } | |||
socket_acceptor(cppcms::service &srv) : | |||
srv_(srv), | |||
acceptor_(srv_.impl().get_io_service()), | |||
stopped_(false) | |||
{ | |||
} | |||
+ virtual std::auto_ptr<acceptor> clone(boost::asio::io_service &iosrv) | |||
+ { | |||
+ #ifdef CPPCMS_WIN32 | |||
+ throw cppcms_error("Internal error - cloning should not be done under Windows platform"); | |||
+ #else | |||
+ std::auto_ptr<socket_acceptor<Proto,ServerAPI> > tmp(new socket_acceptor<Proto,ServerAPI>(srv_,iosrv)); | |||
+ int newfd = ::dup(acceptor_.native()); | |||
+ if(newfd < 0) | |||
+ throw cppcms_error(errno,"Dup failed"); | |||
+ tmp->acceptor_.assign(acceptor_.local_endpoint().protocol(),newfd); | |||
+ std::auto_ptr<acceptor> tmp2; | |||
+ tmp2 = tmp; | |||
+ return tmp2; | |||
+ #endif | |||
+ } | |||
virtual void async_accept() | |||
{ | |||
if(stopped_) | |||
@@ -53,11 +80,24 @@ | |||
ServerAPI *api=new ServerAPI(srv_); | |||
api_=api; | |||
asio_socket_ = &api->socket_; | |||
- acceptor_.async_accept( | |||
- *asio_socket_, | |||
- boost::bind( &socket_acceptor::on_accept, | |||
- this, | |||
- boost::asio::placeholders::error)); | |||
+#ifndef CPPCMS_WIN32 | |||
+ if(srv_.impl().process_shared_acceptor_.get()) { | |||
+ srv_.impl().process_shared_acceptor_->async_accept( | |||
+ acceptor_, | |||
+ *asio_socket_, | |||
+ boost::bind( &socket_acceptor::on_accept, | |||
+ this, | |||
+ boost::asio::placeholders::error)); | |||
+ } | |||
+ else | |||
+#endif | |||
+ { | |||
+ acceptor_.async_accept( | |||
+ *asio_socket_, | |||
+ boost::bind( &socket_acceptor::on_accept, | |||
+ this, | |||
+ boost::asio::placeholders::error)); | |||
+ } | |||
} | |||
virtual void stop() | |||
{ | |||
Index: service.h | |||
=================================================================== | |||
--- service.h (revision 1153) | |||
+++ service.h (working copy) | |||
@@ -80,6 +80,7 @@ | |||
void start_acceptor(); | |||
void setup_exit_handling(); | |||
bool prefork(); | |||
+ void reset_service(); | |||
util::hold_ptr<impl::service> impl_; | |||
}; | |||
Index: service_impl.h | |||
=================================================================== | |||
--- service_impl.h (revision 1153) | |||
+++ service_impl.h (working copy) | |||
@@ -31,6 +31,7 @@ | |||
class session_pool; | |||
namespace impl { | |||
+ class process_shared_acceptor; | |||
namespace cgi { | |||
class acceptor; | |||
} | |||
@@ -44,6 +45,9 @@ | |||
return *io_service_; | |||
} | |||
+ #ifndef CPPCMS_WIN32 | |||
+ std::auto_ptr<process_shared_acceptor> process_shared_acceptor_; | |||
+ #endif | |||
private: | |||
friend class cppcms::service; | |||
Index: CMakeLists.txt | |||
=================================================================== | |||
--- CMakeLists.txt (revision 1153) | |||
+++ CMakeLists.txt (working copy) | |||
@@ -520,7 +520,7 @@ | |||
if(WIN32 AND NOT CYGWIN) | |||
set(CPPCMS_SOURCES ${CPPCMS_SOURCES} session_win32_file_storage.cpp) | |||
else(WIN32 AND NOT CYGWIN) | |||
- set(CPPCMS_SOURCES ${CPPCMS_SOURCES} session_posix_file_storage.cpp) | |||
+ set(CPPCMS_SOURCES ${CPPCMS_SOURCES} session_posix_file_storage.cpp proc_acceptor.cpp) | |||
endif(WIN32 AND NOT CYGWIN) | |||
if(NOT DISABLE_SHARED) | |||
Index: proc_acceptor.h | |||
=================================================================== | |||
--- proc_acceptor.h (revision 1153) | |||
+++ proc_acceptor.h (working copy) | |||
@@ -29,7 +29,7 @@ | |||
~process_shared_acceptor(); | |||
template<typename Socket1,typename Socket2> | |||
- void async_accept(Socket1 acc,Socket2 sock,on_accept_function const &on_accepted) | |||
+ void async_accept(Socket1 &acc,Socket2 &sock,on_accept_function const &on_accepted) | |||
{ | |||
int fd = acc.native(); | |||
{ | |||
@@ -38,16 +38,28 @@ | |||
if(fd + 1 > max_1_ ) | |||
max_1_ = fd+1; | |||
callbacks_[fd]=on_accepted; | |||
- assigners_[fd]=boost::bind(&Socket2::assign,&sock,_1); | |||
+ assigner<Socket2> as = { &sock, acc.local_endpoint().protocol() }; | |||
+ assigners_[fd]=as; | |||
} | |||
wake(); | |||
} | |||
- void stop() | |||
+ void start(); | |||
+ void stop(); | |||
+ private: | |||
+ | |||
+ template<typename Socket> | |||
+ struct assigner | |||
{ | |||
- stop_ = true; | |||
- wake(); | |||
- } | |||
- private: | |||
+ typedef typename Socket::protocol_type protocol_type; | |||
+ Socket *sock; | |||
+ protocol_type proto; | |||
+ void operator()(int fd) const | |||
+ { | |||
+ sock->assign(proto,fd); | |||
+ } | |||
+ }; | |||
+ | |||
+ | |||
void on_fork(); | |||
void wake(); | |||
bool run_one(); | |||
@@ -64,6 +76,7 @@ | |||
std::vector<on_accept_function> callbacks_; | |||
std::vector<assign_function> assigners_; | |||
boost::asio::io_service *service_; | |||
+ std::auto_ptr<boost::thread> worker_; | |||
} | |||
; | |||
} |
@@ -127,8 +127,6 @@ | |||
/* Define to module suffix. */ | |||
#cmakedefine CPPCMS_LIBRARY_PREFIX "${CPPCMS_LIBRARY_PREFIX}" | |||
#cmakedefine CPPCMS_USE_EXTERNAL_BOOST | |||
#cmakedefine CPPCMS_HAS_FCGI | |||
#cmakedefine CPPCMS_HAS_SCGI | |||
#cmakedefine CPPCMS_HAS_HTTP | |||
@@ -1,64 +0,0 @@ | |||
cmake_minimum_required(VERSION 2.6) | |||
set(BOOST_SRC | |||
libs/system/src/error_code.cpp | |||
libs/iostreams/src/zlib.cpp | |||
libs/iostreams/src/mapped_file.cpp | |||
libs/iostreams/src/gzip.cpp | |||
libs/iostreams/src/file_descriptor.cpp | |||
libs/filesystem/src/utf8_codecvt_facet.hpp | |||
libs/filesystem/src/utf8_codecvt_facet.cpp | |||
libs/filesystem/src/portability.cpp | |||
libs/filesystem/src/path.cpp | |||
libs/filesystem/src/operations.cpp | |||
) | |||
include_directories(.) | |||
find_library(ZLIB z NAMES zdll zlib) | |||
find_path(ZLIB_INCLUDE_DIR zlib.h) | |||
include_directories(${ZLIB_INCLUDE_DIR}) | |||
if(NOT DISABLE_SHARED) | |||
add_library(boost SHARED ${BOOST_SRC}) | |||
set(BOOST_SHARED_DEFS CPPCMS_BOOST_ALL_DYN_LINK CPPCMS_BOOST_ALL_NO_LIB) | |||
if(WIN32 AND NOT CYGWIN) | |||
set(BOOST_SHARED_DEFS ${BOOST_SHARED_DEFS} CPPCMS_BOOST_THREAD_BUILD_DLL) | |||
endif(WIN32 AND NOT CYGWIN) | |||
set_target_properties(boost PROPERTIES COMPILE_DEFINITIONS "${BOOST_SHARED_DEFS}") | |||
set_target_properties(boost PROPERTIES CLEAN_DIRECT_OUTPUT 1) | |||
set_target_properties(boost PROPERTIES OUTPUT_NAME "cppcms_boost${CPPCMS_SUFFIX}") | |||
target_link_libraries(boost ${ZLIB}) | |||
if(LIB_PTHREAD) | |||
target_link_libraries(boost ${LIB_PTHREAD}) | |||
endif(LIB_PTHREAD) | |||
install(TARGETS boost | |||
RUNTIME DESTINATION bin | |||
LIBRARY DESTINATION lib | |||
ARCHIVE DESTINATION lib) | |||
endif(NOT DISABLE_SHARED) | |||
if(NOT DISABLE_STATIC) | |||
add_library(boost-static STATIC ${BOOST_SRC}) | |||
set(BOOST_STATIC_DEFS CPPCMS_BOOST_ALL_NO_LIB) | |||
if(WIN32 AND NOT CYGWIN) | |||
set(BOOST_STATIC_DEFS ${BOOST_STATIC_DEFS} CPPCMS_BOOST_THREAD_BUILD_LIB) | |||
endif(WIN32 AND NOT CYGWIN) | |||
set_target_properties(boost-static PROPERTIES COMPILE_DEFINITIONS "${BOOST_STATIC_DEFS}") | |||
set_target_properties(boost-static PROPERTIES CLEAN_DIRECT_OUTPUT 1) | |||
set_target_properties(boost-static PROPERTIES OUTPUT_NAME "cppcms_boost") | |||
target_link_libraries(boost-static ${ZLIB}) | |||
if(LIB_PTHREAD) | |||
target_link_libraries(boost-static ${LIB_PTHREAD}) | |||
endif(LIB_PTHREAD) | |||
install(TARGETS boost-static | |||
RUNTIME DESTINATION bin | |||
LIBRARY DESTINATION lib | |||
ARCHIVE DESTINATION lib) | |||
endif(NOT DISABLE_STATIC) | |||
if(MSVC AND NOT DISABLE_STATIC) | |||
set_target_properties(boost-static PROPERTIES PREFIX "lib") | |||
endif(MSVC AND NOT DISABLE_STATIC) | |||
@@ -0,0 +1,173 @@ | |||
// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) | |||
// (C) Copyright 2003-2007 Jonathan Turkanis | |||
// Distributed under the Boost Software License, Version 1.0. (See accompanying | |||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) | |||
// See http://www.boost.org/libs/iostreams for documentation. | |||
// To configure Boost to work with libbz2, see the | |||
// installation instructions here: | |||
// http://boost.org/libs/iostreams/doc/index.html?path=7 | |||
// Define BOOST_IOSTREAMS_SOURCE so that <boost/iostreams/detail/config.hpp> | |||
// knows that we are building the library (possibly exporting code), rather | |||
// than using it (possibly importing code). | |||
#define CPPCMS_BOOST_IOSTREAMS_SOURCE | |||
#include <cppcms_boost/iostreams/detail/config/dyn_link.hpp> | |||
#include <cppcms_boost/iostreams/filter/gzip.hpp> | |||
namespace cppcms_boost { namespace iostreams { | |||
//------------------Implementation of gzip_header-----------------------------// | |||
namespace detail { | |||
void gzip_header::process(char c) | |||
{ | |||
uint8_t value = static_cast<uint8_t>(c); | |||
switch (state_) { | |||
case s_id1: | |||
if (value != gzip::magic::id1) | |||
throw gzip_error(gzip::bad_header); | |||
state_ = s_id2; | |||
break; | |||
case s_id2: | |||
if (value != gzip::magic::id2) | |||
throw gzip_error(gzip::bad_header); | |||
state_ = s_cm; | |||
break; | |||
case s_cm: | |||
if (value != gzip::method::deflate) | |||
throw gzip_error(gzip::bad_method); | |||
state_ = s_flg; | |||
break; | |||
case s_flg: | |||
flags_ = value; | |||
state_ = s_mtime; | |||
break; | |||
case s_mtime: | |||
mtime_ += value << (offset_ * 8); | |||
if (offset_ == 3) { | |||
state_ = s_xfl; | |||
offset_ = 0; | |||
} else { | |||
++offset_; | |||
} | |||
break; | |||
case s_xfl: | |||
state_ = s_os; | |||
break; | |||
case s_os: | |||
os_ = value; | |||
if (flags_ & gzip::flags::extra) { | |||
state_ = s_extra; | |||
} else if (flags_ & gzip::flags::name) { | |||
state_ = s_name; | |||
} else if (flags_ & gzip::flags::comment) { | |||
state_ = s_comment; | |||
} else if (flags_ & gzip::flags::header_crc) { | |||
state_ = s_hcrc; | |||
} else { | |||
state_ = s_done; | |||
} | |||
break; | |||
case s_xlen: | |||
xlen_ += value << (offset_ * 8); | |||
if (offset_ == 1) { | |||
state_ = s_extra; | |||
offset_ = 0; | |||
} else { | |||
++offset_; | |||
} | |||
break; | |||
case s_extra: | |||
if (--xlen_ == 0) { | |||
if (flags_ & gzip::flags::name) { | |||
state_ = s_name; | |||
} else if (flags_ & gzip::flags::comment) { | |||
state_ = s_comment; | |||
} else if (flags_ & gzip::flags::header_crc) { | |||
state_ = s_hcrc; | |||
} else { | |||
state_ = s_done; | |||
} | |||
} | |||
break; | |||
case s_name: | |||
if (c != 0) { | |||
file_name_ += c; | |||
} else if (flags_ & gzip::flags::comment) { | |||
state_ = s_comment; | |||
} else if (flags_ & gzip::flags::header_crc) { | |||
state_ = s_hcrc; | |||
} else { | |||
state_ = s_done; | |||
} | |||
break; | |||
case s_comment: | |||
if (c != 0) { | |||
comment_ += c; | |||
} else if (flags_ & gzip::flags::header_crc) { | |||
state_ = s_hcrc; | |||
} else { | |||
state_ = s_done; | |||
} | |||
break; | |||
case s_hcrc: | |||
if (offset_ == 1) { | |||
state_ = s_done; | |||
offset_ = 0; | |||
} else { | |||
++offset_; | |||
} | |||
break; | |||
default: | |||
assert(0); | |||
} | |||
} | |||
void gzip_header::reset() | |||
{ | |||
file_name_.clear(); | |||
comment_.clear(); | |||
os_ = flags_ = offset_ = xlen_ = 0; | |||
mtime_ = 0; | |||
state_ = s_id1; | |||
} | |||
//------------------Implementation of gzip_footer-----------------------------// | |||
void gzip_footer::process(char c) | |||
{ | |||
uint8_t value = static_cast<uint8_t>(c); | |||
if (state_ == s_crc) { | |||
crc_ += value << (offset_ * 8); | |||
if (offset_ == 3) { | |||
state_ = s_isize; | |||
offset_ = 0; | |||
} else { | |||
++offset_; | |||
} | |||
} else if (state_ == s_isize) { | |||
isize_ += value << (offset_ * 8); | |||
if (offset_ == 3) { | |||
state_ = s_done; | |||
offset_ = 0; | |||
} else { | |||
++offset_; | |||
} | |||
} else { | |||
assert(0); | |||
} | |||
} | |||
void gzip_footer::reset() | |||
{ | |||
crc_ = isize_ = offset_ = 0; | |||
state_ = s_crc; | |||
} | |||
} // End namespace boost::iostreams::detail. | |||
} } // End namespaces iostreams, boost. |
@@ -0,0 +1,191 @@ | |||
// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) | |||
// (C) Copyright 2003-2007 Jonathan Turkanis | |||
// Distributed under the Boost Software License, Version 1.0. (See accompanying | |||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) | |||
// See http://www.boost.org/libs/iostreams for documentation. | |||
// To configure Boost to work with zlib, see the | |||
// installation instructions here: | |||
// http://boost.org/libs/iostreams/doc/index.html?path=7 | |||
// Define BOOST_IOSTREAMS_SOURCE so that <boost/iostreams/detail/config.hpp> | |||
// knows that we are building the library (possibly exporting code), rather | |||
// than using it (possibly importing code). | |||
#define CPPCMS_BOOST_IOSTREAMS_SOURCE | |||
#include <cppcms_boost/iostreams/detail/config/dyn_link.hpp> | |||
#include <cppcms_boost/iostreams/filter/zlib.hpp> | |||
#include "zlib.h" // Jean-loup Gailly's and Mark Adler's "zlib.h" header. | |||
// To configure Boost to work with zlib, see the | |||
// installation instructions here: | |||
// http://boost.org/libs/iostreams/doc/index.html?path=7 | |||
namespace cppcms_boost { namespace iostreams { | |||
namespace zlib { | |||
// Compression levels | |||
const int no_compression = Z_NO_COMPRESSION; | |||
const int best_speed = Z_BEST_SPEED; | |||
const int best_compression = Z_BEST_COMPRESSION; | |||
const int default_compression = Z_DEFAULT_COMPRESSION; | |||
// Compression methods | |||
const int deflated = Z_DEFLATED; | |||
// Compression strategies | |||
const int default_strategy = Z_DEFAULT_STRATEGY; | |||
const int filtered = Z_FILTERED; | |||
const int huffman_only = Z_HUFFMAN_ONLY; | |||
// Status codes | |||
const int okay = Z_OK; | |||
const int stream_end = Z_STREAM_END; | |||
const int stream_error = Z_STREAM_ERROR; | |||
const int version_error = Z_VERSION_ERROR; | |||
const int data_error = Z_DATA_ERROR; | |||
const int mem_error = Z_MEM_ERROR; | |||
const int buf_error = Z_BUF_ERROR; | |||
// Flush codes | |||
const int finish = Z_FINISH; | |||
const int no_flush = Z_NO_FLUSH; | |||
const int sync_flush = Z_SYNC_FLUSH; | |||
// Code for current OS | |||
//const int os_code = OS_CODE; | |||
} // End namespace zlib. | |||
//------------------Implementation of zlib_error------------------------------// | |||
zlib_error::zlib_error(int error) | |||
: CPPCMS_BOOST_IOSTREAMS_FAILURE("zlib error"), error_(error) | |||
{ } | |||
void zlib_error::check(int error) | |||
{ | |||
switch (error) { | |||
case Z_OK: | |||
case Z_STREAM_END: | |||
//case Z_BUF_ERROR: | |||
return; | |||
case Z_MEM_ERROR: | |||
throw std::bad_alloc(); | |||
default: | |||
throw zlib_error(error); | |||
; | |||
} | |||
} | |||
//------------------Implementation of zlib_base-------------------------------// | |||
namespace detail { | |||
zlib_base::zlib_base() | |||
: stream_(new z_stream), calculate_crc_(false), crc_(0) | |||
{ } | |||
zlib_base::~zlib_base() { delete static_cast<z_stream*>(stream_); } | |||
void zlib_base::before( const char*& src_begin, const char* src_end, | |||
char*& dest_begin, char* dest_end ) | |||
{ | |||
z_stream* s = static_cast<z_stream*>(stream_); | |||
s->next_in = reinterpret_cast<zlib::byte*>(const_cast<char*>(src_begin)); | |||
s->avail_in = static_cast<zlib::uint>(src_end - src_begin); | |||
s->next_out = reinterpret_cast<zlib::byte*>(dest_begin); | |||
s->avail_out= static_cast<zlib::uint>(dest_end - dest_begin); | |||
} | |||
void zlib_base::after(const char*& src_begin, char*& dest_begin, bool compress) | |||
{ | |||
z_stream* s = static_cast<z_stream*>(stream_); | |||
char* next_in = reinterpret_cast<char*>(s->next_in); | |||
char* next_out = reinterpret_cast<char*>(s->next_out); | |||
if (calculate_crc_) { | |||
const zlib::byte* buf = compress ? | |||
reinterpret_cast<const zlib::byte*>(src_begin) : | |||
reinterpret_cast<const zlib::byte*>( | |||
const_cast<const char*>(dest_begin) | |||
); | |||
zlib::uint length = compress ? | |||
static_cast<zlib::uint>(next_in - src_begin) : | |||
static_cast<zlib::uint>(next_out - dest_begin); | |||
if (length > 0) | |||
crc_ = crc32(crc_, buf, length); | |||
} | |||
total_in_ = s->total_in; | |||
total_out_ = s->total_out; | |||
src_begin = const_cast<const char*>(next_in); | |||
dest_begin = next_out; | |||
} | |||
int zlib_base::xdeflate(int flush) | |||
{ | |||
return ::deflate(static_cast<z_stream*>(stream_), flush); | |||
} | |||
int zlib_base::xinflate(int flush) | |||
{ | |||
return ::inflate(static_cast<z_stream*>(stream_), flush); | |||
} | |||
void zlib_base::reset(bool compress, bool realloc) | |||
{ | |||
z_stream* s = static_cast<z_stream*>(stream_); | |||
// Undiagnosed bug: | |||
// deflateReset(), etc., return Z_DATA_ERROR | |||
//zlib_error::check( | |||
realloc ? | |||
(compress ? deflateReset(s) : inflateReset(s)) : | |||
(compress ? deflateEnd(s) : inflateEnd(s)) | |||
; | |||
//); | |||
} | |||
void zlib_base::do_init | |||
( const zlib_params& p, bool compress, | |||
#if !CPPCMS_BOOST_WORKAROUND(CPPCMS_BOOST_MSVC, < 1300) | |||
zlib::xalloc_func /* alloc */, zlib::xfree_func /* free*/, | |||
#endif | |||
void* derived ) | |||
{ | |||
calculate_crc_ = p.calculate_crc; | |||
z_stream* s = static_cast<z_stream*>(stream_); | |||
// Current interface for customizing memory management | |||
// is non-conforming and has been disabled: | |||
//#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) | |||
// s->zalloc = alloc; | |||
// s->zfree = free; | |||
//#else | |||
s->zalloc = 0; | |||
s->zfree = 0; | |||
//#endif | |||
s->opaque = derived; | |||
int window_bits = p.noheader? -p.window_bits : p.window_bits; | |||
zlib_error::check( | |||
compress ? | |||
deflateInit2( s, | |||
p.level, | |||
p.method, | |||
window_bits, | |||
p.mem_level, | |||
p.strategy ) : | |||
inflateInit2(s, window_bits) | |||
); | |||
} | |||
} // End namespace detail. | |||
//----------------------------------------------------------------------------// | |||
} } // End namespaces iostreams, boost. |
@@ -16,13 +16,13 @@ | |||
#include <cppcms/locale_info.h> | |||
#include <cppcms/locale_message.h> | |||
#ifdef CPPCMS_USE_EXTERNAL_BOOST | |||
# include <boost/shared_ptr.hpp> | |||
# include <boost/unordered_map.hpp> | |||
#else // Internal Boost | |||
# include <cppcms_boost/shared_ptr.hpp> | |||
# include <cppcms_boost/unordered_map.hpp> | |||
#endif | |||
#include <booster/shared_ptr.h> | |||
#include "locale_src_mo_hash.hpp" | |||
#include "locale_src_mo_lambda.hpp" | |||
@@ -323,8 +323,8 @@ namespace cppcms { | |||
} | |||
catalogs_set_type catalogs_; | |||
std::vector<boost::shared_ptr<mo_file> > mo_catalogs_; | |||
std::vector<boost::shared_ptr<lambda::plural> > plural_forms_; | |||
std::vector<booster::shared_ptr<mo_file> > mo_catalogs_; | |||
std::vector<booster::shared_ptr<lambda::plural> > plural_forms_; | |||
domains_map_type domains_; | |||
@@ -22,18 +22,15 @@ | |||
#include "session_memory_storage.h" | |||
#ifdef CPPCMS_WIN_NATIVE | |||
#include "session_win32_file_storage.h" | |||
#include <windows.h> | |||
#else | |||
#include "session_posix_file_storage.h" | |||
#include <sys/types.h> | |||
#include <dirent.h> | |||
#endif | |||
#include <string.h> | |||
#include <iostream> | |||
#include <vector> | |||
#include <cppcms/config.h> | |||
#ifdef CPPCMS_USE_EXTERNAL_BOOST | |||
# include <boost/filesystem.hpp> | |||
#else // Internal Boost | |||
# include <cppcms_boost/filesystem.hpp> | |||
namespace boost = cppcms_boost; | |||
#endif | |||
@@ -64,17 +61,32 @@ void test(booster::shared_ptr<cppcms::sessions::session_storage> storage) | |||
storage->remove(bs+"2"); | |||
} | |||
std::vector<std::string> list_files() | |||
int count_files() | |||
{ | |||
namespace fs = boost::filesystem; | |||
std::vector<std::string> files; | |||
fs::directory_iterator end; | |||
for(fs::directory_iterator p(dir);p!=end;++p) { | |||
if(!is_directory(p->status())) { | |||
files.push_back(p->path().filename()); | |||
} | |||
#ifndef CPPCMS_WIN_NATIVE | |||
DIR *d=opendir(dir.c_str()); | |||
TEST(d); | |||
int counter = 0; | |||
struct dirent *de; | |||
while((de=readdir(d))!=0) { | |||
if(strlen(de->d_name)==32) | |||
counter++; | |||
} | |||
return files; | |||
closedir(d); | |||
return counter; | |||
#else | |||
WIN32_FIND_DATA entry; | |||
HANDLE d=FindFirstFile(dir.c_str(),&entry); | |||
int counter=0; | |||
if(d==INVALID_HANDLE_VALUE) | |||
return 0; | |||
do { | |||
if(strlen(entry,cFileName)==32) | |||
counter++; | |||
}while(FindNextFile(d,&entry)); | |||
FindClose(d); | |||
return counter; | |||
#endif | |||
} | |||
void test_files(booster::shared_ptr<cppcms::sessions::session_storage> storage, | |||
@@ -84,23 +96,23 @@ void test_files(booster::shared_ptr<cppcms::sessions::session_storage> storage, | |||
TEST(f.requires_gc()); | |||
time_t now=time(0); | |||
storage->save(bs+"1",now,"test"); | |||
TEST(list_files().size()==1); | |||
TEST(count_files()==1); | |||
storage->remove(bs+"1"); | |||
TEST(list_files().size()==0); | |||
TEST(count_files()==0); | |||
storage->save(bs+"1",now-1,"test"); | |||
storage->save(bs+"2",now+1,"test2"); | |||
TEST(list_files().size()==2); | |||
TEST(count_files()==2); | |||
f.gc_job(); | |||
TEST(list_files().size()==1); | |||
TEST(count_files()==1); | |||
std::string tstr; | |||
time_t ttime; | |||
TEST(!storage->load(bs+"1",ttime,tstr)); | |||
TEST(storage->load(bs+"2",ttime,tstr)); | |||
TEST(ttime==now+1 && tstr=="test2"); | |||
storage->save(bs+"2",now-1,"test2"); | |||
TEST(list_files().size()==1); | |||
TEST(count_files()==1); | |||
f.gc_job(); | |||
TEST(list_files().size()==0); | |||
TEST(count_files()==0); | |||
} | |||