Browse Source

reduce contention with mutex cs_twister

miguelfreitas
Miguel Freitas 11 years ago
parent
commit
78f3ceb921
  1. 92
      src/twister.cpp

92
src/twister.cpp

@ -72,9 +72,11 @@ sha1_hash dhtTargetHash(std::string const &username, std::string const &resource
torrent_handle startTorrentUser(std::string const &username) torrent_handle startTorrentUser(std::string const &username)
{ {
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 )
return torrent_handle();
LOCK(cs_twister); LOCK(cs_twister);
if( !m_userTorrent.count(username) && userInTxDb ) { if( !m_userTorrent.count(username) ) {
sha1_hash ih = dhtTargetHash(username, "tracker", "m"); sha1_hash ih = dhtTargetHash(username, "tracker", "m");
printf("adding torrent for [%s,tracker]\n", username.c_str()); printf("adding torrent for [%s,tracker]\n", username.c_str());
@ -92,26 +94,36 @@ torrent_handle startTorrentUser(std::string const &username)
m_userTorrent[username] = ses->add_torrent(tparams); m_userTorrent[username] = ses->add_torrent(tparams);
m_userTorrent[username].force_dht_announce(); m_userTorrent[username].force_dht_announce();
torrent_status status = m_userTorrent[username].status();
} }
return m_userTorrent[username]; return m_userTorrent[username];
} }
torrent_handle getTorrentUser(std::string const &username)
{
LOCK(cs_twister);
if( m_userTorrent.count(username) )
return m_userTorrent[username];
else
return torrent_handle();
}
int torrentLastHave(std::string const &username) int torrentLastHave(std::string const &username)
{ {
if( !m_userTorrent.count(username) ) torrent_handle h = getTorrentUser(username);
if( !h.is_valid() )
return -1; return -1;
torrent_status status = m_userTorrent[username].status(); torrent_status status = h.status();
return status.last_have; return status.last_have;
} }
int torrentNumPieces(std::string const &username) int torrentNumPieces(std::string const &username)
{ {
if( !m_userTorrent.count(username) ) torrent_handle h = getTorrentUser(username);
if( !h.is_valid() )
return -1; return -1;
torrent_status status = m_userTorrent[username].status(); torrent_status status = h.status();
return status.num_pieces; return status.num_pieces;
} }
@ -1172,14 +1184,12 @@ int findLastPublicPostLocalUser( std::string strUsername )
{ {
int lastk = -1; int lastk = -1;
LOCK(cs_twister); torrent_handle h = getTorrentUser(strUsername);
if( strUsername.size() && m_userTorrent.count(strUsername) && if( h.is_valid() ){
m_userTorrent[strUsername].is_valid() ){
std::vector<std::string> pieces; std::vector<std::string> pieces;
int max_id = std::numeric_limits<int>::max(); int max_id = std::numeric_limits<int>::max();
int since_id = -1; int since_id = -1;
m_userTorrent[strUsername].get_pieces(pieces, 1, max_id, since_id, USERPOST_FLAG_RT); h.get_pieces(pieces, 1, max_id, since_id, USERPOST_FLAG_RT);
if( pieces.size() ) { if( pieces.size() ) {
string const& piece = pieces.front(); string const& piece = pieces.front();
@ -1414,12 +1424,10 @@ Value getposts(const Array& params, bool fHelp)
if( i->name_ == "since_id" ) since_id = i->value_.get_int(); if( i->name_ == "since_id" ) since_id = i->value_.get_int();
} }
LOCK(cs_twister); torrent_handle h = getTorrentUser(strUsername);
if( strUsername.size() && m_userTorrent.count(strUsername) && if( h.is_valid() ){
m_userTorrent[strUsername].is_valid() ){
std::vector<std::string> pieces; std::vector<std::string> pieces;
m_userTorrent[strUsername].get_pieces(pieces, count, max_id, since_id, flags); h.get_pieces(pieces, count, max_id, since_id, flags);
BOOST_FOREACH(string const& piece, pieces) { BOOST_FOREACH(string const& piece, pieces) {
lazy_entry v; lazy_entry v;
@ -1566,22 +1574,16 @@ Value follow(const Array& params, bool fHelp)
string localUser = params[0].get_str(); string localUser = params[0].get_str();
Array users = params[1].get_array(); Array users = params[1].get_array();
LOCK(cs_twister);
for( unsigned int u = 0; u < users.size(); u++ ) { for( unsigned int u = 0; u < users.size(); u++ ) {
string username = users[u].get_str(); string username = users[u].get_str();
if( !m_users[localUser].m_following.count(username) ) {
if( m_userTorrent.count(username) ) {
// perhaps torrent is already initialized due to neighborhood
m_users[localUser].m_following.insert(username);
} else {
torrent_handle h = startTorrentUser(username); torrent_handle h = startTorrentUser(username);
if( h.is_valid() ) {
LOCK(cs_twister);
if( h.is_valid() && m_users.count(localUser) &&
!m_users[localUser].m_following.count(username) ) {
m_users[localUser].m_following.insert(username); m_users[localUser].m_following.insert(username);
} }
} }
}
}
return Value(); return Value();
} }
@ -1600,7 +1602,8 @@ Value unfollow(const Array& params, bool fHelp)
for( unsigned int u = 0; u < users.size(); u++ ) { for( unsigned int u = 0; u < users.size(); u++ ) {
string username = users[u].get_str(); string username = users[u].get_str();
if( m_users[localUser].m_following.count(username) ) { if( m_users.count(localUser) &&
m_users[localUser].m_following.count(username) ) {
m_users[localUser].m_following.erase(username); m_users[localUser].m_following.erase(username);
} }
} }
@ -1619,10 +1622,11 @@ Value getfollowing(const Array& params, bool fHelp)
Array ret; Array ret;
LOCK(cs_twister); LOCK(cs_twister);
if( m_users.count(localUser) ) {
BOOST_FOREACH(string username, m_users[localUser].m_following) { BOOST_FOREACH(string username, m_users[localUser].m_following) {
ret.push_back(username); ret.push_back(username);
} }
}
return ret; return ret;
} }
@ -1635,9 +1639,15 @@ Value getlasthave(const Array& params, bool fHelp)
string localUser = params[0].get_str(); string localUser = params[0].get_str();
Object ret; std::set<std::string> following;
{
LOCK(cs_twister); LOCK(cs_twister);
BOOST_FOREACH(string username, m_users[localUser].m_following) { if( m_users.count(localUser) )
following = m_users[localUser].m_following;
}
Object ret;
BOOST_FOREACH(string username, following) {
ret.push_back(Pair(username,torrentLastHave(username))); ret.push_back(Pair(username,torrentLastHave(username)));
} }
@ -1653,9 +1663,15 @@ Value getnumpieces(const Array& params, bool fHelp)
string localUser = params[0].get_str(); string localUser = params[0].get_str();
Object ret; std::set<std::string> following;
{
LOCK(cs_twister); LOCK(cs_twister);
BOOST_FOREACH(string username, m_users[localUser].m_following) { if( m_users.count(localUser) )
following = m_users[localUser].m_following;
}
Object ret;
BOOST_FOREACH(string username, following) {
ret.push_back(Pair(username,torrentNumPieces(username))); ret.push_back(Pair(username,torrentNumPieces(username)));
} }
@ -1722,15 +1738,9 @@ Value rescandirectmsgs(const Array& params, bool fHelp)
} }
BOOST_FOREACH(string username, following) { BOOST_FOREACH(string username, following) {
torrent_handle torrent; torrent_handle h = getTorrentUser(username);
if( h.is_valid() ){
{ h.recheck_pieces(USERPOST_FLAG_DM);
LOCK(cs_twister);
if( username.size() && m_userTorrent.count(username) )
torrent = m_userTorrent[username];
}
if( torrent.is_valid() ){
torrent.recheck_pieces(USERPOST_FLAG_DM);
} }
} }

Loading…
Cancel
Save