mirror of
https://github.com/twisterarmy/twister-core.git
synced 2025-02-08 21:04:14 +00:00
wait twister threads to finish before destroying libtorrent session object.
may fix #200.
This commit is contained in:
parent
5eb40d9ffd
commit
8f03692074
@ -43,6 +43,7 @@ twister::twister()
|
|||||||
|
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
static session *ses = NULL;
|
static session *ses = NULL;
|
||||||
|
static bool m_shuttingDownSession = false;
|
||||||
static bool m_usingProxy;
|
static bool m_usingProxy;
|
||||||
static int num_outstanding_resume_data;
|
static int num_outstanding_resume_data;
|
||||||
|
|
||||||
@ -55,6 +56,7 @@ enum ExpireResType { SimpleNoExpire, NumberedNoExpire, PostNoExpireRecent };
|
|||||||
static map<std::string, ExpireResType> m_noExpireResources;
|
static map<std::string, ExpireResType> m_noExpireResources;
|
||||||
static map<std::string, torrent_handle> m_userTorrent;
|
static map<std::string, torrent_handle> m_userTorrent;
|
||||||
static boost::scoped_ptr<CLevelDB> m_swarmDb;
|
static boost::scoped_ptr<CLevelDB> m_swarmDb;
|
||||||
|
static int m_threadsToJoin;
|
||||||
|
|
||||||
static CCriticalSection cs_spamMsg;
|
static CCriticalSection cs_spamMsg;
|
||||||
static std::string m_preferredSpamLang = "[en]";
|
static std::string m_preferredSpamLang = "[en]";
|
||||||
@ -66,6 +68,25 @@ static std::map<std::string,UserData> m_users;
|
|||||||
static CCriticalSection cs_seenHashtags;
|
static CCriticalSection cs_seenHashtags;
|
||||||
static std::map<std::string,double> m_seenHashtags;
|
static std::map<std::string,double> m_seenHashtags;
|
||||||
|
|
||||||
|
class SimpleThreadCounter {
|
||||||
|
public:
|
||||||
|
SimpleThreadCounter(CCriticalSection *lock, int *counter, const char *name) :
|
||||||
|
m_lock(lock), m_counter(counter), m_name(name) {
|
||||||
|
RenameThread(m_name);
|
||||||
|
LOCK(*m_lock);
|
||||||
|
(*m_counter)++;
|
||||||
|
}
|
||||||
|
~SimpleThreadCounter() {
|
||||||
|
printf("%s thread exit\n", m_name);
|
||||||
|
LOCK(*m_lock);
|
||||||
|
(*m_counter)--;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
CCriticalSection *m_lock;
|
||||||
|
int *m_counter;
|
||||||
|
const char *m_name;
|
||||||
|
};
|
||||||
|
|
||||||
#define USER_DATA_FILE "user_data"
|
#define USER_DATA_FILE "user_data"
|
||||||
#define GLOBAL_DATA_FILE "global_data"
|
#define GLOBAL_DATA_FILE "global_data"
|
||||||
|
|
||||||
@ -84,7 +105,7 @@ sha1_hash dhtTargetHash(std::string const &username, std::string const &resource
|
|||||||
torrent_handle startTorrentUser(std::string const &username, bool following)
|
torrent_handle startTorrentUser(std::string const &username, bool following)
|
||||||
{
|
{
|
||||||
bool userInTxDb = usernameExists(username); // keep this outside cs_twister to avoid deadlock
|
bool userInTxDb = usernameExists(username); // keep this outside cs_twister to avoid deadlock
|
||||||
if( !userInTxDb )
|
if( !userInTxDb || !ses)
|
||||||
return torrent_handle();
|
return torrent_handle();
|
||||||
|
|
||||||
LOCK(cs_twister);
|
LOCK(cs_twister);
|
||||||
@ -205,10 +226,9 @@ data_error:
|
|||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ThreadWaitExtIP()
|
void ThreadWaitExtIP()
|
||||||
{
|
{
|
||||||
RenameThread("wait-extip");
|
SimpleThreadCounter threadCounter(&cs_twister, &m_threadsToJoin, "wait-extip");
|
||||||
|
|
||||||
std::string ipStr;
|
std::string ipStr;
|
||||||
|
|
||||||
@ -418,16 +438,16 @@ int getDhtNodes(boost::int64_t *dht_global_nodes)
|
|||||||
|
|
||||||
void ThreadMaintainDHTNodes()
|
void ThreadMaintainDHTNodes()
|
||||||
{
|
{
|
||||||
RenameThread("maintain-dht-nodes");
|
SimpleThreadCounter threadCounter(&cs_twister, &m_threadsToJoin, "maintain-dht-nodes");
|
||||||
|
|
||||||
while(!ses) {
|
while(!ses && !m_shuttingDownSession) {
|
||||||
MilliSleep(200);
|
MilliSleep(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 lastSaveResumeTime = GetTime();
|
int64 lastSaveResumeTime = GetTime();
|
||||||
int lastTotalNodesCandidates = 0;
|
int lastTotalNodesCandidates = 0;
|
||||||
|
|
||||||
while(1) {
|
while(ses && !m_shuttingDownSession) {
|
||||||
session_status ss = ses->status();
|
session_status ss = ses->status();
|
||||||
int dht_nodes = ss.dht_nodes;
|
int dht_nodes = ss.dht_nodes;
|
||||||
bool nodesAdded = false;
|
bool nodesAdded = false;
|
||||||
@ -535,11 +555,14 @@ void ThreadSessionAlerts()
|
|||||||
static map<sha1_hash, bool> neighborCheck;
|
static map<sha1_hash, bool> neighborCheck;
|
||||||
static map<sha1_hash, int64_t> statusCheck;
|
static map<sha1_hash, int64_t> statusCheck;
|
||||||
|
|
||||||
while(!ses) {
|
SimpleThreadCounter threadCounter(&cs_twister, &m_threadsToJoin, "session-alerts");
|
||||||
|
|
||||||
|
|
||||||
|
while(!ses && !m_shuttingDownSession) {
|
||||||
MilliSleep(200);
|
MilliSleep(200);
|
||||||
}
|
}
|
||||||
while (ses) {
|
while (ses && !m_shuttingDownSession) {
|
||||||
alert const* a = ses->wait_for_alert(seconds(10));
|
alert const* a = ses->wait_for_alert(seconds(1));
|
||||||
if (a == 0) continue;
|
if (a == 0) continue;
|
||||||
|
|
||||||
std::deque<alert*> alerts;
|
std::deque<alert*> alerts;
|
||||||
@ -721,6 +744,7 @@ void startSessionTorrent(boost::thread_group& threadGroup)
|
|||||||
m_noExpireResources["status"] = SimpleNoExpire;
|
m_noExpireResources["status"] = SimpleNoExpire;
|
||||||
m_noExpireResources["post"] = PostNoExpireRecent;
|
m_noExpireResources["post"] = PostNoExpireRecent;
|
||||||
|
|
||||||
|
m_threadsToJoin = 0;
|
||||||
threadGroup.create_thread(boost::bind(&ThreadWaitExtIP));
|
threadGroup.create_thread(boost::bind(&ThreadWaitExtIP));
|
||||||
threadGroup.create_thread(boost::bind(&ThreadMaintainDHTNodes));
|
threadGroup.create_thread(boost::bind(&ThreadMaintainDHTNodes));
|
||||||
threadGroup.create_thread(boost::bind(&ThreadSessionAlerts));
|
threadGroup.create_thread(boost::bind(&ThreadSessionAlerts));
|
||||||
@ -739,6 +763,17 @@ void stopSessionTorrent()
|
|||||||
MilliSleep(100);
|
MilliSleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_shuttingDownSession = true;
|
||||||
|
int threadsToJoin = 0;
|
||||||
|
do {
|
||||||
|
MilliSleep(100);
|
||||||
|
LOCK(cs_twister);
|
||||||
|
if( threadsToJoin != m_threadsToJoin ) {
|
||||||
|
threadsToJoin = m_threadsToJoin;
|
||||||
|
printf("twister threads to join = %d\n", threadsToJoin);
|
||||||
|
}
|
||||||
|
} while( threadsToJoin );
|
||||||
|
|
||||||
printf("\nsaving session state\n");
|
printf("\nsaving session state\n");
|
||||||
|
|
||||||
entry session_state;
|
entry session_state;
|
||||||
@ -755,6 +790,8 @@ void stopSessionTorrent()
|
|||||||
boost::filesystem::path sesStatePath = GetDataDir() / "ses_state";
|
boost::filesystem::path sesStatePath = GetDataDir() / "ses_state";
|
||||||
save_file(sesStatePath.string(), out);
|
save_file(sesStatePath.string(), out);
|
||||||
|
|
||||||
|
ses->stop_dht();
|
||||||
|
|
||||||
delete ses;
|
delete ses;
|
||||||
ses = NULL;
|
ses = NULL;
|
||||||
}
|
}
|
||||||
@ -2093,7 +2130,7 @@ Value torrentstatus(const Array& params, bool fHelp)
|
|||||||
result.push_back(Pair("num_complete", status.num_complete));
|
result.push_back(Pair("num_complete", status.num_complete));
|
||||||
result.push_back(Pair("num_pieces", status.num_pieces));
|
result.push_back(Pair("num_pieces", status.num_pieces));
|
||||||
string bitfield;
|
string bitfield;
|
||||||
for(int i = 0; i < status.pieces.size(); i++) {
|
for(std::size_t i = 0; i < status.pieces.size(); i++) {
|
||||||
bitfield.append( status.pieces[i]?"1":"0" );
|
bitfield.append( status.pieces[i]?"1":"0" );
|
||||||
}
|
}
|
||||||
result.push_back(Pair("bitfield", bitfield));
|
result.push_back(Pair("bitfield", bitfield));
|
||||||
@ -2115,7 +2152,7 @@ Value torrentstatus(const Array& params, bool fHelp)
|
|||||||
info.push_back(Pair("download_queue_length", p.download_queue_length));
|
info.push_back(Pair("download_queue_length", p.download_queue_length));
|
||||||
info.push_back(Pair("failcount", p.failcount));
|
info.push_back(Pair("failcount", p.failcount));
|
||||||
bitfield = "";
|
bitfield = "";
|
||||||
for(int i = 0; i < p.pieces.size(); i++) {
|
for(std::size_t i = 0; i < p.pieces.size(); i++) {
|
||||||
bitfield.append( p.pieces[i]?"1":"0" );
|
bitfield.append( p.pieces[i]?"1":"0" );
|
||||||
}
|
}
|
||||||
info.push_back(Pair("bitfield", bitfield));
|
info.push_back(Pair("bitfield", bitfield));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user