diff --git a/core/app.cpp b/core/app.cpp index 7565561..9ec6f0b 100644 --- a/core/app.cpp +++ b/core/app.cpp @@ -33,6 +33,8 @@ */ #include +#include +#include #include #include #include @@ -40,7 +42,7 @@ #include #include #include -#include +#include #include "app.h" #include "plugin.h" #include "misc.h" @@ -1774,43 +1776,64 @@ void App::WaitForThreads() -size_t App::FetchPageOnExitCurlCallback(char *ptr, size_t size, size_t nmemb, void *userdata) + + +/* + we send a one FastCGI record at the end when winix closes (to wake up the main thread) + this method is called from the special thread + + typedef struct { + unsigned char version; + unsigned char type; + unsigned char requestIdB1; + unsigned char requestIdB0; + unsigned char contentLengthB1; + unsigned char contentLengthB0; + unsigned char paddingLength; + unsigned char reserved; + unsigned char contentData[contentLength]; + unsigned char paddingData[paddingLength]; + } FCGI_Record; +*/ +void App::SendEmptyFastCGIPacket() { - /* - * without this function the curl library will print the page's content - * to the standart output - */ - return size * nmemb; -} +std::string msg; +sockaddr_un to; +int res; + int s = socket(PF_LOCAL, SOCK_STREAM, 0); -void App::FetchPageOnExit() -{ - // stupid trick to break FCGX_Accept_r() function - // even with FCGX_InitRequest(..., ..., FCGI_FAIL_ACCEPT_ON_INTR) the FCGX_Accept_r - // doesn't want to break on a signal - // so we request one page from the server for exiting from FCGX_Accept_r + if( s < 0 ) + return; - Lock(); - CURL * curl = curl_easy_init(); - Unlock(); + memset(&to, 0, sizeof(to)); + to.sun_len = sizeof(to.sun_len) + + sizeof(to.sun_family) + + socket_to_send_on_exit.size() + + 1; // terminating zero - if( curl ) + to.sun_family = AF_UNIX; + snprintf(to.sun_path, sizeof(to.sun_path)/sizeof(char), "%s", socket_to_send_on_exit.c_str()); + + // actually we can send one byte only + msg += FCGI_VERSION_1; + msg += FCGI_GET_VALUES; + msg += (char)0; // requestid + msg += (char)0; + msg += (char)0; // contentlength + msg += (char)0; + msg += (char)0; // padding length + msg += (char)0; + msg += (char)0; // reserved + + res = connect(s, (sockaddr*)&to, sizeof(to)); + + if( res == 0 ) { - curl_easy_setopt(curl, CURLOPT_URL, url_to_fetch_on_exit.c_str()); - curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1); - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, FetchPageOnExitCurlCallback); - - if( curl_easy_perform(curl) != 0 ) - { - Lock(); - log << log1 << "App: I cannot correctly fetch a page from the special thread" << logend << logsave; - Unlock(); - } - - curl_easy_cleanup(curl); + send(s, msg.c_str(), msg.size(), MSG_EOF); } + + close(s); } @@ -1832,12 +1855,10 @@ int sig; app->synchro.was_stop_signal = true; FCGX_ShutdownPending(); - // here we don't have to use SSL version so we always use config.url_proto - PT::WideToUTF8(app->config.url_proto, app->url_to_fetch_on_exit); - PT::WideToUTF8(app->config.base_url, app->url_to_fetch_on_exit, false); + PT::WideToUTF8(app->config.fcgi_socket, app->socket_to_send_on_exit); app->Unlock(); - app->FetchPageOnExit(); + app->SendEmptyFastCGIPacket(); pthread_exit(0); return 0; diff --git a/core/app.h b/core/app.h index a7ecfc3..804b78d 100644 --- a/core/app.h +++ b/core/app.h @@ -147,7 +147,7 @@ private: int fcgi_socket; Synchro synchro; pthread_t signal_thread; - std::string url_to_fetch_on_exit; + std::string socket_to_send_on_exit; std::string send_data_buf; PT::SpaceToJSON json_generic_serializer; TextStream json_out_stream; @@ -225,8 +225,7 @@ private: void LogGroups(); static void * SpecialThreadForSignals(void*); - static size_t FetchPageOnExitCurlCallback(char *ptr, size_t size, size_t nmemb, void *userdata); - void FetchPageOnExit(); + void SendEmptyFastCGIPacket(); void CreateStaticTree();