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/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <unistd.h>
|
||||
|
@ -40,7 +42,7 @@
|
|||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <utility>
|
||||
#include <curl/curl.h>
|
||||
#include <fastcgi.h>
|
||||
#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;
|
||||
|
|
|
@ -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<std::wstring> 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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue