Merge branch 'master' of github.com:hanzz/libtransport

This commit is contained in:
HanzZ 2013-01-10 20:55:30 +01:00
commit b4e9e12a6e
6 changed files with 114 additions and 15 deletions

View file

@ -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;

View file

@ -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

View file

@ -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 (...)

View file

@ -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()) {

View file

@ -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;

View file

@ -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;