@@ -1,73 +1,91 @@ | |||
SUBDIRS = ./transtext tests | |||
#SUBDIRS = ./transtext tests | |||
noinst_PROGRAMS = hello_world.fcgi | |||
noinst_HEADERS = hello_world_view.h | |||
dist_bin_SCRIPTS = cppcms_tmpl_cc cppcms_run | |||
bin_PROGRAMS = cppcms_make_key | |||
noinst_PROGRAMS = hello_world | |||
#noinst_HEADERS = hello_world_view.h | |||
#dist_bin_SCRIPTS = cppcms_tmpl_cc cppcms_run | |||
#bin_PROGRAMS = cppcms_make_key | |||
EXTRA_DIST = hello_world_skin1.tmpl hello_world_view1.tmpl hello_world_skin2.tmpl Changelog autogen.sh config.txt | |||
#EXTRA_DIST = hello_world_skin1.tmpl hello_world_view1.tmpl hello_world_skin2.tmpl Changelog autogen.sh config.txt | |||
hello_world_fcgi_SOURCES = hello_world.cpp hello_world_view1.cpp hello_world_view2.cpp | |||
hello_world_fcgi_LDADD = libcppcms.la transtext/libcppcmstranstext.la | |||
hello_world_fcgi_CXXFLAGS= -Wall -I./transtext | |||
hello_world_SOURCES= hello_world.cpp | |||
hello_world_LDADD= libcppcms.la | |||
hello_world_CXXFLAGS= -g -Wall | |||
hello_world_view1.cpp: hello_world_skin1.tmpl hello_world_view1.tmpl | |||
./cppcms_tmpl_cc hello_world_skin1.tmpl hello_world_view1.tmpl -o hello_world_view1.cpp -n view1 -d test | |||
#hello_world_view1.cpp: hello_world_skin1.tmpl hello_world_view1.tmpl | |||
# ./cppcms_tmpl_cc hello_world_skin1.tmpl hello_world_view1.tmpl -o hello_world_view1.cpp -n view1 -d test | |||
hello_world_view2.cpp: hello_world_skin2.tmpl hello_world_view1.tmpl | |||
./cppcms_tmpl_cc hello_world_skin2.tmpl hello_world_view1.tmpl -o hello_world_view2.cpp -n view2 -d test | |||
#hello_world_view2.cpp: hello_world_skin2.tmpl hello_world_view1.tmpl | |||
# ./cppcms_tmpl_cc hello_world_skin2.tmpl hello_world_view1.tmpl -o hello_world_view2.cpp -n view2 -d test | |||
lib_LTLIBRARIES = libcppcms.la | |||
libcppcms_la_SOURCES = global_config.cpp manager.cpp worker_thread.cpp \ | |||
text_tool.cpp cache_interface.cpp base_cache.cpp thread_cache.cpp scgi.cpp \ | |||
base_view.cpp util.cpp form.cpp application.cpp session_interface.cpp \ | |||
session_cookies.cpp hmac_encryptor.cpp encryptor.cpp md5.c base64.cpp \ | |||
session_sid.cpp session_file_storage.cpp session_dual.cpp cppcms_error.cpp \ | |||
url_dispatcher.cpp regex.cpp format.cpp json.cpp encoding.cpp | |||
libcppcms_la_SOURCES = \ | |||
service.cpp \ | |||
cgi_api.cpp \ | |||
http_request.cpp \ | |||
http_response.cpp \ | |||
http_context.cpp \ | |||
global_config.cpp \ | |||
cppcms_error.cpp \ | |||
cppcms_error_category.cpp \ | |||
thread_pool.cpp \ | |||
applications_pool.cpp \ | |||
application.cpp \ | |||
url_dispatcher.cpp \ | |||
http_cookie.cpp | |||
#libcppcms_la_SOURCES = global_config.cpp manager.cpp worker_thread.cpp \ | |||
# text_tool.cpp cache_interface.cpp base_cache.cpp thread_cache.cpp scgi.cpp \ | |||
# base_view.cpp util.cpp form.cpp application.cpp session_interface.cpp \ | |||
# session_cookies.cpp hmac_encryptor.cpp encryptor.cpp md5.c base64.cpp \ | |||
# session_sid.cpp session_file_storage.cpp session_dual.cpp cppcms_error.cpp \ | |||
# url_dispatcher.cpp regex.cpp format.cpp json.cpp encoding.cpp | |||
libcppcms_la_LDFLAGS = -no-undefined -version-info 0:0:0 | |||
libcppcms_la_LIBADD = @CPPCMS_LIBS@ transtext/libcppcmstranstext.la | |||
libcppcms_la_CXXFLAGS = -Wall -I./transtext | |||
libcppcms_la_LIBADD = @CPPCMS_LIBS@ | |||
libcppcms_la_CXXFLAGS = -g -Wall | |||
if EN_FORK_CACHE | |||
libcppcms_la_SOURCES += process_cache.cpp | |||
endif | |||
#if EN_FORK_CACHE | |||
#libcppcms_la_SOURCES += process_cache.cpp | |||
#endif | |||
if EN_FCGI_BACKEND | |||
libcppcms_la_SOURCES += fcgi.cpp | |||
endif | |||
#if EN_FCGI_BACKEND | |||
#libcppcms_la_SOURCES += fcgi.cpp | |||
#endif | |||
if EN_ENCR_SESSIONS | |||
libcppcms_la_SOURCES += aes_encryptor.cpp | |||
endif | |||
if EN_SQLITE_SESSIONS | |||
libcppcms_la_SOURCES += session_sqlite_storage.cpp | |||
#libcppcms_la_SOURCES += aes_encryptor.cpp | |||
endif | |||
nobase_pkginclude_HEADERS = global_config.h text_tool.h cppcms_error.h \ | |||
manager.h worker_thread.h fcgi.h cache_interface.h archive.h \ | |||
base_cache.h thread_cache.h cgicc_connection.h scgi.h cgi_api.h \ | |||
process_cache.h shmem_allocator.h posix_mutex.h config.h cgi.h base_view.h \ | |||
util.h form.h application.h session_interface.h session_api.h session_cookies.h \ | |||
hmac_encryptor.h aes_encryptor.h encryptor.h md5.h base64.h session_backend_factory.h \ | |||
session_sid.h session_storage.h session_file_storage.h session_dual.h \ | |||
session_cache_backend.h session_sqlite_storage.h tcp_cache_protocol.h tcp_cache.h \ | |||
tcp_connector.h session_tcp_storage.h tcp_messenger.h asio_config.h fcntl_mutex.h | |||
if EN_TCP_CACHE | |||
libcppcms_la_SOURCES += tcp_cache.cpp tcp_messenger.cpp session_tcp_storage.cpp tcp_connector.cpp | |||
bin_PROGRAMS += cppcms_tcp_scale | |||
cppcms_tcp_scale_SOURCES = base_cache.cpp thread_cache.cpp tcp_cache_server.cpp session_file_storage.cpp cppcms_error.cpp | |||
cppcms_tcp_scale_CXXFLAGS=-DNO_BUILDER_INTERFACE | |||
cppcms_tcp_scale_LDADD = @TCPSCALE_LIBS@ | |||
if EN_SQLITE_SESSIONS | |||
cppcms_tcp_scale_SOURCES += session_sqlite_storage.cpp | |||
endif | |||
endif | |||
#if EN_SQLITE_SESSIONS | |||
#libcppcms_la_SOURCES += session_sqlite_storage.cpp | |||
#endif | |||
#nobase_pkginclude_HEADERS = global_config.h text_tool.h cppcms_error.h \ | |||
# manager.h worker_thread.h fcgi.h cache_interface.h archive.h \ | |||
# base_cache.h thread_cache.h cgicc_connection.h scgi.h cgi_api.h \ | |||
# process_cache.h shmem_allocator.h posix_mutex.h config.h cgi.h base_view.h \ | |||
# util.h form.h application.h session_interface.h session_api.h session_cookies.h \ | |||
# hmac_encryptor.h aes_encryptor.h encryptor.h md5.h base64.h session_backend_factory.h \ | |||
# session_sid.h session_storage.h session_file_storage.h session_dual.h \ | |||
# session_cache_backend.h session_sqlite_storage.h tcp_cache_protocol.h tcp_cache.h \ | |||
# tcp_connector.h session_tcp_storage.h tcp_messenger.h asio_config.h fcntl_mutex.h | |||
#if EN_TCP_CACHE | |||
#libcppcms_la_SOURCES += tcp_cache.cpp tcp_messenger.cpp session_tcp_storage.cpp tcp_connector.cpp | |||
#bin_PROGRAMS += cppcms_tcp_scale | |||
#cppcms_tcp_scale_SOURCES = base_cache.cpp thread_cache.cpp tcp_cache_server.cpp session_file_storage.cpp cppcms_error.cpp | |||
#cppcms_tcp_scale_CXXFLAGS=-DNO_BUILDER_INTERFACE | |||
#cppcms_tcp_scale_LDADD = @TCPSCALE_LIBS@ | |||
#if EN_SQLITE_SESSIONS | |||
#cppcms_tcp_scale_SOURCES += session_sqlite_storage.cpp | |||
#endif | |||
# | |||
#endif | |||
@@ -1,48 +1,84 @@ | |||
#define CPPCMS_SOURCE | |||
#include "application.h" | |||
#include "http_context.h" | |||
#include "service.h" | |||
#include "cppcms_error.h" | |||
#include "url_dispatcher.h" | |||
namespace cppcms { | |||
application::application(worker_thread &w) : | |||
worker(w), | |||
url(w.url), | |||
app(worker.app), | |||
cgi(worker.cgi), | |||
env(worker.env), | |||
cgi_conn(worker.cgi_conn), | |||
cache(worker.cache), | |||
session(worker.session), | |||
cout(worker.cout), | |||
on_start(worker.on_start), | |||
on_end(worker.on_end) | |||
struct application::data { | |||
data(cppcms::service *s): | |||
service(s), | |||
conn(0), | |||
pool_id(-1) | |||
{ | |||
} | |||
cppcms::service *service; | |||
http::context *conn; | |||
int pool_id; | |||
url_dispatcher url; | |||
}; | |||
application::application(cppcms::service &srv) : | |||
d(new data(&srv)) | |||
{ | |||
} | |||
application::~application() | |||
{ | |||
} | |||
void application::on_404() | |||
cppcms::service &application::service() | |||
{ | |||
set_header(new cgicc::HTTPStatusHeader(404,"Not found")); | |||
cout<< "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" | |||
" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" | |||
"<html>\n" | |||
" <head>\n" | |||
" <title>404 - Not Found</title>\n" | |||
" </head>\n" | |||
" <body>\n" | |||
" <h1>404 - Not Found</h1>\n" | |||
" </body>\n" | |||
"</html>\n"; | |||
return *d->service; | |||
} | |||
void application::main() | |||
cppcms_config const &application::settings() | |||
{ | |||
on_start(); | |||
if(url.dispatch(env->getPathInfo())<0) { | |||
on_404(); | |||
} | |||
on_end(); | |||
return service().settings(); | |||
} | |||
http::request &application::request() | |||
{ | |||
return context().request(); | |||
} | |||
http::response &application::response() | |||
{ | |||
return context().response(); | |||
} | |||
url_dispatcher &application::dispatcher() | |||
{ | |||
return d->url; | |||
} | |||
http::context &application::context() | |||
{ | |||
if(!d->conn) | |||
throw cppcms_error("Trying to access uninitialized context"); | |||
return *d->conn; | |||
} | |||
void application::assign_context(http::context *conn) | |||
{ | |||
d->conn=conn; | |||
} | |||
void application::pool_id(int id) | |||
{ | |||
d->pool_id=id; | |||
} | |||
int application::pool_id() | |||
{ | |||
return d->pool_id; | |||
} | |||
} // cppcms |
@@ -9,13 +9,13 @@ namespace cppcms { | |||
class service; | |||
class cppcms_config; | |||
class context; | |||
class url_dispatcher; | |||
class applications_pool; | |||
namespace http { | |||
class request; | |||
class response; | |||
class context; | |||
} | |||
class CPPCMS_API application : public util::noncopyable { | |||
@@ -24,17 +24,22 @@ namespace cppcms { | |||
~application(); | |||
cppcms::service &service(); | |||
cppcms_config const &config(); | |||
cppcms::context &context(); | |||
cppcms_config const &settings(); | |||
http::context &context(); | |||
http::request &request(); | |||
http::response &response(); | |||
url_dispatcher &dispatcher(); | |||
private: | |||
struct data; | |||
util::hold_ptr<data> d; | |||
void assign_context(http::context *conn); | |||
private: | |||
void pool_id(int id); | |||
int pool_id(); | |||
struct data; // future use | |||
util::hold_ptr<data> d; | |||
friend class applications_pool; | |||
}; | |||
@@ -1,3 +1,4 @@ | |||
#define CPPCMS_SOURCE | |||
#include "applications_pool.h" | |||
#include "application.h" | |||
#include <set> | |||
@@ -34,6 +34,63 @@ namespace cppcms { | |||
util::hold_ptr<data> d; | |||
}; | |||
namespace details { | |||
template<typename T> | |||
struct simple_factory0 : public applications_pool::factory | |||
{ | |||
std::auto_ptr<application> operator()(service &s) const | |||
{ | |||
std::auto_ptr<application> app(new T(s)); | |||
return app; | |||
} | |||
}; | |||
template<typename T,typename P1> | |||
struct simple_factory1 : public applications_pool::factory | |||
{ | |||
simple_factory1(P1 p1) : p1_(p1) {} | |||
P1 p1_; | |||
std::auto_ptr<application> operator()(service &s) const | |||
{ | |||
std::auto_ptr<application> app(new T(s,p1_)); | |||
return app; | |||
} | |||
}; | |||
template<typename T,typename P1,typename P2> | |||
struct simple_factory2 : public applications_pool::factory | |||
{ | |||
simple_factory2(P1 p1,P2 p2) : p1_(p1),p2_(p2) {} | |||
P1 p1_; | |||
P2 p2_; | |||
std::auto_ptr<application> operator()(service &s) const | |||
{ | |||
std::auto_ptr<application> app(new T(s,p1_,p2_)); | |||
return app; | |||
} | |||
}; | |||
} // details | |||
template<typename T> | |||
std::auto_ptr<applications_pool::factory> applications_factory() | |||
{ | |||
std::auto_ptr<applications_pool::factory> f(new details::simple_factory0<T>); | |||
return f; | |||
} | |||
template<typename T,typename P1> | |||
std::auto_ptr<applications_pool::factory> applications_factory(P1 p1) | |||
{ | |||
std::auto_ptr<applications_pool::factory> f(new details::simple_factory1<T,P1>(p1)); | |||
return f; | |||
} | |||
template<typename T,typename P1,typename P2> | |||
std::auto_ptr<applications_pool::factory> applications_factory(P1 p1,P2 p2) | |||
{ | |||
std::auto_ptr<applications_pool::factory> f(new details::simple_factory2<T,P1,P2>(p1,p2)); | |||
return f; | |||
} | |||
} // cppcms | |||
@@ -1,10 +1,14 @@ | |||
#ifndef CPPCMS_ASIO_CONF_H | |||
#define CPPCMS_ASIO_CONF_H | |||
#if defined(_WIN32) | |||
# define _WIN32_WINNT 0x0500 | |||
#elif defined(__CYGWIN__) | |||
# define _WIN32_WINNT 0x0500 | |||
#include "defs.h" | |||
#if defined(CPPCMS_WIN32) | |||
# ifndef _WIN32_WINNT | |||
# define _WIN32_WINNT 0x0501 | |||
# endif | |||
#endif | |||
#if defined(CPPCMS_CYGWIN) | |||
# define __USE_W32_SOCKETS 1 | |||
#endif | |||
@@ -35,7 +35,12 @@ namespace impl { | |||
virtual void stop() | |||
{ | |||
stopped_=true; | |||
acceptor_.cancel(); | |||
boost::system::error_code e; | |||
#ifdef CPPCMS_WIN32 | |||
acceptor_.close(e); | |||
#else | |||
acceptor_.cancel(e); | |||
#endif | |||
} | |||
private: | |||
void on_accept(boost::system::error_code const &e) | |||
@@ -51,7 +56,7 @@ namespace impl { | |||
{ | |||
socket->set_option(boost::asio::ip::tcp::no_delay(true)); | |||
} | |||
#if !defined(_WIN32) && !defined(__CYGWIN__) | |||
#if !defined(CPPCMS_WIN32) | |||
void set_options(boost::asio::local::stream_protocol::socket *socket) | |||
{ | |||
// nothing; | |||
@@ -66,7 +71,7 @@ namespace impl { | |||
bool stopped_; | |||
}; | |||
#if !defined(_WIN32) && !defined(__CYGWIN__) | |||
#if !defined(CPPCMS_WIN32) | |||
template<typename API> | |||
class unix_socket_acceptor : public socket_acceptor<boost::asio::local::stream_protocol,API> | |||
{ | |||
@@ -1,3 +1,4 @@ | |||
#define CPPCMS_SOURCE | |||
#include "asio_config.h" | |||
#include "application.h" | |||
@@ -38,6 +39,16 @@ namespace { | |||
namespace cppcms { namespace impl { namespace cgi { | |||
connection::connection(cppcms::service &srv) : | |||
service_(&srv) | |||
{ | |||
} | |||
connection::~connection() | |||
{ | |||
} | |||
cppcms::service &connection::service() | |||
{ | |||
return *service_; | |||
@@ -86,7 +97,7 @@ void connection::load_content(boost::system::error_code const &e) | |||
async_read( &content_.front(), | |||
content_.size(), | |||
boost::bind(&connection::on_content_read,shared_from_this(),_1)); | |||
boost::bind(&connection::process_request,shared_from_this(),_1)); | |||
} | |||
@@ -138,9 +149,12 @@ void connection::setup_application() | |||
url_dispatcher::dispatch_type how; | |||
if(application_.get() == 0 || (how=application_->dispatcher().dispatchable(path))!=url_dispatcher::none) { | |||
make_error_response(http::response::not_found); | |||
on_response_complete(); | |||
return; | |||
} | |||
application_->assign_context(context_.get()); | |||
if(how == url_dispatcher::asynchronous) { | |||
dispatch(false); | |||
} | |||
@@ -157,10 +171,15 @@ void connection::dispatch(bool in_thread) | |||
{ | |||
try { | |||
application_->dispatcher().dispatch(); | |||
context_->response().finalize(); | |||
context_->response().out() << std::flush; | |||
} | |||
catch(std::exception const &e){ | |||
// TODO | |||
if(!context_->response().some_output_was_written()) { | |||
if(!in_thread) | |||
context_->response().io_mode(http::response::asynchronous); | |||
make_error_response(http::response::internal_server_error); | |||
} | |||
// TODO log it | |||
} | |||
if(in_thread) | |||
get_io_service().post(boost::bind(&connection::on_response_complete,shared_from_this())); | |||
@@ -170,13 +189,33 @@ void connection::dispatch(bool in_thread) | |||
void connection::on_response_complete() | |||
{ | |||
application_->assign_context(0); | |||
service().applications_pool().put(application_); | |||
if(context_->response().io_mode() == http::response::asynchronous) { | |||
async_chunk_=context_->response().get_async_chunk(); | |||
if(!async_chunk_.empty()) { | |||
async_write( | |||
async_chunk_.c_str(), | |||
async_chunk_.size(), | |||
boost::bind(&connection::try_restart,shared_from_this(),_1)); | |||
return; | |||
} | |||
} | |||
try_restart(boost::system::error_code()); | |||
} | |||
void connection::try_restart(boost::system::error_code const &e) | |||
{ | |||
if(e) return; | |||
if(keep_alive()) { | |||
context_.reset(); | |||
on_accepted(); | |||
} | |||
} | |||
namespace { | |||
struct reader { | |||
reader(connection *C,io_handler const &H,size_t S,char *P) : h(H), s(S), p(P),conn(C) | |||
@@ -4,13 +4,11 @@ | |||
#include "noncopyable.h" | |||
#include <vector> | |||
#include "asio_config.h" | |||
#include <boost/enable_shared_from_this.hpp> | |||
#include <boost/function.hpp> | |||
#include <boost/system/error_code.hpp> | |||
namespace boost { namespace asio { class io_service; } } | |||
namespace cppcms { | |||
@@ -69,7 +67,6 @@ namespace cgi { | |||
void async_write(void const *,size_t,io_handler const &h); | |||
private: | |||
void load_content(boost::system::error_code const &e); | |||
void on_content_read(boost::system::error_code const &e); | |||
void process_request(boost::system::error_code const &e); | |||
void load_multipart_form_data(); | |||
@@ -77,12 +74,14 @@ namespace cgi { | |||
void setup_application(); | |||
void dispatch(bool thread); | |||
void on_response_complete(); | |||
void try_restart(boost::system::error_code const &); | |||
std::auto_ptr<http::context> context_; | |||
std::vector<char> content_; | |||
std::auto_ptr<application> application_; | |||
cppcms::service *service_; | |||
std::string async_chunk_; | |||
}; | |||
@@ -1,6 +1,7 @@ | |||
# Server API settings | |||
server.api = "fastcgi" # fastcgi -- preferred API | |||
service.worker_threads = 0 | |||
service.api = "scgi" # fastcgi -- preferred API | |||
# scgi -- simplefied FCGI API -- yet another alternative | |||
# cgi -- Use only in case you application does huge amount of work | |||
# such the fork()+exec() time in neligable | |||
@@ -23,7 +24,8 @@ server.buffer = 100 # Default 1 -- relevant for multi-threaded model | |||
# How many requests may be "on-hold" even if | |||
# thread pool is full. Also sets "listen(2) backlog parameter | |||
server.socket = "/tmp/hello-fastcgi.socket" # Default is "" -- use default socket given | |||
service.port = 8000 | |||
# service.socket = "/tmp/hello-fastcgi.socket" # Default is "" -- use default socket given | |||
# by web server - | |||
# server.disable_xpowered_by = 0 # Disable X-Powered-By header (default enabled) | |||
@@ -82,33 +82,6 @@ AC_TRY_RUN([ #include <pthread.h> | |||
echo "Check: process shared mutex... ok"],[echo "Check: process shared mutex not supported"],[echo "Cross compile, assume no"]) | |||
if test "x$enable_forkcache" != "xno" ; then | |||
AC_CHECK_LIB(mm,main,[ | |||
have_mm=yes | |||
CPPCMS_LIBS="-lmm $CPPCMS_LIBS" | |||
AC_DEFINE([EN_FORK_CACHE],[],["Enable fork cache"]) | |||
], | |||
[ echo "======================================================================" | |||
echo " OSSP mm library (libmm) not installed" | |||
echo " The fork cache backend is disabled " | |||
echo "======================================================================" ]) | |||
fi | |||
AM_CONDITIONAL(EN_FORK_CACHE,[test "x$have_mm" = "xyes" ]) | |||
if test "x$enable_fastcgi" != "xno" ; then | |||
AC_CHECK_LIB(fcgi++,main,[ | |||
have_fcgi=yes | |||
CPPCMS_LIBS="-lfcgi++ -lfcgi $CPPCMS_LIBS" | |||
AC_DEFINE([EN_FCGI_BACKEND],[],["Enable fastcgi backend"]) | |||
], | |||
[ echo "======================================================================" | |||
echo "Fast CGI library not installed" | |||
echo "============== FastCGI API will be disabled ==========================" | |||
echo "You still have scgi and cgi API" ]) | |||
fi | |||
AM_CONDITIONAL(EN_FCGI_BACKEND,[test "x$have_fcgi" = "xyes" ]) | |||
if test "x$enable_crypt" != "xno" ; then | |||
AC_CHECK_LIB(gcrypt,main,[ | |||
have_gcrypt=yes | |||
@@ -121,19 +94,6 @@ if test "x$enable_crypt" != "xno" ; then | |||
fi | |||
AM_CONDITIONAL(EN_ENCR_SESSIONS,[test "x$have_gcrypt" = "xyes" ]) | |||
if test "x$enable_sqlite" != "xno" ; then | |||
AC_CHECK_LIB(sqlite3,sqlite3_open,[ | |||
have_sqlite3=yes | |||
LIBS="-lsqlite3 $LIBS" | |||
AC_DEFINE([EN_SQLITE_SESSIONS],[],["Enable sqlite sessions"]) | |||
], | |||
[ echo "=====================================================================" | |||
echo "libsqlite3 not found, Sqlite sessions backend is disabled" | |||
echo "=====================================================================" ]) | |||
fi | |||
AM_CONDITIONAL(EN_SQLITE_SESSIONS,[test "x$have_sqlite3" = "xyes" ]) | |||
have_auto_type_detection=no | |||
AC_TRY_COMPILE([],[int \$1=10;],[ | |||
@@ -226,12 +186,13 @@ then | |||
fi | |||
fi | |||
case $host in | |||
*cygwin*) CPPCMS_LIBS="-lws2_32 -lwsock32 $CPPCMS_LIBS" | |||
esac | |||
if test "x$have_asio" = "xyes" | |||
then | |||
AC_DEFINE([EN_TCP_CACHE],[],["Enable tcp cache"]) | |||
case $host in | |||
*cygwin*) LIBS="-lws2_32 $LIBS" | |||
esac | |||
fi | |||
@@ -250,34 +211,36 @@ then | |||
AC_SEARCH_LIBS(gethostbyname,nsl socket) | |||
fi | |||
if test "x$bsts" = "x" | |||
then | |||
AC_CHECK_LIB(boost_regex,main,[ | |||
CPPCMS_LIBS="-lboost_regex $CPPCMS_LIBS" | |||
], | |||
[AC_CHECK_LIB(boost_regex-gcc-mt,main,[ | |||
],[AC_CHECK_LIB(boost_regex-gcc-mt,main,[ | |||
CPPCMS_LIBS="-lboost_regex-gcc-mt $CPPCMS_LIBS" | |||
],[ echo "boost::regex not found" ; exit -1])]) | |||
if test "x$cms_bld" = "xnormal" | |||
then | |||
AC_CHECK_LIB(boost_iostreams,main,[ | |||
CPPCMS_LIBS="-lboost_iostreams $CPPCMS_LIBS" | |||
],[AC_CHECK_LIB(boost_iostreams-gcc-mt,main,[ | |||
CPPCMS_LIBS="-lboost_iostreams-gcc-mt $CPPCMS_LIBS" | |||
],[ echo "boost::iostreams not found" ; exit -1])]) | |||
fi | |||
AC_CHECK_LIB(boost_signals,main,[ | |||
CPPCMS_LIBS="-lboost_signals $CPPCMS_LIBS" | |||
],[AC_CHECK_LIB(boost_signals-gcc-mt,main,[ | |||
CPPCMS_LIBS="-lboost_signals-gcc-mt $CPPCMS_LIBS" | |||
],[ echo "boost::signals not found" ; exit -1])]) | |||
else | |||
CPPCMS_LIBS="-lboost_regex-$bsts -lboost_iostreams-$bsts -lboost_signals-$bsts $CPPCMS_LIBS" | |||
if test "x$cms_bld" = "xnormal" | |||
then | |||
CPPCMS_LIBS="-lboost_iostreams-$bsts CPPCMS_LIBS" | |||
fi | |||
fi | |||
AC_CHECK_LIB(boost_iostreams,main,[ | |||
CPPCMS_LIBS="-lboost_iostreams $CPPCMS_LIBS" | |||
],[AC_CHECK_LIB(boost_iostreams-gcc-mt,main,[ | |||
CPPCMS_LIBS="-lboost_iostreams-gcc-mt $CPPCMS_LIBS" | |||
],[ echo "boost::iostreams not found" ; exit -1])]) | |||
AC_CHECK_LIB(boost_system,main,[ | |||
CPPCMS_LIBS="-lboost_system $CPPCMS_LIBS" | |||
],[AC_CHECK_LIB(boost_system-gcc-mt,main,[ | |||
CPPCMS_LIBS="-lboost_system-gcc-mt $CPPCMS_LIBS" | |||
],[ echo "boost::system not found" ; exit -1])]) | |||
AC_CHECK_LIB(boost_thread,main,[ | |||
CPPCMS_LIBS="-lboost_thread $CPPCMS_LIBS" | |||
],[AC_CHECK_LIB(boost_thread-gcc-mt,main,[ | |||
CPPCMS_LIBS="-lboost_thread-gcc-mt $CPPCMS_LIBS" | |||
],[ echo "boost::thread not found" ; exit -1])]) | |||
AC_CHECK_LIB(boost_date_time,main,[ | |||
CPPCMS_LIBS="-lboost_date_time $CPPCMS_LIBS" | |||
],[AC_CHECK_LIB(boost_date_time-gcc-mt,main,[ | |||
CPPCMS_LIBS="-lboost_date_time-gcc-mt $CPPCMS_LIBS" | |||
],[ echo "boost::date_time not found" ; exit -1])]) | |||
CPPCMS_LIBS="$CPPCMS_LIBS $LIBS" | |||
TCPSCALE_LIBS="$LIBS" | |||
@@ -1,3 +1,4 @@ | |||
#define CPPCMS_SOURCE | |||
#include "cppcms_error.h" | |||
#include <iostream> | |||
#include <string.h> | |||
@@ -1,13 +1,14 @@ | |||
#ifndef CPPCMS_ERROR_H | |||
#define CPPCMS_ERROR_H | |||
#include "defs.h" | |||
#include <string> | |||
#include <stdexcept> | |||
namespace cppcms { | |||
class cppcms_error : public std::runtime_error { | |||
class CPPCMS_API cppcms_error : public std::runtime_error { | |||
std::string strerror(int err); | |||
public: | |||
cppcms_error(int err,std::string const &error); | |||
@@ -0,0 +1,21 @@ | |||
#include "cppcms_error_category.h" | |||
namespace cppcms { | |||
namespace impl { | |||
char const *error_category::name() const | |||
{ | |||
return "cppcms::io"; | |||
} | |||
std::string error_category::message(int cat) const | |||
{ | |||
switch(cat) { | |||
case errc::ok: return "ok"; | |||
case errc::protocol_violation: return "protocol violation"; | |||
default: | |||
return "unknown"; | |||
} | |||
} | |||
const error_category cppcms_category; | |||
} // impl | |||
} // cppcms |
@@ -13,19 +13,8 @@ namespace cppcms { | |||
} | |||
class error_category : public boost::system::error_category { | |||
public: | |||
virtual char const *name() const | |||
{ | |||
return "cppcms::io"; | |||
} | |||
virtual std::string message(int cat) const | |||
{ | |||
switch(cat) { | |||
case errc::ok: return "ok"; | |||
case errc::protocol_violation: return "protocol violation"; | |||
default: | |||
return "unknown"; | |||
} | |||
} | |||
virtual char const *name() const; | |||
virtual std::string message(int cat) const; | |||
}; | |||
extern const error_category cppcms_category; | |||
@@ -15,5 +15,19 @@ | |||
# define CPPCMS_API __attribute__((visibility("default"))) | |||
#endif | |||
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__) | |||
#define CPPCMS_WIN_NATIVE | |||
#endif | |||
#if defined(__CYGWIN__) | |||
#define CPPCMS_CYGWIN | |||
#endif | |||
#if defined(CPPCMS_WIN_NATIVE) || defined(CPPCMS_CYGWIN) | |||
#define CPPCMS_WIN32 | |||
#endif | |||
#if !defined(CPPCMS_WIN_NATIVE) | |||
#define CPPCMS_POSIX | |||
#endif | |||
#endif /// CPPCMS_DEFS_H |
@@ -1,3 +1,4 @@ | |||
#define CPPCMS_SOURCE | |||
#include "global_config.h" | |||
#include "cppcms_error.h" | |||
#include <map> | |||
@@ -1,180 +1,37 @@ | |||
#include "application.h" | |||
#include "manager.h" | |||
#include "hello_world_view.h" | |||
#include "regex.h" | |||
using namespace cppcms; | |||
#include "url_dispatcher.h" | |||
#include "applications_pool.h" | |||
#include "service.h" | |||
#include "http_response.h" | |||
class my_hello_world : public application { | |||
class hello : public cppcms::application { | |||
public: | |||
my_hello_world(worker_thread &w) : | |||
application(w) | |||
hello(cppcms::service &srv) : | |||
cppcms::application(srv) | |||
{ | |||
using util::regex; | |||
static const regex std("^/?$"); | |||
url.assign(std,&my_hello_world::std,this); | |||
static const regex test("^/test$"); | |||
url.assign(test,&my_hello_world::test,this); | |||
static const regex test2("^/test2$"); | |||
url.assign(test2,&my_hello_world::test2,this); | |||
static const regex cache("^/cache$"); | |||
url.assign(cache,&my_hello_world::cache_test,this); | |||
static const regex png("^/png$"); | |||
url.assign(png,&my_hello_world::png,this); | |||
use_template("view2"); | |||
}; | |||
void test(); | |||
void png(); | |||
void test2(); | |||
void std(); | |||
void cache_test(); | |||
}; | |||
void my_hello_world::png() | |||
{ | |||
ifstream file("test.png"); | |||
if(!file) { | |||
cout<<"File test.png not found"; | |||
return ; | |||
} | |||
vector<char> buffer(1024); | |||
set_header(new cgicc::HTTPContentHeader("image/png")); | |||
set_user_io(); | |||
ostream &cout=cgi_conn->cout(); | |||
for(;;) { | |||
file.read(&buffer.front(),1024); | |||
cout.write(&buffer.front(),file.gcount()); | |||
if(file.eof()) | |||
break; | |||
} | |||
file.close(); | |||
} | |||
void my_hello_world::test2() | |||
{ | |||
if(!session.is_set("test")) { | |||
session["test"]="1"; | |||
cout<<"Set 1"; | |||
} | |||
else { | |||
int state=session.get<int>("test"); | |||
switch(state) { | |||
case 1: | |||
if(!session.is_exposed("test")) { | |||
cout<<"Expose 1"; | |||
session.expose("test"); | |||
} | |||
else { | |||
session["test"]="2"; | |||
cout<<"Change exposed to 2"; | |||
} | |||
break; | |||
case 2: | |||
if(session.is_exposed("test")) { | |||
session.hide("test"); | |||
cout<<"Hidden 2"; | |||
} | |||
else { | |||
session["test"]="3"; | |||
cout<<"Hidden 2 moved to 3 and exposed"; | |||
session.expose("test"); | |||
} | |||
break; | |||
case 3: | |||
session.del("test"); | |||
cout<<"Remove 3 and remove from hidden"; | |||
break; | |||
default: | |||
cout<<"Error"; | |||
} | |||
} | |||
} | |||
void my_hello_world::test() | |||
{ | |||
if(!session.is_set("time")) { | |||
cout<<"No Time\n"; | |||
dispatcher().assign(".*",&hello::hello_world,this); | |||
} | |||
else { | |||
time_t given=session.get<time_t>("time"); | |||
cout<<asctime(gmtime(&given))<<"<br/>\n"; | |||
if(session.is_set("msg")) { | |||
cout<<session["msg"]<<"<br/>"; | |||
} | |||
if(given % 3 == 0) { | |||
cout<<"SET LONG MESSAGE"; | |||
session["msg"]="Looooooooooooooooooooooooooooooong msg"; | |||
} | |||
else { | |||
cout<<"UNSET LONG MESSAGE"; | |||
session.del("msg"); | |||
} | |||
cout<<"<br/>"<<endl; | |||
if(session.is_set("msg")) { | |||
int val=given % 2; | |||
session.expose("msg",val); | |||
cout<<(val ? "exposed" : "hidden")<<endl; | |||
} | |||
//session.clear(); | |||
} | |||
session.set<time_t>("time",time(NULL)); | |||
} | |||
void my_hello_world::std() | |||
{ | |||
view::hello v(this); | |||
if(env->getRequestMethod()=="POST") { | |||
v.form.load(*cgi); | |||
if(v.form.validate()) { | |||
session["name"]=v.form.username.get(); | |||
v.username=v.form.username.get(); | |||
v.realname=v.form.name.get(); | |||
v.ok=v.form.ok.get(); | |||
v.password=v.form.p1.get(); | |||
v.form.clear(); | |||
} | |||
void hello_world() | |||
{ | |||
response().out() << | |||
"<html><body>\n" | |||
"<h1>Hello World!</h1>\n" | |||
"<body></html>\n"; | |||
} | |||
}; | |||
v.title="Cool"; | |||
if(session.is_set("name")) | |||
v.title+=":"+session["name"]; | |||
v.msg=gettext("Hello World"); | |||
for(int i=0;i<15;i++) | |||
v.numbers.push_back(i); | |||
v.lst.push_back(view::data("Hello",10)); | |||
render("hello",v); | |||
} | |||
void my_hello_world::cache_test() | |||
{ | |||
string tmp; | |||
bool from_cache=true; | |||
if(!cache.fetch_frame("test",tmp,true)) { | |||
tmp="test value"; | |||
from_cache=false; | |||
cache.store_frame("test",tmp,5); | |||
} | |||
if(from_cache) | |||
cout <<"Fetched ["<<tmp<<"] from cache"; | |||
else | |||
cout <<"Fetched ["<<tmp<<"] from start"; | |||
} | |||
int main(int argc,char ** argv) | |||
int main(int argc,char **argv) | |||
{ | |||
try { | |||
manager app(argc,argv); | |||
app.set_worker(new application_factory<my_hello_world>()); | |||
app.execute(); | |||
cppcms::service service(argc,argv); | |||
service.applications_pool().mount(".*",cppcms::applications_factory<hello>()); | |||
service.run(); | |||
} | |||
catch(std::exception const &e) { | |||
cerr<<e.what()<<endl; | |||
std::cerr<<e.what()<<std::endl; | |||
return 1; | |||
} | |||
return 0; | |||
} |
@@ -0,0 +1,55 @@ | |||
#define CPPCMS_SOURCE | |||
#include "cgi_api.h" | |||
#include "service.h" | |||
#include "http_context.h" | |||
#include "http_request.h" | |||
#include "http_response.h" | |||
namespace cppcms { | |||
namespace http { | |||
struct context::data { | |||
http::request request; | |||
http::response response; | |||
data(context &cntx) : | |||
request(cntx.connection()), | |||
response(cntx) | |||
{ | |||
} | |||
}; | |||
context::context(impl::cgi::connection *conn) : | |||
conn_(conn) | |||
{ | |||
d.reset(new data(*this)); | |||
} | |||
context::~context() | |||
{ | |||
} | |||
impl::cgi::connection &context::connection() | |||
{ | |||
return *conn_; | |||
} | |||
http::request &context::request() | |||
{ | |||
return d->request; | |||
} | |||
http::response &context::response() | |||
{ | |||
return d->response; | |||
} | |||
cppcms_config const &context::settings() | |||
{ | |||
return conn_->service().settings(); | |||
} | |||
} // http | |||
} // cppcms |
@@ -16,11 +16,13 @@ namespace cppcms { | |||
class CPPCMS_API context : private util::noncopyable { | |||
struct data; | |||
util::hold_ptr<data> d_; | |||
util::hold_ptr<data> d; | |||
impl::cgi::connection *conn_; | |||
public: | |||
context(impl::cgi::connection *conn); | |||
~context(); | |||
impl::cgi::connection &connection(); | |||
http::request &request(); | |||
http::response &response(); | |||
cppcms_config const &settings(); | |||
@@ -1,3 +1,4 @@ | |||
#define CPPCMS_SOURCE | |||
#include "http_cookie.h" | |||
#include "http_protocol.h" | |||
#include "cppcms_error.h" | |||
@@ -1,3 +1,4 @@ | |||
#define CPPCMS_SOURCE | |||
#include "cgi_api.h" | |||
#include "http_request.h" | |||
#include "http_cookie.h" | |||
@@ -1,19 +1,22 @@ | |||
#define CPPCMS_SOURCE | |||
#include <iostream> | |||
#include <sstream> | |||
#include <iterator> | |||
#include <map> | |||
#include "cgi_api.h" | |||
#include "http_response.h" | |||
#include "http_context.h" | |||
#include "http_request.h" | |||
#include "http_cookie.h" | |||
#include "global_config.h" | |||
#include "cppcms_error.h" | |||
#include "util.h" | |||
#include "service.h" | |||
#include "config.h" | |||
#include "util.h" | |||
#include <iostream> | |||
#include <sstream> | |||
#include <iterator> | |||
#include <map> | |||
#include <boost/lexical_cast.hpp> | |||
#include <boost/iostreams/stream.hpp> | |||
#include <boost/iostreams/filtering_stream.hpp> | |||
#include <boost/iostreams/filter/gzip.hpp> | |||
#include <boost/iostreams/tee.hpp> | |||
@@ -43,13 +46,13 @@ namespace { | |||
namespace { | |||
struct output_device : public boost::iostreams::sink { | |||
class output_device : public boost::iostreams::sink { | |||
impl::cgi::connection *conn_; | |||
public: | |||
output_device(impl::cgi::connection *conn) : conn_(conn) {} | |||
std::streamsize write(char const *data,std::streamsize n) | |||
{ | |||
size_t all=0; | |||
std::streamsize all=0; | |||
while(all < n) | |||
all += conn_->write_some(data,n); | |||
return all; | |||
@@ -77,7 +80,7 @@ struct response::data { | |||
response::response(context &context) : | |||
d(new data(context.connection())), | |||
d(new data(&context.connection())), | |||
context_(context), | |||
stream_(0), | |||
io_mode_(normal), | |||
@@ -91,6 +94,10 @@ response::response(context &context) : | |||
} | |||
} | |||
response::~response() | |||
{ | |||
} | |||
void response::set_content_header(std::string const &content_type) | |||
{ | |||
std::string charset=context_.settings().str("l10n.charset",""); | |||
@@ -190,7 +197,7 @@ void response::write_http_headers(std::ostream &stream) | |||
out<<d->cookies[i]<<"\r\n"; | |||
} | |||
out<<"\r\n"; | |||
out<<flush; | |||
out<<std::flush; | |||
} | |||
@@ -207,11 +214,16 @@ std::ostream &response::out() | |||
if(ostream_requested_) | |||
return *stream_; | |||
std::ostream &real_sink = io_mode_ == asynchronous ? d->buffered : d->output ; | |||
std::ostream *real_sink = 0; | |||
if(io_mode_ == asynchronous) | |||
real_sink = &d->buffered; | |||
else | |||
real_sink = &d->output; | |||
ostream_requested_=1; | |||
write_http_headers(real_sink); | |||
write_http_headers(*real_sink); | |||
if(need_gzip()) { | |||
gzip_params params; | |||
@@ -234,9 +246,9 @@ std::ostream &response::out() | |||
} | |||
if(stream_) | |||
d->filter.push(real_sink); | |||
d->filter.push(*real_sink); | |||
else | |||
stream_=&real_sink; | |||
stream_=real_sink; | |||
return *stream_; | |||
} | |||
@@ -248,7 +260,7 @@ std::string response::get_async_chunk() | |||
return result; | |||
} | |||
bool result::some_output_was_written() | |||
bool response::some_output_was_written() | |||
{ | |||
return ostream_requested_; | |||
} | |||
@@ -62,8 +62,6 @@ namespace http { | |||
// synchronous io | |||
normal, // write request, use buffering, possible compression, | |||
nogzip, // as normal but disable gzip | |||
direct, // use direct connection for transferring huge | |||
// amount of data, for example big csv, file download | |||
asynchronous, | |||
// the data is buffered and never transferred | |||
// untill it is requested explicitly | |||
@@ -63,8 +63,8 @@ server.bind = "127.0.0.1" | |||
fastcgi.server = ( "/hello" => ( "localhost" => ( | |||
"check-local" => "disable", | |||
# "host" => "127.0.0.1", | |||
# "port" => 8000 | |||
"socket" => "/tmp/hello-fastcgi.socket" | |||
"host" => "127.0.0.1", | |||
"port" => 8000 | |||
# "socket" => "/tmp/hello-fastcgi.socket" | |||
))) | |||
@@ -130,7 +130,7 @@ namespace cgi { | |||
typedef scgi<boost::asio::ip::tcp> tcp_socket_scgi; | |||
typedef tcp_socket_acceptor<tcp_socket_scgi> tcp_socket_scgi_acceptor; | |||
#if !defined(_WIN32) && !defined(__CYGWIN__) | |||
#if !defined(CPPCMS_WIN32) | |||
typedef scgi<boost::asio::local::stream_protocol> unix_socket_scgi; | |||
typedef unix_socket_acceptor<unix_socket_scgi> unix_socket_scgi_acceptor; | |||
#endif | |||
@@ -11,7 +11,7 @@ | |||
#include "asio_config.h" | |||
#if !defined(_WIN32) && !defined(__CYGWIN__) | |||
#ifdef CPPCMS_POSIX | |||
#include <sys/wait.h> | |||
#endif | |||
@@ -37,7 +37,7 @@ int service::threads_no() | |||
} | |||
namespace { | |||
#if defined(__CYGWIN__) || defined(_WIN32) | |||
#if defined(CPPCMS_WIN32) | |||
void make_socket_pair(boost::asio::ip::tcp::socket &s1,boost::asio::ip::tcp::socket &s2) | |||
{ | |||
boost::asio::ip::tcp::acceptor acceptor(s1.get_io_service(), | |||
@@ -81,7 +81,7 @@ namespace { | |||
#endif | |||
} // anon | |||
#ifdef _WIN32 | |||
#ifdef CPPCMS_WIN_NATIVE | |||
void service::setup_exit_handling() | |||
{ | |||
throw cppcms_error("TODO Setup exit handling"); | |||
@@ -90,18 +90,9 @@ void service::setup_exit_handling() | |||
#else | |||
void service::setup_exit_handling() | |||
{ | |||
sigset_t set; | |||
sigemptyset(&set); | |||
sigaddset(&set,SIGINT); | |||
sigaddset(&set,SIGTERM); | |||
sigaddset(&set,SIGUSR1); | |||
pthread_sigmask(SIG_BLOCK,&set,0); | |||
make_socket_pair(impl_->sig_,impl_->breaker_); | |||
static char c; | |||
@@ -112,8 +103,10 @@ void service::setup_exit_handling() | |||
notification_socket=impl_->sig_.native(); | |||
struct sigaction sa; | |||
memset(&sa,0,sizeof(sa)); | |||
sa.sa_handler=handler; | |||
sigaction(SIGINT,&sa,0); | |||
sigaction(SIGTERM,&sa,0); | |||
sigaction(SIGUSR1,&sa,0); | |||
@@ -131,6 +124,7 @@ void service::run() | |||
impl_->acceptor_->async_accept(); | |||
setup_exit_handling(); | |||
impl_->get_io_service().run(); | |||
} | |||
@@ -139,14 +133,14 @@ int service::procs_no() | |||
int procs=settings().integer("service.procs",0); | |||
if(procs < 0) | |||
procs = 0; | |||
#if defined(_WIN32) || defined(__CYGWIN) | |||
#ifdef CPPCMS_WIN32 | |||
if(procs > 0) | |||
throw cppcms_error("Prefork is not supported under Windows"); | |||
#endif | |||
return procs; | |||
} | |||
#if defined(_WIN32) || defined(__CYGWIN__) | |||
#ifdef CPPCMS_WIN32 | |||
bool service::prefork() | |||
{ | |||
procs_no(); | |||
@@ -228,9 +222,9 @@ void service::start_acceptor() | |||
throw cppcms_error("Unknown service.api: " + api); | |||
} | |||
else { | |||
#ifdef _WIN32 | |||
#ifdef CPPCMS_WIN_NATIVE | |||
throw cppcms_error("Unix domain sockets are not supported under Windows... (isn't it obvious?)"); | |||
#elif defined(__CYGWIN__) | |||
#elif defined CPPCMS_CYGWIN | |||
throw cppcms_error("CppCMS uses native Win32 sockets under cygwin, so Unix sockets are not supported"); | |||
#else | |||
if(api=="scgi") | |||
@@ -267,10 +261,14 @@ cppcms::impl::service &service::impl() | |||
void service::stop() | |||
{ | |||
std::cout<<"Shutting down"<<std::endl; | |||
if(impl_->acceptor_.get()) | |||
impl_->acceptor_->stop(); | |||
std::cout<<"Acceptor down"<<std::endl; | |||
thread_pool().stop(); | |||
std::cout<<"Thread pool"<<std::endl; | |||
impl_->get_io_service().stop(); | |||
std::cout<<"Io Service down"<<std::endl; | |||
} | |||
namespace impl { | |||
@@ -34,7 +34,7 @@ namespace impl { | |||
std::auto_ptr<thread_pool> thread_pool_; | |||
boost::asio::io_service io_service_; | |||
#if defined(__CYGWIN__) || defined(_WIN32) | |||
#ifdef CPPCMS_WIN32 | |||
boost::asio::ip::tcp::socket sig_,breaker_; | |||
#else | |||
boost::asio::local::stream_protocol::socket sig_,breaker_; | |||
@@ -19,7 +19,7 @@ namespace impl { | |||
thread_pool(int threads) | |||
{ | |||
workers_.resize(threads); | |||
#ifndef _WIN32 | |||
#if !defined(CPPCMS_WIN_NATIVE) | |||
sigset_t set,old; | |||
sigfillset(&set); | |||
pthread_sigmask(SIG_BLOCK,&set,&old); | |||
@@ -28,7 +28,7 @@ namespace impl { | |||
workers_[i].reset(new boost::thread(boost::bind(&thread_pool::worker,this))); | |||
} | |||
#ifndef _WIN32 | |||
#if !defined(CPPCMS_WIN_NATIVE) | |||
pthread_sigmask(SIG_SETMASK,&old,0); | |||
#endif | |||
@@ -35,8 +35,8 @@ namespace cppcms { | |||
struct mounted : public option { | |||
mounted(std::string expr,int select,application *app) : | |||
option(expr), | |||
select_(select), | |||
app_(app) | |||
app_(app), | |||
select_(select) | |||
{ | |||
} | |||