mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-28 16:01:20 +02:00
- nhttp: enable threading
This is ported from neutrino-mp and contains code by martii and seife from following commits: 20d3031b8bb47b5af79bf10c385e3564fe5c26dc93d01c1987
363633dc1b
c3e1310a2f727e26ce11669e3aeae78305f87049
This commit is contained in:
@@ -144,8 +144,6 @@ void * timerd_main_thread(void *data);
|
|||||||
static bool timerd_thread_started = false;
|
static bool timerd_thread_started = false;
|
||||||
|
|
||||||
void * nhttpd_main_thread(void *data);
|
void * nhttpd_main_thread(void *data);
|
||||||
static pthread_t nhttpd_thread ;
|
|
||||||
static bool nhttpd_thread_started = false;
|
|
||||||
|
|
||||||
//#define DISABLE_SECTIONSD
|
//#define DISABLE_SECTIONSD
|
||||||
|
|
||||||
@@ -1955,8 +1953,9 @@ TIMER_START();
|
|||||||
|
|
||||||
dvbsub_init();
|
dvbsub_init();
|
||||||
|
|
||||||
pthread_create (&nhttpd_thread, NULL, nhttpd_main_thread, (void *) NULL);
|
pthread_t nhttpd_thread;
|
||||||
nhttpd_thread_started = true;
|
if (!pthread_create (&nhttpd_thread, NULL, nhttpd_main_thread, (void *) NULL))
|
||||||
|
pthread_detach (nhttpd_thread);
|
||||||
|
|
||||||
CStreamManager::getInstance()->Start();
|
CStreamManager::getInstance()->Start();
|
||||||
|
|
||||||
@@ -3793,12 +3792,6 @@ void stop_daemons(bool stopall, bool for_flash)
|
|||||||
delete g_Radiotext;
|
delete g_Radiotext;
|
||||||
g_Radiotext = NULL;
|
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");
|
printf("streaming shutdown\n");
|
||||||
CStreamManager::getInstance()->Stop();
|
CStreamManager::getInstance()->Stop();
|
||||||
printf("streaming shutdown done\n");
|
printf("streaming shutdown done\n");
|
||||||
|
@@ -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_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_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_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
|
// Define/Undefine Features forced by CONFIG_SYSTEM_xxx
|
||||||
// Dependencies
|
// Dependencies
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#ifdef Y_CONFIG_USE_OPEN_SSL
|
//#ifdef Y_CONFIG_USE_OPEN_SSL
|
||||||
#undef Y_CONFIG_HAVE_SENDFILE // Sendfile does not work for SSL
|
//#undef Y_CONFIG_HAVE_SENDFILE // Sendfile does not work for SSL, but we'll fallback to send
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
#if defined(CONFIG_SYSTEM_TUXBOX) || defined(CONFIG_SYSTEM_TUXBOX_COOLSTREAM)
|
#if defined(CONFIG_SYSTEM_TUXBOX) || defined(CONFIG_SYSTEM_TUXBOX_COOLSTREAM)
|
||||||
#define Y_CONFIG_FEATURE_UPLOAD y
|
#define Y_CONFIG_FEATURE_UPLOAD y
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
#include <syscall.h>
|
#include <syscall.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <system/set_threadname.h>
|
||||||
// yhttpd
|
// yhttpd
|
||||||
#include "yconfig.h"
|
#include "yconfig.h"
|
||||||
#include <ylogging.h>
|
#include <ylogging.h>
|
||||||
@@ -105,9 +106,22 @@ void yhttpd_reload_config() {
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Main Entry
|
// 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
|
#ifndef Y_CONFIG_BUILD_AS_DAEMON
|
||||||
void * nhttpd_main_thread(void *) {
|
void * nhttpd_main_thread(void *) {
|
||||||
|
set_threadname(__func__);
|
||||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
||||||
|
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||||
aprintf("Webserver %s tid %ld\n", WEBSERVERNAME, syscall(__NR_gettid));
|
aprintf("Webserver %s tid %ld\n", WEBSERVERNAME, syscall(__NR_gettid));
|
||||||
yhttpd = new Cyhttpd();
|
yhttpd = new Cyhttpd();
|
||||||
//CLogging::getInstance()->setDebug(true);
|
//CLogging::getInstance()->setDebug(true);
|
||||||
@@ -116,7 +130,11 @@ void * nhttpd_main_thread(void *) {
|
|||||||
aprintf("Error initializing WebServer\n");
|
aprintf("Error initializing WebServer\n");
|
||||||
return (void *) EXIT_FAILURE;
|
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;
|
yhttpd->flag_threading_off = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
yhttpd->hooks_attach();
|
yhttpd->hooks_attach();
|
||||||
yhttpd->ReadConfig();
|
yhttpd->ReadConfig();
|
||||||
@@ -127,7 +145,9 @@ void * nhttpd_main_thread(void *) {
|
|||||||
|
|
||||||
yhttpd->run();
|
yhttpd->run();
|
||||||
}
|
}
|
||||||
|
pthread_cleanup_pop(0);
|
||||||
delete yhttpd;
|
delete yhttpd;
|
||||||
|
yhttpd = NULL;
|
||||||
|
|
||||||
aprintf("Main end\n");
|
aprintf("Main end\n");
|
||||||
return (void *) EXIT_SUCCESS;
|
return (void *) EXIT_SUCCESS;
|
||||||
@@ -235,6 +255,7 @@ Cyhttpd::Cyhttpd() {
|
|||||||
Cyhttpd::~Cyhttpd() {
|
Cyhttpd::~Cyhttpd() {
|
||||||
if (webserver)
|
if (webserver)
|
||||||
delete webserver;
|
delete webserver;
|
||||||
|
CLanguage::deleteInstance();
|
||||||
webserver = NULL;
|
webserver = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,6 +337,7 @@ bool Cyhttpd::Configure() {
|
|||||||
// Main Webserver call
|
// Main Webserver call
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Cyhttpd::run() {
|
void Cyhttpd::run() {
|
||||||
|
set_threadname(__func__);
|
||||||
if (webserver) {
|
if (webserver) {
|
||||||
if (flag_threading_off)
|
if (flag_threading_off)
|
||||||
webserver->is_threading = false;
|
webserver->is_threading = false;
|
||||||
@@ -439,7 +461,7 @@ void Cyhttpd::ReadConfig(void) {
|
|||||||
log_level_printf(3, "ReadConfig Start\n");
|
log_level_printf(3, "ReadConfig Start\n");
|
||||||
CConfigFile *Config = new CConfigFile(',');
|
CConfigFile *Config = new CConfigFile(',');
|
||||||
bool have_config = false;
|
bool have_config = false;
|
||||||
if (access(HTTPD_CONFIGFILE, 4) == 0)
|
if (access(HTTPD_CONFIGFILE, R_OK) == 0)
|
||||||
have_config = true;
|
have_config = true;
|
||||||
Config->loadConfig(HTTPD_CONFIGFILE);
|
Config->loadConfig(HTTPD_CONFIGFILE);
|
||||||
// convert old config files
|
// convert old config files
|
||||||
@@ -527,16 +549,16 @@ void Cyhttpd::ReadConfig(void) {
|
|||||||
|
|
||||||
// Check location of logos
|
// Check location of logos
|
||||||
if (Config->getString("Tuxbox.LogosURL", "") == "") {
|
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");
|
Config->setString("Tuxbox.LogosURL", ConfigList["WebsiteMain.override_directory"] + "/logos");
|
||||||
have_config = false; //save config
|
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");
|
Config->setString("Tuxbox.LogosURL", ConfigList["WebsiteMain.directory"] + "/logos");
|
||||||
have_config = false; //save config
|
have_config = false; //save config
|
||||||
}
|
}
|
||||||
#ifdef Y_CONFIG_USE_HOSTEDWEB
|
#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");
|
Config->setString("Tuxbox.LogosURL", ConfigList["WebsiteMain.hosted_directory"] + "/logos");
|
||||||
have_config = false; //save config
|
have_config = false; //save config
|
||||||
}
|
}
|
||||||
|
@@ -229,7 +229,7 @@ bool CySocket::set_option(int typ, int option) {
|
|||||||
void CySocket::set_reuse_port() {
|
void CySocket::set_reuse_port() {
|
||||||
#ifdef SO_REUSEPORT
|
#ifdef SO_REUSEPORT
|
||||||
if(!set_option(SOL_SOCKET, SO_REUSEPORT))
|
if(!set_option(SOL_SOCKET, SO_REUSEPORT))
|
||||||
dperror("setsockopt(SO_REUSEPORT)\n");
|
dperror("setsockopt(SO_REUSEPORT)\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +239,7 @@ void CySocket::set_reuse_port() {
|
|||||||
void CySocket::set_reuse_addr() {
|
void CySocket::set_reuse_addr() {
|
||||||
#ifdef SO_REUSEADDR
|
#ifdef SO_REUSEADDR
|
||||||
if(!set_option(SOL_SOCKET, SO_REUSEADDR))
|
if(!set_option(SOL_SOCKET, SO_REUSEADDR))
|
||||||
dperror("setsockopt(SO_REUSEADDR)\n");
|
dperror("setsockopt(SO_REUSEADDR)\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,7 +249,7 @@ void CySocket::set_reuse_addr() {
|
|||||||
void CySocket::set_keep_alive() {
|
void CySocket::set_keep_alive() {
|
||||||
#ifdef SO_KEEPALIVE
|
#ifdef SO_KEEPALIVE
|
||||||
if(!set_option(SOL_SOCKET, SO_KEEPALIVE))
|
if(!set_option(SOL_SOCKET, SO_KEEPALIVE))
|
||||||
dperror("setsockopt(SO_KEEPALIVE)\n");
|
dperror("setsockopt(SO_KEEPALIVE)\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,7 +259,7 @@ void CySocket::set_keep_alive() {
|
|||||||
void CySocket::set_tcp_nodelay() {
|
void CySocket::set_tcp_nodelay() {
|
||||||
#ifdef TCP_NODELAY
|
#ifdef TCP_NODELAY
|
||||||
if(!set_option(IPPROTO_TCP, TCP_NODELAY))
|
if(!set_option(IPPROTO_TCP, TCP_NODELAY))
|
||||||
dperror("setsockopt(SO_KEEPALIVE)\n");
|
dperror("setsockopt(SO_KEEPALIVE)\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
@@ -271,10 +271,10 @@ void CySocket::set_tcp_nodelay() {
|
|||||||
int CySocket::Read(char *buffer, unsigned int length) {
|
int CySocket::Read(char *buffer, unsigned int length) {
|
||||||
#ifdef Y_CONFIG_USE_OPEN_SSL
|
#ifdef Y_CONFIG_USE_OPEN_SSL
|
||||||
if(isSSLSocket)
|
if(isSSLSocket)
|
||||||
return SSL_read(ssl, buffer, length);
|
return SSL_read(ssl, buffer, length);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
return ::read(sock, buffer, length);
|
return ::read(sock, buffer, length);
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Send a buffer (normal or SSL)
|
// Send a buffer (normal or SSL)
|
||||||
@@ -283,7 +283,7 @@ int CySocket::Send(char const *buffer, unsigned int length) {
|
|||||||
unsigned int len = 0;
|
unsigned int len = 0;
|
||||||
#ifdef Y_CONFIG_USE_OPEN_SSL
|
#ifdef Y_CONFIG_USE_OPEN_SSL
|
||||||
if(isSSLSocket)
|
if(isSSLSocket)
|
||||||
len = SSL_write(ssl, buffer, length);
|
len = SSL_write(ssl, buffer, length);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
len = ::send(sock, buffer, length, MSG_NOSIGNAL);
|
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)
|
if (size > -1 && size < left)
|
||||||
left = size;
|
left = size;
|
||||||
#ifdef Y_CONFIG_HAVE_SENDFILE
|
#ifdef Y_CONFIG_HAVE_SENDFILE
|
||||||
|
#ifdef Y_CONFIG_USE_OPEN_SSL
|
||||||
|
if(!isSSLSocket)
|
||||||
|
#endif
|
||||||
while (left > 0) {
|
while (left > 0) {
|
||||||
// split sendfile() transfer to smaller chunks to reduce memory-mapping requirements
|
// split sendfile() transfer to smaller chunks to reduce memory-mapping requirements
|
||||||
if((written = ::sendfile(sock, filed, &start, std::min((off_t) 0x8000000LL, left))) == -1) {
|
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 {
|
} else {
|
||||||
BytesSend += written;
|
BytesSend += written;
|
||||||
left -= written;
|
left -= written;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // Y_CONFIG_HAVE_SENDFILE
|
#endif // Y_CONFIG_HAVE_SENDFILE
|
||||||
if (left > 0) {
|
if (left > 0) {
|
||||||
@@ -347,7 +350,6 @@ bool CySocket::SendFile(int filed, off_t start, off_t size) {
|
|||||||
perror("send failed");
|
perror("send failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
BytesSend += written;
|
|
||||||
left -= written;
|
left -= written;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -372,7 +374,7 @@ unsigned int CySocket::ReceiveFileGivenLength(int filed, unsigned int _length) {
|
|||||||
u_long readarg = 0;
|
u_long readarg = 0;
|
||||||
#ifdef Y_CONFIG_USE_OPEN_SSL
|
#ifdef Y_CONFIG_USE_OPEN_SSL
|
||||||
if(isSSLSocket)
|
if(isSSLSocket)
|
||||||
readarg = RECEIVE_BLOCK_LEN;
|
readarg = RECEIVE_BLOCK_LEN;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
@@ -48,7 +48,7 @@ CWebserver::CWebserver() {
|
|||||||
FD_ZERO(&read_fds);
|
FD_ZERO(&read_fds);
|
||||||
fdmax = 0;
|
fdmax = 0;
|
||||||
open_connections = 0;
|
open_connections = 0;
|
||||||
#ifdef Y_CONFIG_BUILD_AS_DAEMON
|
#ifdef Y_CONFIG_FEATURE_THREADING
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
#endif
|
#endif
|
||||||
@@ -412,13 +412,13 @@ bool CWebserver::handle_connection(CySocket *newSock) {
|
|||||||
newConn->ySock = newSock;
|
newConn->ySock = newSock;
|
||||||
newConn->ySock->handling = true;
|
newConn->ySock->handling = true;
|
||||||
newConn->WebserverBackref = this;
|
newConn->WebserverBackref = this;
|
||||||
#ifdef Y_CONFIG_BUILD_AS_DAEMON
|
#ifdef Y_CONFIG_FEATURE_THREADING
|
||||||
newConn->is_treaded = is_threading;
|
newConn->is_treaded = is_threading;
|
||||||
#else
|
#else
|
||||||
newConn->is_treaded = false;
|
newConn->is_treaded = false;
|
||||||
#endif
|
#endif
|
||||||
int index = -1;
|
int index = -1;
|
||||||
#ifdef Y_CONFIG_BUILD_AS_DAEMON
|
#ifdef Y_CONFIG_FEATURE_THREADING
|
||||||
if(is_threading)
|
if(is_threading)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock( &mutex );
|
pthread_mutex_lock( &mutex );
|
||||||
@@ -442,7 +442,7 @@ bool CWebserver::handle_connection(CySocket *newSock) {
|
|||||||
|
|
||||||
// start connection Thread
|
// start connection Thread
|
||||||
if(pthread_create(&Connection_Thread_List[index], &attr, WebThread, (void *)newConn) != 0)
|
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
|
else // non threaded
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user