diff --git a/src/neutrino.cpp b/src/neutrino.cpp index 84d680e7b..c760ece20 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -144,8 +144,6 @@ void * timerd_main_thread(void *data); static bool timerd_thread_started = false; void * nhttpd_main_thread(void *data); -static pthread_t nhttpd_thread ; -static bool nhttpd_thread_started = false; //#define DISABLE_SECTIONSD @@ -1955,8 +1953,9 @@ TIMER_START(); dvbsub_init(); - pthread_create (&nhttpd_thread, NULL, nhttpd_main_thread, (void *) NULL); - nhttpd_thread_started = true; + pthread_t nhttpd_thread; + if (!pthread_create (&nhttpd_thread, NULL, nhttpd_main_thread, (void *) NULL)) + pthread_detach (nhttpd_thread); CStreamManager::getInstance()->Start(); @@ -3793,12 +3792,6 @@ void stop_daemons(bool stopall, bool for_flash) delete g_Radiotext; g_Radiotext = NULL; } - printf("httpd shutdown\n"); - if (nhttpd_thread_started) { - pthread_cancel(nhttpd_thread); - pthread_join(nhttpd_thread, NULL); - } - printf("httpd shutdown done\n"); printf("streaming shutdown\n"); CStreamManager::getInstance()->Stop(); printf("streaming shutdown done\n"); diff --git a/src/nhttpd/yconfig.h b/src/nhttpd/yconfig.h index 7e249ab98..96776847e 100644 --- a/src/nhttpd/yconfig.h +++ b/src/nhttpd/yconfig.h @@ -61,14 +61,15 @@ #define Y_CONFIG_FEATUE_SENDFILE_CAN_ACCESS_ALL y // Add Feature: every file can be accessed (use carefully: security!!) //#define Y_CONFIG_FEATURE_CHROOT y // Add Feature: Use Change Root for Security //#define Y_CONFIG_FEATURE_HTTPD_USER y // Add Feature: Set User for yhttpd-Process -#define Y_CONFIG_BUILD_AS_DAEMON y // Build as a Daemon with possibility for multi threading +#define Y_CONFIG_BUILD_AS_DAEMON y // Build as a Daemon +#define Y_CONFIG_FEATURE_THREADING y // Build with possibility for multi threading //----------------------------------------------------------------------------- // Define/Undefine Features forced by CONFIG_SYSTEM_xxx // Dependencies //----------------------------------------------------------------------------- -#ifdef Y_CONFIG_USE_OPEN_SSL -#undef Y_CONFIG_HAVE_SENDFILE // Sendfile does not work for SSL -#endif +//#ifdef Y_CONFIG_USE_OPEN_SSL +//#undef Y_CONFIG_HAVE_SENDFILE // Sendfile does not work for SSL, but we'll fallback to send +//#endif #if defined(CONFIG_SYSTEM_TUXBOX) || defined(CONFIG_SYSTEM_TUXBOX_COOLSTREAM) #define Y_CONFIG_FEATURE_UPLOAD y diff --git a/src/nhttpd/yhttpd.cpp b/src/nhttpd/yhttpd.cpp index 718728c1c..d0ceba730 100644 --- a/src/nhttpd/yhttpd.cpp +++ b/src/nhttpd/yhttpd.cpp @@ -12,6 +12,7 @@ #include #include +#include // yhttpd #include "yconfig.h" #include @@ -105,9 +106,22 @@ void yhttpd_reload_config() { //----------------------------------------------------------------------------- // Main Entry //----------------------------------------------------------------------------- + +void thread_cleanup (void *p) +{ + Cyhttpd *y = (Cyhttpd *)p; + if (y) { + y->stop_webserver(); + delete y; + } + y = NULL; +} + #ifndef Y_CONFIG_BUILD_AS_DAEMON void * nhttpd_main_thread(void *) { + set_threadname(__func__); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0); + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); aprintf("Webserver %s tid %ld\n", WEBSERVERNAME, syscall(__NR_gettid)); yhttpd = new Cyhttpd(); //CLogging::getInstance()->setDebug(true); @@ -116,7 +130,11 @@ void * nhttpd_main_thread(void *) { aprintf("Error initializing WebServer\n"); return (void *) EXIT_FAILURE; } + /* we pthread_cancel this thread from the main thread, but still want to clean up */ + pthread_cleanup_push(thread_cleanup, yhttpd); +#ifndef Y_CONFIG_FEATURE_THREADING yhttpd->flag_threading_off = true; +#endif yhttpd->hooks_attach(); yhttpd->ReadConfig(); @@ -127,7 +145,9 @@ void * nhttpd_main_thread(void *) { yhttpd->run(); } + pthread_cleanup_pop(0); delete yhttpd; + yhttpd = NULL; aprintf("Main end\n"); return (void *) EXIT_SUCCESS; @@ -235,6 +255,7 @@ Cyhttpd::Cyhttpd() { Cyhttpd::~Cyhttpd() { if (webserver) delete webserver; + CLanguage::deleteInstance(); webserver = NULL; } @@ -316,6 +337,7 @@ bool Cyhttpd::Configure() { // Main Webserver call //----------------------------------------------------------------------------- void Cyhttpd::run() { + set_threadname(__func__); if (webserver) { if (flag_threading_off) webserver->is_threading = false; @@ -439,7 +461,7 @@ void Cyhttpd::ReadConfig(void) { log_level_printf(3, "ReadConfig Start\n"); CConfigFile *Config = new CConfigFile(','); bool have_config = false; - if (access(HTTPD_CONFIGFILE, 4) == 0) + if (access(HTTPD_CONFIGFILE, R_OK) == 0) have_config = true; Config->loadConfig(HTTPD_CONFIGFILE); // convert old config files @@ -527,16 +549,16 @@ void Cyhttpd::ReadConfig(void) { // Check location of logos if (Config->getString("Tuxbox.LogosURL", "") == "") { - if (access(std::string(ConfigList["WebsiteMain.override_directory"] + "/logos").c_str(), 4) == 0) { + if (access(std::string(ConfigList["WebsiteMain.override_directory"] + "/logos").c_str(), R_OK) == 0) { Config->setString("Tuxbox.LogosURL", ConfigList["WebsiteMain.override_directory"] + "/logos"); have_config = false; //save config } - else if (access(std::string(ConfigList["WebsiteMain.directory"] + "/logos").c_str(), 4) == 0){ + else if (access(std::string(ConfigList["WebsiteMain.directory"] + "/logos").c_str(), R_OK) == 0) { Config->setString("Tuxbox.LogosURL", ConfigList["WebsiteMain.directory"] + "/logos"); have_config = false; //save config } #ifdef Y_CONFIG_USE_HOSTEDWEB - else if (access(std::string(ConfigList["WebsiteMain.hosted_directory"] + "/logos").c_str(), 4) == 0){ + else if (access(std::string(ConfigList["WebsiteMain.hosted_directory"] + "/logos").c_str(), R_OK) == 0) { Config->setString("Tuxbox.LogosURL", ConfigList["WebsiteMain.hosted_directory"] + "/logos"); have_config = false; //save config } diff --git a/src/nhttpd/yhttpd_core/ysocket.cpp b/src/nhttpd/yhttpd_core/ysocket.cpp index d39a1b914..e21eb2cff 100644 --- a/src/nhttpd/yhttpd_core/ysocket.cpp +++ b/src/nhttpd/yhttpd_core/ysocket.cpp @@ -229,7 +229,7 @@ bool CySocket::set_option(int typ, int option) { void CySocket::set_reuse_port() { #ifdef SO_REUSEPORT if(!set_option(SOL_SOCKET, SO_REUSEPORT)) - dperror("setsockopt(SO_REUSEPORT)\n"); + dperror("setsockopt(SO_REUSEPORT)\n"); #endif } @@ -239,7 +239,7 @@ void CySocket::set_reuse_port() { void CySocket::set_reuse_addr() { #ifdef SO_REUSEADDR if(!set_option(SOL_SOCKET, SO_REUSEADDR)) - dperror("setsockopt(SO_REUSEADDR)\n"); + dperror("setsockopt(SO_REUSEADDR)\n"); #endif } @@ -249,7 +249,7 @@ void CySocket::set_reuse_addr() { void CySocket::set_keep_alive() { #ifdef SO_KEEPALIVE if(!set_option(SOL_SOCKET, SO_KEEPALIVE)) - dperror("setsockopt(SO_KEEPALIVE)\n"); + dperror("setsockopt(SO_KEEPALIVE)\n"); #endif } @@ -259,7 +259,7 @@ void CySocket::set_keep_alive() { void CySocket::set_tcp_nodelay() { #ifdef TCP_NODELAY if(!set_option(IPPROTO_TCP, TCP_NODELAY)) - dperror("setsockopt(SO_KEEPALIVE)\n"); + dperror("setsockopt(SO_KEEPALIVE)\n"); #endif } //============================================================================= @@ -271,10 +271,10 @@ void CySocket::set_tcp_nodelay() { int CySocket::Read(char *buffer, unsigned int length) { #ifdef Y_CONFIG_USE_OPEN_SSL if(isSSLSocket) - return SSL_read(ssl, buffer, length); + return SSL_read(ssl, buffer, length); else #endif - return ::read(sock, buffer, length); + return ::read(sock, buffer, length); } //----------------------------------------------------------------------------- // Send a buffer (normal or SSL) @@ -283,7 +283,7 @@ int CySocket::Send(char const *buffer, unsigned int length) { unsigned int len = 0; #ifdef Y_CONFIG_USE_OPEN_SSL if(isSSLSocket) - len = SSL_write(ssl, buffer, length); + len = SSL_write(ssl, buffer, length); else #endif len = ::send(sock, buffer, length, MSG_NOSIGNAL); @@ -323,6 +323,9 @@ bool CySocket::SendFile(int filed, off_t start, off_t size) { if (size > -1 && size < left) left = size; #ifdef Y_CONFIG_HAVE_SENDFILE +#ifdef Y_CONFIG_USE_OPEN_SSL + if(!isSSLSocket) +#endif while (left > 0) { // split sendfile() transfer to smaller chunks to reduce memory-mapping requirements if((written = ::sendfile(sock, filed, &start, std::min((off_t) 0x8000000LL, left))) == -1) { @@ -334,7 +337,7 @@ bool CySocket::SendFile(int filed, off_t start, off_t size) { } else { BytesSend += written; left -= written; - } + } } #endif // Y_CONFIG_HAVE_SENDFILE if (left > 0) { @@ -347,7 +350,6 @@ bool CySocket::SendFile(int filed, off_t start, off_t size) { perror("send failed"); return false; } - BytesSend += written; left -= written; } } @@ -372,7 +374,7 @@ unsigned int CySocket::ReceiveFileGivenLength(int filed, unsigned int _length) { u_long readarg = 0; #ifdef Y_CONFIG_USE_OPEN_SSL if(isSSLSocket) - readarg = RECEIVE_BLOCK_LEN; + readarg = RECEIVE_BLOCK_LEN; else #endif { diff --git a/src/nhttpd/yhttpd_core/ywebserver.cpp b/src/nhttpd/yhttpd_core/ywebserver.cpp index c360b75ca..9219c54ee 100644 --- a/src/nhttpd/yhttpd_core/ywebserver.cpp +++ b/src/nhttpd/yhttpd_core/ywebserver.cpp @@ -48,7 +48,7 @@ CWebserver::CWebserver() { FD_ZERO(&read_fds); fdmax = 0; open_connections = 0; -#ifdef Y_CONFIG_BUILD_AS_DAEMON +#ifdef Y_CONFIG_FEATURE_THREADING pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); #endif @@ -412,13 +412,13 @@ bool CWebserver::handle_connection(CySocket *newSock) { newConn->ySock = newSock; newConn->ySock->handling = true; newConn->WebserverBackref = this; -#ifdef Y_CONFIG_BUILD_AS_DAEMON +#ifdef Y_CONFIG_FEATURE_THREADING newConn->is_treaded = is_threading; #else newConn->is_treaded = false; #endif int index = -1; -#ifdef Y_CONFIG_BUILD_AS_DAEMON +#ifdef Y_CONFIG_FEATURE_THREADING if(is_threading) { pthread_mutex_lock( &mutex ); @@ -442,7 +442,7 @@ bool CWebserver::handle_connection(CySocket *newSock) { // start connection Thread if(pthread_create(&Connection_Thread_List[index], &attr, WebThread, (void *)newConn) != 0) - dperror("Could not create Connection-Thread\n"); + dperror("Could not create Connection-Thread\n"); } else // non threaded #endif