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:
parent
f875bd2944
commit
0a43870e76
91
core/app.cpp
91
core/app.cpp
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue