diff --git a/.travis.yml b/.travis.yml index f2a19a4bb..4346eb7e1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,9 +49,9 @@ script: - cd ../bindings/python - bjam -j 3 variant=$variant warnings=off $CC stage_module - LD_LIBRARY_PATH=. python test.py -# - if [ $variant == "test_debug" ]; then -# cd ../../simulation; -# bjam -j 3 crypto=built-in warnings=off $CC; -# fi + - if [ $variant == "test_debug" ]; then + cd ../../simulation; + bjam -j 3 crypto=built-in warnings=off $CC; + fi - ccache --show-stats diff --git a/include/libtorrent/config.hpp b/include/libtorrent/config.hpp index 684bcca58..34060f9c1 100644 --- a/include/libtorrent/config.hpp +++ b/include/libtorrent/config.hpp @@ -585,6 +585,8 @@ int snprintf(char* buf, int len, char const* fmt, ...) #endif #endif +// whether function-local static variables are thread safe. In c++11 and later +// they are (except msvc) #ifndef TORRENT_THREADSAFE_STATIC #if __cplusplus < 199711L || (defined _MSC_VER && _MSC_VER <= 1800) #define TORRENT_THREADSAFE_STATIC 0 diff --git a/include/libtorrent/piece_picker.hpp b/include/libtorrent/piece_picker.hpp index f31402c13..d0a660e89 100644 --- a/include/libtorrent/piece_picker.hpp +++ b/include/libtorrent/piece_picker.hpp @@ -136,7 +136,7 @@ namespace libtorrent enum options_t { - // pick rarest first + // pick rarest first rarest_first = 1, // pick the most common first, or the last pieces if sequential reverse = 2, diff --git a/simulation/swarm_suite.cpp b/simulation/swarm_suite.cpp index 8ca48e1f1..804e64747 100644 --- a/simulation/swarm_suite.cpp +++ b/simulation/swarm_suite.cpp @@ -33,6 +33,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/session.hpp" #include "libtorrent/settings_pack.hpp" #include "libtorrent/alert_types.hpp" +#include "libtorrent/random.hpp" #include "libtorrent/time.hpp" // for clock_type #include @@ -49,15 +50,18 @@ struct swarm_config : swarm_setup_provider { swarm_config(int flags) : m_flags(flags) - , m_swarm_id(std::rand()) , m_start_time(lt::clock_type::now()) { + m_swarm_id = test_counter(); + // in case the previous run was terminated error_code ec; char save_path[200]; snprintf(save_path, sizeof(save_path), "swarm-%04d-peer-%02d" , m_swarm_id, 0); create_directory(save_path, ec); + if (ec) fprintf(stderr, "failed to create directory: \"%s\": %s\n" + , save_path, ec.message().c_str()); std::ofstream file(combine_path(save_path, "temporary").c_str()); m_ti = ::create_torrent(&file, 0x4000, 9, false); file.close(); diff --git a/src/piece_picker.cpp b/src/piece_picker.cpp index d6f587a7f..80b074cc6 100644 --- a/src/piece_picker.cpp +++ b/src/piece_picker.cpp @@ -268,7 +268,7 @@ namespace libtorrent #endif // since we're removing a downloading_piece, we also need to free its - // blocks that are allocated from the m_block_info array. + // blocks that are allocated from the m_block_info array. m_free_block_infos.push_back(i->info_idx); TORRENT_ASSERT(find_dl_piece(download_state, i->index) == i); diff --git a/src/random.cpp b/src/random.cpp index 3a0350c5f..8b76164a0 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -52,6 +52,17 @@ namespace libtorrent using boost::random::mt19937; using boost::random::uniform_int_distribution; +#ifdef TORRENT_BUILD_SIMULATOR + + boost::uint32_t random() + { + // make sure random numbers are deterministic. Seed with a fixed number + static mt19937 random_engine(4040); + return uniform_int_distribution(0, UINT_MAX)(random_engine); + } + +#else + #if !TORRENT_THREADSAFE_STATIC // because local statics are not atomic pre c++11 // do it manually, probably at a higher cost @@ -80,5 +91,8 @@ namespace libtorrent return uniform_int_distribution(0, UINT_MAX)(*rnd); #endif } + +#endif // TORRENT_BUILD_SIMULATOR + } diff --git a/test/main.cpp b/test/main.cpp index bb5122178..9d7935194 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -50,10 +50,15 @@ POSSIBILITY OF SUCH DAMAGE. #ifdef WIN32 #include // fot SetErrorMode #include // for _dup and _dup2 +#include // for _getpid #define dup _dup #define dup2 _dup2 +#else + +#include // for getpid() + #endif using namespace libtorrent; @@ -64,6 +69,8 @@ int old_stdout = -1; int old_stderr = -1; bool redirect_output = true; +extern int _g_test_idx; + // the current tests file descriptor unit_test_t* current_test = NULL; @@ -194,7 +201,6 @@ EXPORT int main(int argc, char const* argv[]) | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); #endif - srand(total_microseconds(clock_type::now().time_since_epoch()) & 0x7fffffff); #ifdef O_NONBLOCK // on darwin, stdout is set to non-blocking mode by default // which sometimes causes tests to fail with EAGAIN just @@ -217,8 +223,14 @@ EXPORT int main(int argc, char const* argv[]) signal(SIGSYS, &sig_handler); #endif + int process_id = -1; +#ifdef _WIN32 + process_id = _getpid(); +#else + process_id = getpid(); +#endif char dir[40]; - snprintf(dir, sizeof(dir), "test_tmp_%u", rand()); + snprintf(dir, sizeof(dir), "test_tmp_%u", process_id); std::string test_dir = complete(dir); error_code ec; create_directory(test_dir, ec); @@ -273,6 +285,7 @@ EXPORT int main(int argc, char const* argv[]) } } + _g_test_idx = i; current_test = &t; #ifndef BOOST_NO_EXCEPTIONS diff --git a/test/test.cpp b/test/test.cpp index c9c92e01b..93cacd099 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -37,9 +37,15 @@ POSSIBILITY OF SUCH DAMAGE. unit_test_t _g_unit_tests[1024]; int _g_num_unit_tests = 0; int _g_test_failures = 0; +int _g_test_idx = 0; static std::vector failure_strings; +int test_counter() +{ + return _g_test_idx; +} + void report_failure(char const* err, char const* file, int line) { char buf[500]; diff --git a/test/test.hpp b/test/test.hpp index ee29017eb..5eb14e2df 100644 --- a/test/test.hpp +++ b/test/test.hpp @@ -69,6 +69,7 @@ POSSIBILITY OF SUCH DAMAGE. void EXPORT report_failure(char const* err, char const* file, int line); int EXPORT print_failures(); +int EXPORT test_counter(); typedef void (*unit_test_fun_t)();