I know that building multiple modules in separate threads that belong to the same engine is "thread safe" because the engine will only allow building one module at a time.
It looks like if multiple threads are calling "asIScriptEngine::GetModule" and "asIScriptModule::Discard" at the same time they calling code should acquire a lock first, since these functions modify an array belonging to the engine. I'm not suggesting that the functions themselves should block. I am just confirming that the burden is on the application to synchronize those module-related activities.
// Create a new script module
asAcquireExclusiveLock();
asIScriptModule *mod = engine->GetModule("module", asGM_ALWAYS_CREATE);
asReleaseExclusiveLock();
// Load and add the script sections to the module
string script;
LoadScriptFile("script.as", script);
mod->AddScriptSection("script.as", script.c_str());
// Build the module
int r = mod->Build();
// ... Do something with the module
asAcquireExclusiveLock();
mod->Discard();
asReleaseExclusiveLock();