Merge branch 'master' of github.com:hanzz/libtransport
This commit is contained in:
commit
b4e9e12a6e
6 changed files with 114 additions and 15 deletions
|
@ -136,6 +136,7 @@ class NetworkPluginServer {
|
|||
void handleFTRejected(User *user, const std::string &buddyName, const std::string &fileName, unsigned long size);
|
||||
void handleFTDataNeeded(Backend *b, unsigned long ftid);
|
||||
|
||||
void handlePIDTerminated(unsigned long pid);
|
||||
private:
|
||||
void send(boost::shared_ptr<Swift::Connection> &, const std::string &data);
|
||||
|
||||
|
@ -152,6 +153,7 @@ class NetworkPluginServer {
|
|||
Config *m_config;
|
||||
boost::shared_ptr<Swift::ConnectionServer> m_server;
|
||||
std::list<Backend *> m_clients;
|
||||
std::vector<unsigned long> m_pids;
|
||||
Swift::Timer::ref m_pingTimer;
|
||||
Swift::Timer::ref m_collectTimer;
|
||||
Swift::Timer::ref m_loginTimer;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
log4j.rootLogger=debug, R
|
||||
|
||||
log4j.appender.R=org.apache.log4j.RollingFileAppender
|
||||
log4j.appender.R.File=/var/log/spectrum2/${jid}/backends/backend-${pid}.log
|
||||
log4j.appender.R.File=/var/log/spectrum2/${jid}/backends/backend-${id}.log
|
||||
|
||||
log4j.appender.R.MaxFileSize=10000KB
|
||||
# Keep one backup file
|
||||
log4j.appender.R.MaxBackupIndex=1
|
||||
|
||||
log4j.appender.R.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.R.layout.ConversionPattern=%d %-5p %c: %m%n
|
||||
log4j.appender.R.layout.ConversionPattern=${pid}: %d %-5p %c: %m%n
|
||||
|
|
|
@ -363,7 +363,7 @@ Config *Config::createFromArgs(int argc, char **argv, std::string &error, std::s
|
|||
}
|
||||
catch (std::runtime_error& e)
|
||||
{
|
||||
error = os.str();
|
||||
error = std::string(e.what()) + "\n" + os.str();
|
||||
return NULL;
|
||||
}
|
||||
catch (...)
|
||||
|
|
|
@ -119,24 +119,29 @@ static void initLogging(Config *config, std::string key) {
|
|||
}
|
||||
|
||||
p.load(istream);
|
||||
LogString pid, jid;
|
||||
LogString pid, jid, id;
|
||||
log4cxx::helpers::Transcoder::decode(boost::lexical_cast<std::string>(getpid()), pid);
|
||||
log4cxx::helpers::Transcoder::decode(CONFIG_STRING(config, "service.jid"), jid);
|
||||
log4cxx::helpers::Transcoder::decode(CONFIG_STRING_DEFAULTED(config, "service.backend_id", ""), id);
|
||||
#ifdef _MSC_VER
|
||||
p.setProperty(L"pid", pid);
|
||||
p.setProperty(L"jid", jid);
|
||||
p.setProperty(L"id", id);
|
||||
#else
|
||||
p.setProperty("pid", pid);
|
||||
p.setProperty("jid", jid);
|
||||
p.setProperty("id", id);
|
||||
#endif
|
||||
|
||||
std::string dir;
|
||||
BOOST_FOREACH(const log4cxx::LogString &prop, p.propertyNames()) {
|
||||
if (boost::ends_with(prop, ".File")) {
|
||||
// if (boost::ends_with(prop, ".File")) {
|
||||
log4cxx::helpers::Transcoder::encode(p.get(prop), dir);
|
||||
boost::replace_all(dir, "${jid}", jid);
|
||||
boost::replace_all(dir, "${pid}", pid);
|
||||
boost::replace_all(dir, "${id}", id);
|
||||
break;
|
||||
}
|
||||
// }
|
||||
}
|
||||
mode_t old_cmask;
|
||||
if (!dir.empty()) {
|
||||
|
|
|
@ -71,6 +71,8 @@ static unsigned long bytestream_id;
|
|||
|
||||
DEFINE_LOGGER(logger, "NetworkPluginServer");
|
||||
|
||||
static NetworkPluginServer *_server;
|
||||
|
||||
class NetworkConversation : public Conversation {
|
||||
public:
|
||||
NetworkConversation(ConversationManager *conversationManager, const std::string &legacyName, bool muc = false) : Conversation(conversationManager, legacyName, muc) {
|
||||
|
@ -128,7 +130,7 @@ class NetworkFactory : public Factory {
|
|||
wrap.SerializeToString(&MESSAGE);
|
||||
|
||||
// Executes new backend
|
||||
static unsigned long exec_(const std::string& exePath, const char *host, const char *port, const char *cmdlineArgs) {
|
||||
static unsigned long exec_(const std::string& exePath, const char *host, const char *port, const char *log_id, const char *cmdlineArgs) {
|
||||
// BACKEND_ID is replaced with unique ID. The ID is increasing for every backend.
|
||||
std::string finalExePath = boost::replace_all_copy(exePath, "BACKEND_ID", boost::lexical_cast<std::string>(backend_id++));
|
||||
|
||||
|
@ -171,7 +173,7 @@ static unsigned long exec_(const std::string& exePath, const char *host, const c
|
|||
return 0;
|
||||
#else
|
||||
// Add host and port.
|
||||
finalExePath += std::string(" --host ") + host + " --port " + port + " " + cmdlineArgs;
|
||||
finalExePath += std::string(" --host ") + host + " --port " + port + " --service.backend_id=" + log_id + " " + cmdlineArgs;
|
||||
LOG4CXX_INFO(logger, "Starting new backend " << finalExePath);
|
||||
|
||||
// Create array of char * from string using -lpopt library
|
||||
|
@ -214,6 +216,7 @@ static void SigCatcher(int n) {
|
|||
// WARNING: Do not put LOG4CXX_ here, because it can lead to deadlock
|
||||
while ((result = waitpid(-1, &status, WNOHANG)) > 0) {
|
||||
if (result != 0) {
|
||||
_server->handlePIDTerminated((unsigned long)result);
|
||||
if (WIFEXITED(status)) {
|
||||
if (WEXITSTATUS(status) != 0) {
|
||||
// LOG4CXX_ERROR(logger, "Backend can not be started, exit_code=" << WEXITSTATUS(status));
|
||||
|
@ -251,6 +254,7 @@ static void handleBuddyPayload(LocalBuddy *buddy, const pbnetwork::Buddy &payloa
|
|||
}
|
||||
|
||||
NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, UserManager *userManager, FileTransferManager *ftManager, DiscoItemsResponder *discoItemsResponder) {
|
||||
_server = this;
|
||||
m_ftManager = ftManager;
|
||||
m_userManager = userManager;
|
||||
m_config = config;
|
||||
|
@ -324,7 +328,7 @@ void NetworkPluginServer::start() {
|
|||
LOG4CXX_INFO(logger, "Listening on host " << CONFIG_STRING(m_config, "service.backend_host") << " port " << CONFIG_STRING(m_config, "service.backend_port"));
|
||||
|
||||
while (true) {
|
||||
unsigned long pid = exec_(CONFIG_STRING(m_config, "service.backend"), CONFIG_STRING(m_config, "service.backend_host").c_str(), CONFIG_STRING(m_config, "service.backend_port").c_str(), m_config->getCommandLineArgs().c_str());
|
||||
unsigned long pid = exec_(CONFIG_STRING(m_config, "service.backend"), CONFIG_STRING(m_config, "service.backend_host").c_str(), CONFIG_STRING(m_config, "service.backend_port").c_str(), "1", m_config->getCommandLineArgs().c_str());
|
||||
LOG4CXX_INFO(logger, "Tried to spawn first backend with pid " << pid);
|
||||
LOG4CXX_INFO(logger, "Backend should now connect to Spectrum2 instance. Spectrum2 won't accept any connection before backend connects");
|
||||
|
||||
|
@ -353,6 +357,8 @@ void NetworkPluginServer::start() {
|
|||
}
|
||||
}
|
||||
|
||||
m_pids.push_back(pid);
|
||||
|
||||
signal(SIGCHLD, SigCatcher);
|
||||
#endif
|
||||
// quit the while loop
|
||||
|
@ -1660,6 +1666,57 @@ void NetworkPluginServer::sendPing(Backend *c) {
|
|||
// LOG4CXX_INFO(logger, "PING to " << c);
|
||||
}
|
||||
|
||||
void NetworkPluginServer::handlePIDTerminated(unsigned long pid) {
|
||||
std::vector<unsigned long>::iterator log_id_it;
|
||||
log_id_it = std::find(m_pids.begin(), m_pids.end(), pid);
|
||||
if (log_id_it != m_pids.end()) {
|
||||
*log_id_it = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
static int sig_block_count = 0;
|
||||
static sigset_t block_mask;
|
||||
|
||||
static void __block_signals ( void )
|
||||
{
|
||||
static int init_done = 0;
|
||||
|
||||
if ( (sig_block_count++) != 1 ) return;
|
||||
|
||||
if ( init_done == 0 ) {
|
||||
sigemptyset ( &block_mask );
|
||||
sigaddset ( &block_mask, SIGPIPE );
|
||||
sigaddset ( &block_mask, SIGHUP );
|
||||
sigaddset ( &block_mask, SIGINT );
|
||||
sigaddset ( &block_mask, SIGQUIT );
|
||||
sigaddset ( &block_mask, SIGTERM );
|
||||
sigaddset ( &block_mask, SIGABRT );
|
||||
sigaddset ( &block_mask, SIGCHLD );
|
||||
init_done = 1;
|
||||
}
|
||||
|
||||
sigprocmask ( SIG_BLOCK, &block_mask, NULL );
|
||||
return;
|
||||
}
|
||||
|
||||
static void __unblock_signals ( void )
|
||||
{
|
||||
sigset_t sigset;
|
||||
|
||||
if ( (sig_block_count--) != 0 ) return;
|
||||
sigprocmask ( SIG_UNBLOCK, &block_mask, NULL );
|
||||
|
||||
if ( sigpending ( &sigset ) == 0 ) {
|
||||
if ( sigismember ( &sigset, SIGCHLD ) ) {
|
||||
raise ( SIGCHLD );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
NetworkPluginServer::Backend *NetworkPluginServer::getFreeClient(bool acceptUsers, bool longRun, bool check) {
|
||||
NetworkPluginServer::Backend *c = NULL;
|
||||
|
||||
|
@ -1692,7 +1749,29 @@ NetworkPluginServer::Backend *NetworkPluginServer::getFreeClient(bool acceptUser
|
|||
if (c == NULL && !m_startingBackend) {
|
||||
m_isNextLongRun = longRun;
|
||||
m_startingBackend = true;
|
||||
exec_(CONFIG_STRING(m_config, "service.backend"), CONFIG_STRING(m_config, "service.backend_host").c_str(), CONFIG_STRING(m_config, "service.backend_port").c_str(), m_config->getCommandLineArgs().c_str());
|
||||
|
||||
#ifndef _WIN32
|
||||
__block_signals();
|
||||
#endif
|
||||
std::vector<unsigned long>::iterator log_id_it;
|
||||
log_id_it = std::find(m_pids.begin(), m_pids.end(), 0);
|
||||
std::string log_id = "";
|
||||
if (log_id_it == m_pids.end()) {
|
||||
log_id = boost::lexical_cast<std::string>(m_pids.size() + 1);
|
||||
}
|
||||
else {
|
||||
log_id = boost::lexical_cast<std::string>(log_id_it - m_pids.begin() + 1);
|
||||
}
|
||||
unsigned long pid = exec_(CONFIG_STRING(m_config, "service.backend"), CONFIG_STRING(m_config, "service.backend_host").c_str(), CONFIG_STRING(m_config, "service.backend_port").c_str(), log_id.c_str(), m_config->getCommandLineArgs().c_str());
|
||||
if (log_id_it == m_pids.end()) {
|
||||
m_pids.push_back(pid);
|
||||
}
|
||||
else {
|
||||
*log_id_it = pid;
|
||||
}
|
||||
#ifndef _WIN32
|
||||
__unblock_signals();
|
||||
#endif
|
||||
}
|
||||
|
||||
return c;
|
||||
|
|
|
@ -349,6 +349,7 @@ bool SQLite3Backend::getBuddies(long id, std::list<BuddyInfo> &roster) {
|
|||
std::string key;
|
||||
|
||||
int ret;
|
||||
int ret2 = -10;
|
||||
while((ret = sqlite3_step(m_getBuddies)) == SQLITE_ROW) {
|
||||
BuddyInfo b;
|
||||
RESET_GET_COUNTER(m_getBuddies);
|
||||
|
@ -366,7 +367,7 @@ bool SQLite3Backend::getBuddies(long id, std::list<BuddyInfo> &roster) {
|
|||
buddy_id = -1;
|
||||
}
|
||||
|
||||
while(buddy_id == -1 && (ret = sqlite3_step(m_getBuddiesSettings)) == SQLITE_ROW) {
|
||||
while(buddy_id == -1 && ret2 != SQLITE_DONE && ret2 != SQLITE_ERROR && (ret2 = sqlite3_step(m_getBuddiesSettings)) == SQLITE_ROW) {
|
||||
RESET_GET_COUNTER(m_getBuddiesSettings);
|
||||
buddy_id = GET_INT(m_getBuddiesSettings);
|
||||
|
||||
|
@ -403,12 +404,24 @@ bool SQLite3Backend::getBuddies(long id, std::list<BuddyInfo> &roster) {
|
|||
roster.push_back(b);
|
||||
}
|
||||
|
||||
while((ret = sqlite3_step(m_getBuddiesSettings)) == SQLITE_ROW) {
|
||||
if (ret != SQLITE_DONE) {
|
||||
LOG4CXX_ERROR(logger, "getBuddies query "<< (sqlite3_errmsg(m_db) == NULL ? "" : sqlite3_errmsg(m_db)));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ret != SQLITE_DONE) {
|
||||
LOG4CXX_ERROR(logger, "getBuddies query"<< (sqlite3_errmsg(m_db) == NULL ? "" : sqlite3_errmsg(m_db)));
|
||||
return false;
|
||||
if (ret2 != SQLITE_DONE) {
|
||||
if (ret2 == SQLITE_ERROR) {
|
||||
LOG4CXX_ERROR(logger, "getBuddiesSettings query "<< (sqlite3_errmsg(m_db) == NULL ? "" : sqlite3_errmsg(m_db)));
|
||||
return false;
|
||||
}
|
||||
|
||||
while((ret2 = sqlite3_step(m_getBuddiesSettings)) == SQLITE_ROW) {
|
||||
}
|
||||
|
||||
if (ret2 != SQLITE_DONE) {
|
||||
LOG4CXX_ERROR(logger, "getBuddiesSettings query "<< (sqlite3_errmsg(m_db) == NULL ? "" : sqlite3_errmsg(m_db)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Add table
Reference in a new issue