@@ -14,13 +14,6 @@ namespace rack { | |||||
namespace plugin { | namespace plugin { | ||||
struct Update { | |||||
std::string pluginSlug; | |||||
std::string version; | |||||
std::string changelogUrl; | |||||
}; | |||||
void init(); | void init(); | ||||
void destroy(); | void destroy(); | ||||
void logIn(const std::string &email, const std::string &password); | void logIn(const std::string &email, const std::string &password); | ||||
@@ -36,6 +29,13 @@ std::string normalizeTag(const std::string &tag); | |||||
bool isSlugValid(const std::string &slug); | bool isSlugValid(const std::string &slug); | ||||
struct Update { | |||||
std::string pluginSlug; | |||||
std::string version; | |||||
std::string changelogUrl; | |||||
}; | |||||
extern const std::set<std::string> allowedTags; | extern const std::set<std::string> allowedTags; | ||||
extern std::vector<Plugin*> plugins; | extern std::vector<Plugin*> plugins; | ||||
@@ -11,7 +11,9 @@ namespace rack { | |||||
namespace random { | namespace random { | ||||
/** Seeds the RNG with the current time */ | |||||
/** Initializes the thread-local RNG state. | |||||
Must call per-thread, otherwise the RNG will always return 0. | |||||
*/ | |||||
void init(); | void init(); | ||||
/** Returns a uniform random uint32_t from 0 to UINT32_MAX */ | /** Returns a uniform random uint32_t from 0 to UINT32_MAX */ | ||||
uint32_t u32(); | uint32_t u32(); | ||||
@@ -150,6 +150,7 @@ struct EngineWorker { | |||||
void start() { | void start() { | ||||
thread = std::thread([&] { | thread = std::thread([&] { | ||||
random::init(); | |||||
run(); | run(); | ||||
}); | }); | ||||
} | } | ||||
@@ -436,7 +437,10 @@ static void Engine_run(Engine *that) { | |||||
void Engine::start() { | void Engine::start() { | ||||
internal->running = true; | internal->running = true; | ||||
internal->thread = std::thread(Engine_run, this); | |||||
internal->thread = std::thread([&] { | |||||
random::init(); | |||||
Engine_run(this); | |||||
}); | |||||
} | } | ||||
void Engine::stop() { | void Engine::stop() { | ||||
@@ -11,7 +11,7 @@ namespace random { | |||||
// xoroshiro128+ | // xoroshiro128+ | ||||
// from http://xoroshiro.di.unimi.it/xoroshiro128plus.c | // from http://xoroshiro.di.unimi.it/xoroshiro128plus.c | ||||
static uint64_t xoroshiro128plus_state[2] = {}; | |||||
thread_local uint64_t xoroshiro128plus_state[2]; | |||||
static uint64_t rotl(const uint64_t x, int k) { | static uint64_t rotl(const uint64_t x, int k) { | ||||
return (x << k) | (x >> (64 - k)); | return (x << k) | (x >> (64 - k)); | ||||
@@ -30,8 +30,6 @@ static uint64_t xoroshiro128plus_next(void) { | |||||
} | } | ||||
void init() { | void init() { | ||||
// Only allow the seed to be initialized once during the lifetime of the program. | |||||
assert(xoroshiro128plus_state[0] == 0 && xoroshiro128plus_state[1] == 0); | |||||
struct timeval tv; | struct timeval tv; | ||||
gettimeofday(&tv, NULL); | gettimeofday(&tv, NULL); | ||||
xoroshiro128plus_state[0] = tv.tv_sec; | xoroshiro128plus_state[0] = tv.tv_sec; | ||||