// static uint64_t IDBRequest::NextSerialNumber() { BackgroundChildImpl::ThreadLocal* threadLocal = BackgroundChildImpl::GetThreadLocalForCurrentThread(); MOZ_ASSERT(threadLocal); ThreadLocal* idbThreadLocal = threadLocal->mIndexedDBThreadLocal; MOZ_ASSERT(idbThreadLocal); return idbThreadLocal->NextRequestSN(); }
inline void operator()() { staticThinggy = new Thinggy; staticThreadLocal.set(staticThinggy); waiting = true; gate.Set(); waiter.Wait(); waiting = false; threadLocalHadValue = staticThreadLocal.get() != NULL; gate.Set(); }
void test_threadlocalstroage() { g_tls->set(10); g_tls->print(); Thread t1(std::bind(testTLS, 23)); t1.join(); Thread t2(std::bind(testTLS, 100)); t2.join(); g_tls->print(); }
const string& Thread::getTidString() { if (t_tidstring.value().empty()) { Thread::ThreadHandle ret_tid; ret_tid = ::pthread_self(); t_tid.value() = ret_tid; char buf[32] = {0}; snprintf(buf, sizeof(buf), "%ll", (uint64_t)ret_tid); t_tidstring.value() = buf; } return t_tidstring; }
// static IDBTransaction* IDBTransaction::GetCurrent() { using namespace mozilla::ipc; MOZ_ASSERT(BackgroundChild::GetForCurrentThread()); BackgroundChildImpl::ThreadLocal* threadLocal = BackgroundChildImpl::GetThreadLocalForCurrentThread(); MOZ_ASSERT(threadLocal); ThreadLocal* idbThreadLocal = threadLocal->mIndexedDBThreadLocal; MOZ_ASSERT(idbThreadLocal); return idbThreadLocal->GetCurrentTransaction(); }
//static CoroutineManager& CoroutineManager::getInstance() { CoroutineManager *pInstance = coroutineManagerInstance; if(!pInstance) { pInstance = new CoroutineManager(); coroutineManagerInstance.set(pInstance); } return *pInstance; }
void ArdbServer::TouchIdleConn(Channel* ch) { static ThreadLocal<IdleConnManager> kLocalIdleConns; uint64 now = get_current_epoch_millis(); IdleConn conn; conn.conn_id = ch->GetID(); conn.ts = now; IdleConnManager& m = kLocalIdleConns.GetValue(); if (m.timer_id == -1) { m.serv = &(ch->GetService()); m.maxIdleTime = m_cfg.timeout * 1000; m.lru.SetMaxCacheSize(m_cfg.max_clients); m.timer_id = ch->GetService().GetTimer().Schedule(&m, 1, 5, SECONDS); } IdleConn tmp; m.lru.Insert(conn.conn_id, conn, tmp); }
virtual RequestHandler *createRequestHandler() { s_rpc_request_handler->setServerInfo(m_serverInfo); if (s_rpc_request_handler->needReset() || s_rpc_request_handler->incRequest() > m_serverInfo->getMaxRequest()) { s_rpc_request_handler.reset(); s_rpc_request_handler->setServerInfo(m_serverInfo); s_rpc_request_handler->incRequest(); } return s_rpc_request_handler.get(); }
BackgroundHangThread* BackgroundHangThread::FindThread() { if (sTlsKey.initialized()) { // Use TLS if available return sTlsKey.get(); } // If TLS is unavailable, we can search through the thread list RefPtr<BackgroundHangManager> manager(BackgroundHangManager::sInstance); MOZ_ASSERT(manager, "Creating BackgroundHangMonitor after shutdown"); PRThread* threadID = PR_GetCurrentThread(); // Lock thread list for traversal MonitorAutoLock autoLock(manager->mLock); for (BackgroundHangThread* thread = manager->mHangThreads.getFirst(); thread; thread = thread->getNext()) { if (thread->mThreadID == threadID) { return thread; } } // Current thread is not initialized return nullptr; }
TEST(TestThreadLocal, Simple) { GlobalThreadLocal runnable; thread t(runnable); gate.Wait(); EXPECT_TRUE(runnable.waiting); EXPECT_TRUE(staticThinggy != NULL); EXPECT_TRUE(staticThreadLocal.get() == NULL); waiter.Set(); gate.Wait(); EXPECT_TRUE(runnable.threadLocalHadValue); EXPECT_TRUE(!destructorCalled); delete staticThinggy; EXPECT_TRUE(destructorCalled); cleanup(); }
namespace thread_tls2 { class TestTLS { public: TestTLS() { num = -1; cout << "TestTLS : [" << this << "] " << num << "\n"; } ~TestTLS() { cout << "~TestTLS : [" << this << "] " << num << "\n"; } void set(int n) { num = n; } void plus(int n) { num += n; } void print() { cout << "print : [" << this << "] " << num << "\n"; } private: int num; }; ThreadLocal<TestTLS> g_tls; void testTLS(int i) { g_tls->plus(i); g_tls->print(); } void test_threadtls() { g_tls->set(10); g_tls->print(); Thread t1(std::bind(testTLS, 23)); t1.join(); Thread t2(std::bind(testTLS, 100)); t2.join(); g_tls->print(); } }
static void Startup() { /* We can tolerate init() failing. The if block turns off warn_unused_result. */ if (!sTlsKey.init()) {} }
already_AddRefed<IDBOpenDBRequest> IDBFactory::OpenInternal(JSContext* aCx, nsIPrincipal* aPrincipal, const nsAString& aName, const Optional<uint64_t>& aVersion, const Optional<StorageType>& aStorageType, bool aDeleting, CallerType aCallerType, ErrorResult& aRv) { MOZ_ASSERT(mWindow || mOwningObject); MOZ_ASSERT_IF(!mWindow, !mPrivateBrowsingMode); CommonFactoryRequestParams commonParams; PrincipalInfo& principalInfo = commonParams.principalInfo(); if (aPrincipal) { if (!NS_IsMainThread()) { MOZ_CRASH("Figure out security checks for workers! What's this " "aPrincipal we have on a worker thread?"); } MOZ_ASSERT(aCallerType == CallerType::System); MOZ_DIAGNOSTIC_ASSERT(mPrivateBrowsingMode == (aPrincipal->GetPrivateBrowsingId() > 0)); if (NS_WARN_IF(NS_FAILED(PrincipalToPrincipalInfo(aPrincipal, &principalInfo)))) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } if (principalInfo.type() != PrincipalInfo::TContentPrincipalInfo && principalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } } else { principalInfo = *mPrincipalInfo; } uint64_t version = 0; if (!aDeleting && aVersion.WasPassed()) { if (aVersion.Value() < 1) { aRv.ThrowTypeError<MSG_INVALID_VERSION>(); return nullptr; } version = aVersion.Value(); } // Nothing can be done here if we have previously failed to create a // background actor. if (mBackgroundActorFailed) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } PersistenceType persistenceType; bool isInternal = principalInfo.type() == PrincipalInfo::TSystemPrincipalInfo; if (!isInternal && principalInfo.type() == PrincipalInfo::TContentPrincipalInfo) { nsCString origin = principalInfo.get_ContentPrincipalInfo().originNoSuffix(); isInternal = QuotaManager::IsOriginInternal(origin); } // Allow storage attributes for add-ons independent of the pref. // This works in the main thread only, workers don't have the principal. bool isAddon = false; if (NS_IsMainThread()) { // aPrincipal is passed inconsistently, so even when we are already on // the main thread, we may have been passed a null aPrincipal. nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(principalInfo); if (principal) { nsAutoString addonId; Unused << NS_WARN_IF(NS_FAILED(principal->GetAddonId(addonId))); isAddon = !addonId.IsEmpty(); } } if (isInternal) { // Chrome privilege and internal origins always get persistent storage. persistenceType = PERSISTENCE_TYPE_PERSISTENT; } else if (isAddon || DOMPrefs::IndexedDBStorageOptionsEnabled()) { persistenceType = PersistenceTypeFromStorage(aStorageType); } else { persistenceType = PERSISTENCE_TYPE_DEFAULT; } DatabaseMetadata& metadata = commonParams.metadata(); metadata.name() = aName; metadata.persistenceType() = persistenceType; FactoryRequestParams params; if (aDeleting) { metadata.version() = 0; params = DeleteDatabaseRequestParams(commonParams); } else { metadata.version() = version; params = OpenDatabaseRequestParams(commonParams); } if (!mBackgroundActor) { BackgroundChildImpl::ThreadLocal* threadLocal = BackgroundChildImpl::GetThreadLocalForCurrentThread(); nsAutoPtr<ThreadLocal> newIDBThreadLocal; ThreadLocal* idbThreadLocal; if (threadLocal && threadLocal->mIndexedDBThreadLocal) { idbThreadLocal = threadLocal->mIndexedDBThreadLocal; } else { nsCOMPtr<nsIUUIDGenerator> uuidGen = do_GetService("@mozilla.org/uuid-generator;1"); MOZ_ASSERT(uuidGen); nsID id; MOZ_ALWAYS_SUCCEEDS(uuidGen->GenerateUUIDInPlace(&id)); newIDBThreadLocal = idbThreadLocal = new ThreadLocal(id); } PBackgroundChild* backgroundActor = BackgroundChild::GetOrCreateForCurrentThread(); if (NS_WARN_IF(!backgroundActor)) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } { BackgroundFactoryChild* actor = new BackgroundFactoryChild(this); // Set EventTarget for the top-level actor. // All child actors created later inherit the same event target. backgroundActor->SetEventTargetForActor(actor, EventTarget()); MOZ_ASSERT(actor->GetActorEventTarget()); mBackgroundActor = static_cast<BackgroundFactoryChild*>( backgroundActor->SendPBackgroundIDBFactoryConstructor(actor, idbThreadLocal->GetLoggingInfo())); if (NS_WARN_IF(!mBackgroundActor)) { mBackgroundActorFailed = true; IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } } if (newIDBThreadLocal) { if (!threadLocal) { threadLocal = BackgroundChildImpl::GetThreadLocalForCurrentThread(); } MOZ_ASSERT(threadLocal); MOZ_ASSERT(!threadLocal->mIndexedDBThreadLocal); threadLocal->mIndexedDBThreadLocal = newIDBThreadLocal.forget(); } } RefPtr<IDBOpenDBRequest> request; if (mWindow) { JS::Rooted<JSObject*> scriptOwner(aCx, nsGlobalWindowInner::Cast(mWindow.get())->FastGetGlobalJSObject()); MOZ_ASSERT(scriptOwner); request = IDBOpenDBRequest::CreateForWindow(aCx, this, mWindow, scriptOwner); } else { JS::Rooted<JSObject*> scriptOwner(aCx, mOwningObject); request = IDBOpenDBRequest::CreateForJS(aCx, this, scriptOwner); if (!request) { MOZ_ASSERT(!NS_IsMainThread()); aRv.ThrowUncatchableException(); return nullptr; } } MOZ_ASSERT(request); if (aDeleting) { IDB_LOG_MARK("IndexedDB %s: Child Request[%llu]: " "indexedDB.deleteDatabase(\"%s\")", "IndexedDB %s: C R[%llu]: IDBFactory.deleteDatabase()", IDB_LOG_ID_STRING(), request->LoggingSerialNumber(), NS_ConvertUTF16toUTF8(aName).get()); } else { IDB_LOG_MARK("IndexedDB %s: Child Request[%llu]: " "indexedDB.open(\"%s\", %s)", "IndexedDB %s: C R[%llu]: IDBFactory.open()", IDB_LOG_ID_STRING(), request->LoggingSerialNumber(), NS_ConvertUTF16toUTF8(aName).get(), IDB_LOG_STRINGIFY(aVersion)); } nsresult rv = InitiateRequest(request, params); if (NS_WARN_IF(NS_FAILED(rv))) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } return request.forget(); }
void Random::secureRandom(void* data, size_t size) { static ThreadLocal<BufferedRandomDevice> bufferedRandomDevice; bufferedRandomDevice->get(data, size); }
int get() { return value.get(); }
int LUAInterpreter::CallArdb(lua_State *lua, bool raise_error) { int j, argc = lua_gettop(lua); ArgumentArray cmdargs; /* Require at least one argument */ if (argc == 0) { luaPushError(lua, "Please specify at least one argument for redis.call()"); return 1; } /* Build the arguments vector */ for (j = 0; j < argc; j++) { if (!lua_isstring(lua, j + 1)) break; std::string arg; arg.append(lua_tostring(lua, j + 1), lua_strlen(lua, j + 1)); cmdargs.push_back(arg); } /* Check if one of the arguments passed by the Lua script * is not a string or an integer (lua_isstring() return true for * integers as well). */ if (j != argc) { luaPushError(lua, "Lua redis() command arguments must be strings or integers"); return 1; } /* Setup our fake client for command execution */ RedisCommandFrame cmd(cmdargs); Ardb::RedisCommandHandlerSetting* setting = g_db->FindRedisCommandHandlerSetting(cmd); /* Command lookup */ if (NULL == setting) { luaPushError(lua, "Unknown Redis command called from Lua script"); return -1; } /* There are commands that are not allowed inside scripts. */ if (!setting->IsAllowedInScript()) { luaPushError(lua, "This Redis command is not allowed from scripts"); return -1; } LuaExecContext* ctx = g_lua_exec_ctx.GetValue(); /* Write commands are forbidden against read-only slaves, or if a * command marked as non-deterministic was already called in the context * of this script. */ if (setting->IsWriteCommand()) { if (!g_db->GetConf().master_host.empty() && g_db->GetConf().slave_readonly && !g_db->IsLoadingData() && !(ctx->caller->flags.slave)) { luaPushError(lua, "-READONLY You can't write against a read only slave."); return -1; } } Context& lua_ctx = ctx->exec; RedisReply& reply = lua_ctx.GetReply(); reply.Clear(); lua_ctx.ClearFlags(); lua_ctx.flags.lua = 1; g_db->DoCall(lua_ctx, *setting, cmd); if (raise_error && reply.type != REDIS_REPLY_ERROR) { raise_error = 0; } redisProtocolToLuaType(lua, reply); if (raise_error) { /* If we are here we should have an error in the stack, in the * form of a table with an "err" field. Extract the string to * return the plain error. */ lua_pushstring(lua, "err"); lua_gettable(lua, -2); return lua_error(lua); } return 1; }
LuaExecContextGuard() { g_lua_exec_ctx.SetValue(&ctx); }
ArdbConnContext* GetCurrentContext() { return m_ctx_local.GetValue(); }
virtual void onThreadExit(RequestHandler *handler) { s_rpc_request_handler.reset(); }
void testTLS(int i) { g_tls->plus(i); g_tls->print(); }
TEST(ThreadLocalStorage, NotSetReturnsNull) { static ThreadLocal<int> number; EXPECT_EQ(nullptr, number.get()); }
TEST(ThreadLocal, Unthreaded) { EXPECT_EQ(sVar.get(), 0); sVar = 10; EXPECT_EQ(sVar.get(), 10); }
namespace HPHP { /////////////////////////////////////////////////////////////////////////////// std::set<std::string> SatelliteServerInfo::InternalURLs; int SatelliteServerInfo::DanglingServerPort = 0; SatelliteServerInfo::SatelliteServerInfo(Hdf hdf) { m_name = hdf.getName(); m_port = hdf["Port"].getInt16(0); m_threadCount = hdf["ThreadCount"].getInt32(5); m_maxRequest = hdf["MaxRequest"].getInt32(500); m_maxDuration = hdf["MaxDuration"].getInt32(120); m_timeoutSeconds = hdf["TimeoutSeconds"].getInt32(RuntimeOption::RequestTimeoutSeconds); m_warmupDoc = hdf["WarmupDocument"].getString(""); m_reqInitFunc = hdf["RequestInitFunction"].getString(""); m_password = hdf["Password"].getString(""); string type = hdf["Type"]; if (type == "InternalPageServer") { m_type = SatelliteServer::KindOfInternalPageServer; vector<string> urls; hdf["URLs"].get(urls); for (unsigned int i = 0; i < urls.size(); i++) { m_urls.insert(format_pattern(urls[i])); } if (hdf["BlockMainServer"].getBool(true)) { InternalURLs.insert(m_urls.begin(), m_urls.end()); } } else if (type == "DanglingPageServer") { m_type = SatelliteServer::KindOfDanglingPageServer; DanglingServerPort = m_port; } else if (type == "RPCServer") { m_type = SatelliteServer::KindOfRPCServer; } else if (type == "ThriftServer") { m_type = SatelliteServer::KindOfThriftServer; } else { m_type = SatelliteServer::UnknownType; } } /////////////////////////////////////////////////////////////////////////////// // InternalPageServer: LibEventServer + allowed URL checking DECLARE_BOOST_TYPES(InternalPageServerImpl); class InternalPageServerImpl : public LibEventServer { public: InternalPageServerImpl(const std::string &address, int port, int thread, int timeoutSeconds) : LibEventServer(address, port, thread, timeoutSeconds) { } void create(const std::set<std::string> &urls) { m_allowedURLs = urls; } virtual bool shouldHandle(const std::string &cmd) { String url(cmd.c_str(), cmd.size(), AttachLiteral); for (set<string>::const_iterator iter = m_allowedURLs.begin(); iter != m_allowedURLs.end(); ++iter) { Variant ret = preg_match (String(iter->c_str(), iter->size(), AttachLiteral), url); if (ret.toInt64() > 0) { return true; } } return false; } private: std::set<std::string> m_allowedURLs; }; class InternalPageServer : public SatelliteServer { public: InternalPageServer(SatelliteServerInfoPtr info) { InternalPageServerImplPtr server (new TypedServer<InternalPageServerImpl, HttpRequestHandler> (RuntimeOption::ServerIP, info->getPort(), info->getThreadCount(), info->getTimeoutSeconds())); server->create(info->getURLs()); m_server = server; } virtual void start() { m_server->start(); } virtual void stop() { m_server->stop(); m_server->waitForEnd(); } private: ServerPtr m_server; }; /////////////////////////////////////////////////////////////////////////////// // DanglingPageServer: same as LibEventServer class DanglingPageServer : public SatelliteServer { public: DanglingPageServer(SatelliteServerInfoPtr info) { m_server = ServerPtr (new TypedServer<LibEventServer, HttpRequestHandler> (RuntimeOption::ServerIP, info->getPort(), info->getThreadCount(), info->getTimeoutSeconds())); } virtual void start() { m_server->start(); } virtual void stop() { m_server->stop(); m_server->waitForEnd(); } private: ServerPtr m_server; }; /////////////////////////////////////////////////////////////////////////////// // RPCServer: LibEventServer + RPCRequestHandler static ThreadLocal<RPCRequestHandler> s_rpc_request_handler; class RPCServerImpl : public LibEventServer { public: RPCServerImpl(const std::string &address, SatelliteServerInfoPtr info) : LibEventServer(address, info->getPort(), info->getThreadCount(), info->getTimeoutSeconds()), m_serverInfo(info) { } virtual RequestHandler *createRequestHandler() { s_rpc_request_handler->setServerInfo(m_serverInfo); if (s_rpc_request_handler->needReset() || s_rpc_request_handler->incRequest() > m_serverInfo->getMaxRequest()) { s_rpc_request_handler.reset(); s_rpc_request_handler->setServerInfo(m_serverInfo); s_rpc_request_handler->incRequest(); } return s_rpc_request_handler.get(); } virtual void releaseRequestHandler(RequestHandler *handler) { // do nothing } virtual void onThreadExit(RequestHandler *handler) { s_rpc_request_handler.reset(); } private: SatelliteServerInfoPtr m_serverInfo; }; class RPCServer : public SatelliteServer { public: RPCServer(SatelliteServerInfoPtr info) { m_server = ServerPtr(new RPCServerImpl(RuntimeOption::ServerIP, info)); } virtual void start() { m_server->start(); } virtual void stop() { m_server->stop(); m_server->waitForEnd(); } private: ServerPtr m_server; }; /////////////////////////////////////////////////////////////////////////////// // SatelliteServer SatelliteServerPtr SatelliteServer::Create(SatelliteServerInfoPtr info) { SatelliteServerPtr satellite; switch (info->getType()) { case KindOfInternalPageServer: satellite = SatelliteServerPtr(new InternalPageServer(info)); break; case KindOfDanglingPageServer: satellite = SatelliteServerPtr(new DanglingPageServer(info)); break; case KindOfRPCServer: satellite = SatelliteServerPtr(new RPCServer(info)); break; case KindOfThriftServer: // TODO break; default: ASSERT(false); } if (satellite) { satellite->setName(info->getName()); } return satellite; } /////////////////////////////////////////////////////////////////////////////// }
NestedDiagnosticContext& NestedDiagnosticContext::current() { static ThreadLocal<NestedDiagnosticContext> ndc; return ndc.get(); }
luaLoadLib(m_lua, "cjson", luaopen_cjson); luaLoadLib(m_lua, "struct", luaopen_struct); luaLoadLib(m_lua, "cmsgpack", luaopen_cmsgpack); return 0; } int LUAInterpreter::RemoveUnsupportedFunctions() { lua_pushnil(m_lua); lua_setglobal(m_lua, "loadfile"); return 0; } static ThreadLocal<Context*> g_local_ctx; static ThreadLocal<LuaExecContext*> g_lua_exec_ctx; struct LuaExecContextGuard { LuaExecContext ctx; LuaExecContextGuard() { g_lua_exec_ctx.SetValue(&ctx); } ~LuaExecContextGuard() { g_lua_exec_ctx.SetValue(NULL); } }; int LUAInterpreter::CallArdb(lua_State *lua, bool raise_error)
ThreadLocalVariables() : canceled(false){ value.set(0); }
~LuaExecContextGuard() { g_lua_exec_ctx.SetValue(NULL); }
void increment() { value.set(value.get() + 1); }
already_AddRefed<IDBOpenDBRequest> IDBFactory::OpenInternal(JSContext* aCx, nsIPrincipal* aPrincipal, const nsAString& aName, const Optional<uint64_t>& aVersion, const Optional<StorageType>& aStorageType, bool aDeleting, ErrorResult& aRv) { MOZ_ASSERT(mWindow || mOwningObject); MOZ_ASSERT_IF(!mWindow, !mPrivateBrowsingMode); CommonFactoryRequestParams commonParams; commonParams.privateBrowsingMode() = mPrivateBrowsingMode; PrincipalInfo& principalInfo = commonParams.principalInfo(); if (aPrincipal) { if (!NS_IsMainThread()) { MOZ_CRASH("Figure out security checks for workers!"); } MOZ_ASSERT(nsContentUtils::IsCallerChrome()); if (NS_WARN_IF(NS_FAILED(PrincipalToPrincipalInfo(aPrincipal, &principalInfo)))) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } if (principalInfo.type() != PrincipalInfo::TContentPrincipalInfo && principalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } } else { principalInfo = *mPrincipalInfo; } uint64_t version = 0; if (!aDeleting && aVersion.WasPassed()) { if (aVersion.Value() < 1) { aRv.ThrowTypeError<MSG_INVALID_VERSION>(); return nullptr; } version = aVersion.Value(); } // Nothing can be done here if we have previously failed to create a // background actor. if (mBackgroundActorFailed) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } PersistenceType persistenceType; if (principalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) { // Chrome privilege always gets persistent storage. persistenceType = PERSISTENCE_TYPE_PERSISTENT; } else { persistenceType = PersistenceTypeFromStorage(aStorageType); } DatabaseMetadata& metadata = commonParams.metadata(); metadata.name() = aName; metadata.persistenceType() = persistenceType; FactoryRequestParams params; if (aDeleting) { metadata.version() = 0; params = DeleteDatabaseRequestParams(commonParams); } else { metadata.version() = version; params = OpenDatabaseRequestParams(commonParams); } if (!mBackgroundActor && mPendingRequests.IsEmpty()) { BackgroundChildImpl::ThreadLocal* threadLocal = BackgroundChildImpl::GetThreadLocalForCurrentThread(); nsAutoPtr<ThreadLocal> newIDBThreadLocal; ThreadLocal* idbThreadLocal; if (threadLocal && threadLocal->mIndexedDBThreadLocal) { idbThreadLocal = threadLocal->mIndexedDBThreadLocal; } else { nsCOMPtr<nsIUUIDGenerator> uuidGen = do_GetService("@mozilla.org/uuid-generator;1"); MOZ_ASSERT(uuidGen); nsID id; MOZ_ALWAYS_SUCCEEDS(uuidGen->GenerateUUIDInPlace(&id)); newIDBThreadLocal = idbThreadLocal = new ThreadLocal(id); } if (PBackgroundChild* actor = BackgroundChild::GetForCurrentThread()) { BackgroundActorCreated(actor, idbThreadLocal->GetLoggingInfo()); } else { // We need to start the sequence to create a background actor for this // thread. RefPtr<BackgroundCreateCallback> cb = new BackgroundCreateCallback(this, idbThreadLocal->GetLoggingInfo()); if (NS_WARN_IF(!BackgroundChild::GetOrCreateForCurrentThread(cb))) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } } if (newIDBThreadLocal) { if (!threadLocal) { threadLocal = BackgroundChildImpl::GetThreadLocalForCurrentThread(); } MOZ_ASSERT(threadLocal); MOZ_ASSERT(!threadLocal->mIndexedDBThreadLocal); threadLocal->mIndexedDBThreadLocal = newIDBThreadLocal.forget(); } } RefPtr<IDBOpenDBRequest> request; if (mWindow) { JS::Rooted<JSObject*> scriptOwner(aCx, nsGlobalWindow::Cast(mWindow.get())->FastGetGlobalJSObject()); MOZ_ASSERT(scriptOwner); request = IDBOpenDBRequest::CreateForWindow(aCx, this, mWindow, scriptOwner); } else { JS::Rooted<JSObject*> scriptOwner(aCx, mOwningObject); request = IDBOpenDBRequest::CreateForJS(aCx, this, scriptOwner); if (!request) { MOZ_ASSERT(!NS_IsMainThread()); aRv.ThrowUncatchableException(); return nullptr; } } MOZ_ASSERT(request); if (aDeleting) { IDB_LOG_MARK("IndexedDB %s: Child Request[%llu]: " "indexedDB.deleteDatabase(\"%s\")", "IndexedDB %s: C R[%llu]: IDBFactory.deleteDatabase()", IDB_LOG_ID_STRING(), request->LoggingSerialNumber(), NS_ConvertUTF16toUTF8(aName).get()); } else { IDB_LOG_MARK("IndexedDB %s: Child Request[%llu]: " "indexedDB.open(\"%s\", %s)", "IndexedDB %s: C R[%llu]: IDBFactory.open()", IDB_LOG_ID_STRING(), request->LoggingSerialNumber(), NS_ConvertUTF16toUTF8(aName).get(), IDB_LOG_STRINGIFY(aVersion)); } // If we already have a background actor then we can start this request now. if (mBackgroundActor) { nsresult rv = InitiateRequest(request, params); if (NS_WARN_IF(NS_FAILED(rv))) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } } else { mPendingRequests.AppendElement(new PendingRequestInfo(request, params)); } return request.forget(); }
Thread::ThreadHandle Thread::getCurrentThreadID() { getTidString(); return t_tid.value(); }