fixed: the way how winix is closing

beforehand we made a http connection from the special thread
       now we just send a fastcgi packet to the unix socket

       the old way was broken because it requires the http server to work
       and if the operating system is going to shutdown/reboot then the http server
       can be first closed and consequently the winix cannot wake up from
       the main thread (and will be terminated SIGKILL by the os)
       



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@998 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2015-01-02 07:01:08 +00:00
parent f875bd2944
commit 0a43870e76
2 changed files with 58 additions and 38 deletions

View File

@ -33,6 +33,8 @@
*/ */
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <pwd.h> #include <pwd.h>
#include <grp.h> #include <grp.h>
#include <unistd.h> #include <unistd.h>
@ -40,7 +42,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <utility> #include <utility>
#include <curl/curl.h> #include <fastcgi.h>
#include "app.h" #include "app.h"
#include "plugin.h" #include "plugin.h"
#include "misc.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()
{ {
/* std::string msg;
* without this function the curl library will print the page's content sockaddr_un to;
* to the standart output int res;
*/
return size * nmemb;
}
int s = socket(PF_LOCAL, SOCK_STREAM, 0);
void App::FetchPageOnExit() if( s < 0 )
{ return;
// 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
Lock(); memset(&to, 0, sizeof(to));
CURL * curl = curl_easy_init(); to.sun_len = sizeof(to.sun_len)
Unlock(); + 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()); send(s, msg.c_str(), msg.size(), MSG_EOF);
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);
} }
close(s);
} }
@ -1832,12 +1855,10 @@ int sig;
app->synchro.was_stop_signal = true; app->synchro.was_stop_signal = true;
FCGX_ShutdownPending(); FCGX_ShutdownPending();
// here we don't have to use SSL version so we always use config.url_proto PT::WideToUTF8(app->config.fcgi_socket, app->socket_to_send_on_exit);
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);
app->Unlock(); app->Unlock();
app->FetchPageOnExit(); app->SendEmptyFastCGIPacket();
pthread_exit(0); pthread_exit(0);
return 0; return 0;

View File

@ -147,7 +147,7 @@ private:
int fcgi_socket; int fcgi_socket;
Synchro synchro; Synchro synchro;
pthread_t signal_thread; pthread_t signal_thread;
std::string url_to_fetch_on_exit; std::string socket_to_send_on_exit;
std::string send_data_buf; std::string send_data_buf;
PT::SpaceToJSON json_generic_serializer; PT::SpaceToJSON json_generic_serializer;
TextStream<std::wstring> json_out_stream; TextStream<std::wstring> json_out_stream;
@ -225,8 +225,7 @@ private:
void LogGroups(); void LogGroups();
static void * SpecialThreadForSignals(void*); static void * SpecialThreadForSignals(void*);
static size_t FetchPageOnExitCurlCallback(char *ptr, size_t size, size_t nmemb, void *userdata); void SendEmptyFastCGIPacket();
void FetchPageOnExit();
void CreateStaticTree(); void CreateStaticTree();