mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1074418, Guard against talos using IndexedDB after shutdown has started, r=khuey.
This commit is contained in:
parent
02fec1e3a3
commit
6fcaa9131c
@ -3910,20 +3910,7 @@ protected:
|
|||||||
FactoryOp(Factory* aFactory,
|
FactoryOp(Factory* aFactory,
|
||||||
already_AddRefed<ContentParent> aContentParent,
|
already_AddRefed<ContentParent> aContentParent,
|
||||||
const CommonFactoryRequestParams& aCommonParams,
|
const CommonFactoryRequestParams& aCommonParams,
|
||||||
bool aDeleting)
|
bool aDeleting);
|
||||||
: mFactory(aFactory)
|
|
||||||
, mContentParent(Move(aContentParent))
|
|
||||||
, mCommonParams(aCommonParams)
|
|
||||||
, mState(State_Initial)
|
|
||||||
, mStoragePrivilege(mozilla::dom::quota::Content)
|
|
||||||
, mEnforcingQuota(true)
|
|
||||||
, mDeleting(aDeleting)
|
|
||||||
, mBlockedQuotaManager(false)
|
|
||||||
, mChromeWriteAccessAllowed(false)
|
|
||||||
{
|
|
||||||
AssertIsOnBackgroundThread();
|
|
||||||
MOZ_ASSERT(aFactory);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual
|
virtual
|
||||||
~FactoryOp()
|
~FactoryOp()
|
||||||
@ -5075,20 +5062,42 @@ public:
|
|||||||
static QuotaClient*
|
static QuotaClient*
|
||||||
GetInstance()
|
GetInstance()
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
return sInstance;
|
return sInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static bool
|
||||||
NoteBackgroundThread(nsIEventTarget* aBackgroundThread);
|
IsShuttingDownOnMainThread()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
if (sInstance) {
|
||||||
|
return sInstance->mShutdownRequested;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QuotaManager::IsShuttingDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
IsShuttingDownOnNonMainThread()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
|
|
||||||
|
return QuotaManager::IsShuttingDown();
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HasShutDown() const
|
IsShuttingDown() const
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
return mShutdownRequested;
|
return mShutdownRequested;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NoteBackgroundThread(nsIEventTarget* aBackgroundThread);
|
||||||
|
|
||||||
NS_INLINE_DECL_REFCOUNTING(QuotaClient)
|
NS_INLINE_DECL_REFCOUNTING(QuotaClient)
|
||||||
|
|
||||||
virtual mozilla::dom::quota::Client::Type
|
virtual mozilla::dom::quota::Client::Type
|
||||||
@ -5557,6 +5566,10 @@ AllocPBackgroundIDBFactoryParent(PBackgroundParent* aManager,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
nsRefPtr<Factory> actor = Factory::Create(aOptionalWindowId);
|
nsRefPtr<Factory> actor = Factory::Create(aOptionalWindowId);
|
||||||
return actor.forget().take();
|
return actor.forget().take();
|
||||||
}
|
}
|
||||||
@ -5568,6 +5581,7 @@ RecvPBackgroundIDBFactoryConstructor(PBackgroundParent* /* aManager */,
|
|||||||
{
|
{
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
MOZ_ASSERT(aActor);
|
MOZ_ASSERT(aActor);
|
||||||
|
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnNonMainThread());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -5751,6 +5765,7 @@ Factory::Factory(const OptionalWindowId& aOptionalWindowId)
|
|||||||
, mActorDestroyed(false)
|
, mActorDestroyed(false)
|
||||||
{
|
{
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
|
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnNonMainThread());
|
||||||
}
|
}
|
||||||
|
|
||||||
Factory::~Factory()
|
Factory::~Factory()
|
||||||
@ -5763,6 +5778,7 @@ already_AddRefed<Factory>
|
|||||||
Factory::Create(const OptionalWindowId& aOptionalWindowId)
|
Factory::Create(const OptionalWindowId& aOptionalWindowId)
|
||||||
{
|
{
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
|
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnNonMainThread());
|
||||||
|
|
||||||
// If this is the first instance then we need to do some initialization.
|
// If this is the first instance then we need to do some initialization.
|
||||||
if (!sFactoryInstanceCount) {
|
if (!sFactoryInstanceCount) {
|
||||||
@ -5872,6 +5888,10 @@ Factory::AllocPBackgroundIDBFactoryRequestParent(
|
|||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
MOZ_ASSERT(aParams.type() != FactoryRequestParams::T__None);
|
MOZ_ASSERT(aParams.type() != FactoryRequestParams::T__None);
|
||||||
|
|
||||||
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
const CommonFactoryRequestParams* commonParams;
|
const CommonFactoryRequestParams* commonParams;
|
||||||
|
|
||||||
switch (aParams.type()) {
|
switch (aParams.type()) {
|
||||||
@ -5933,6 +5953,7 @@ Factory::RecvPBackgroundIDBFactoryRequestConstructor(
|
|||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
MOZ_ASSERT(aActor);
|
MOZ_ASSERT(aActor);
|
||||||
MOZ_ASSERT(aParams.type() != FactoryRequestParams::T__None);
|
MOZ_ASSERT(aParams.type() != FactoryRequestParams::T__None);
|
||||||
|
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnNonMainThread());
|
||||||
|
|
||||||
auto* op = static_cast<FactoryOp*>(aActor);
|
auto* op = static_cast<FactoryOp*>(aActor);
|
||||||
|
|
||||||
@ -10304,6 +10325,25 @@ AutoSetProgressHandler::Register(
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FactoryOp::FactoryOp(Factory* aFactory,
|
||||||
|
already_AddRefed<ContentParent> aContentParent,
|
||||||
|
const CommonFactoryRequestParams& aCommonParams,
|
||||||
|
bool aDeleting)
|
||||||
|
: mFactory(aFactory)
|
||||||
|
, mContentParent(Move(aContentParent))
|
||||||
|
, mCommonParams(aCommonParams)
|
||||||
|
, mState(State_Initial)
|
||||||
|
, mStoragePrivilege(mozilla::dom::quota::Content)
|
||||||
|
, mEnforcingQuota(true)
|
||||||
|
, mDeleting(aDeleting)
|
||||||
|
, mBlockedQuotaManager(false)
|
||||||
|
, mChromeWriteAccessAllowed(false)
|
||||||
|
{
|
||||||
|
AssertIsOnBackgroundThread();
|
||||||
|
MOZ_ASSERT(aFactory);
|
||||||
|
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnNonMainThread());
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
FactoryOp::Open()
|
FactoryOp::Open()
|
||||||
{
|
{
|
||||||
@ -10314,7 +10354,8 @@ FactoryOp::Open()
|
|||||||
nsRefPtr<ContentParent> contentParent;
|
nsRefPtr<ContentParent> contentParent;
|
||||||
mContentParent.swap(contentParent);
|
mContentParent.swap(contentParent);
|
||||||
|
|
||||||
if (!OperationMayProceed()) {
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnMainThread()) ||
|
||||||
|
!OperationMayProceed()) {
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
}
|
}
|
||||||
@ -10392,7 +10433,8 @@ FactoryOp::RetryCheckPermission()
|
|||||||
nsRefPtr<ContentParent> contentParent;
|
nsRefPtr<ContentParent> contentParent;
|
||||||
mContentParent.swap(contentParent);
|
mContentParent.swap(contentParent);
|
||||||
|
|
||||||
if (!OperationMayProceed()) {
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnMainThread()) ||
|
||||||
|
!OperationMayProceed()) {
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
}
|
}
|
||||||
@ -10428,16 +10470,14 @@ FactoryOp::SendToIOThread()
|
|||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_ASSERT(mState == State_OpenPending);
|
MOZ_ASSERT(mState == State_OpenPending);
|
||||||
|
|
||||||
if (!OperationMayProceed()) {
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnMainThread()) ||
|
||||||
|
!OperationMayProceed()) {
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
QuotaManager* quotaManager = QuotaManager::Get();
|
QuotaManager* quotaManager = QuotaManager::Get();
|
||||||
if (NS_WARN_IF(!quotaManager)) {
|
MOZ_ASSERT(quotaManager);
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Must set this before dispatching otherwise we will race with the IO thread.
|
// Must set this before dispatching otherwise we will race with the IO thread.
|
||||||
mState = State_DatabaseWorkOpen;
|
mState = State_DatabaseWorkOpen;
|
||||||
@ -10819,6 +10859,7 @@ FactoryOp::FinishOpen()
|
|||||||
MOZ_ASSERT(!mDatabaseId.IsEmpty());
|
MOZ_ASSERT(!mDatabaseId.IsEmpty());
|
||||||
MOZ_ASSERT(!mBlockedQuotaManager);
|
MOZ_ASSERT(!mBlockedQuotaManager);
|
||||||
MOZ_ASSERT(!mContentParent);
|
MOZ_ASSERT(!mContentParent);
|
||||||
|
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnMainThread());
|
||||||
|
|
||||||
PersistenceType persistenceType = mCommonParams.metadata().persistenceType();
|
PersistenceType persistenceType = mCommonParams.metadata().persistenceType();
|
||||||
|
|
||||||
@ -10830,10 +10871,8 @@ FactoryOp::FinishOpen()
|
|||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
QuotaManager* quotaManager;
|
QuotaManager* quotaManager = QuotaManager::GetOrCreate();
|
||||||
|
if (NS_WARN_IF(!quotaManager)) {
|
||||||
if (QuotaManager::IsShuttingDown() ||
|
|
||||||
!(quotaManager = QuotaManager::GetOrCreate())) {
|
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
}
|
}
|
||||||
@ -11002,9 +11041,8 @@ OpenDatabaseOp::QuotaManagerOpen()
|
|||||||
MOZ_ASSERT(!mOfflineStorage);
|
MOZ_ASSERT(!mOfflineStorage);
|
||||||
|
|
||||||
QuotaClient* quotaClient = QuotaClient::GetInstance();
|
QuotaClient* quotaClient = QuotaClient::GetInstance();
|
||||||
MOZ_ASSERT(quotaClient);
|
if (NS_WARN_IF(!quotaClient) ||
|
||||||
|
NS_WARN_IF(quotaClient->IsShuttingDown())) {
|
||||||
if (NS_WARN_IF(quotaClient->HasShutDown())) {
|
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
}
|
}
|
||||||
@ -11051,7 +11089,8 @@ OpenDatabaseOp::DoDatabaseWork()
|
|||||||
"OpenDatabaseHelper::DoDatabaseWork",
|
"OpenDatabaseHelper::DoDatabaseWork",
|
||||||
js::ProfileEntry::Category::STORAGE);
|
js::ProfileEntry::Category::STORAGE);
|
||||||
|
|
||||||
if (NS_WARN_IF(QuotaManager::IsShuttingDown()) || !OperationMayProceed()) {
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread()) ||
|
||||||
|
!OperationMayProceed()) {
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
}
|
}
|
||||||
@ -11502,7 +11541,9 @@ OpenDatabaseOp::BeginVersionChange()
|
|||||||
MOZ_ASSERT(!mDatabase);
|
MOZ_ASSERT(!mDatabase);
|
||||||
MOZ_ASSERT(!mVersionChangeTransaction);
|
MOZ_ASSERT(!mVersionChangeTransaction);
|
||||||
|
|
||||||
if (IsActorDestroyed()) {
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread()) ||
|
||||||
|
!OperationMayProceed() ||
|
||||||
|
IsActorDestroyed()) {
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
}
|
}
|
||||||
@ -11658,7 +11699,9 @@ OpenDatabaseOp::SendUpgradeNeeded()
|
|||||||
MOZ_ASSERT(NS_SUCCEEDED(mResultCode));
|
MOZ_ASSERT(NS_SUCCEEDED(mResultCode));
|
||||||
MOZ_ASSERT_IF(!IsActorDestroyed(), mDatabase);
|
MOZ_ASSERT_IF(!IsActorDestroyed(), mDatabase);
|
||||||
|
|
||||||
if (IsActorDestroyed()) {
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread()) ||
|
||||||
|
!OperationMayProceed() ||
|
||||||
|
IsActorDestroyed()) {
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
}
|
}
|
||||||
@ -12066,6 +12109,12 @@ VersionChangeOp::DoDatabaseWork(TransactionBase* aTransaction)
|
|||||||
aTransaction->AssertIsOnTransactionThread();
|
aTransaction->AssertIsOnTransactionThread();
|
||||||
MOZ_ASSERT(mOpenDatabaseOp->mState == State_DatabaseWorkVersionChange);
|
MOZ_ASSERT(mOpenDatabaseOp->mState == State_DatabaseWorkVersionChange);
|
||||||
|
|
||||||
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread()) ||
|
||||||
|
!OperationMayProceed()) {
|
||||||
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
PROFILER_LABEL("IndexedDB",
|
PROFILER_LABEL("IndexedDB",
|
||||||
"VersionChangeOp::DoDatabaseWork",
|
"VersionChangeOp::DoDatabaseWork",
|
||||||
js::ProfileEntry::Category::STORAGE);
|
js::ProfileEntry::Category::STORAGE);
|
||||||
@ -12267,7 +12316,8 @@ DeleteDatabaseOp::DoDatabaseWork()
|
|||||||
"DeleteDatabaseOp::DoDatabaseWork",
|
"DeleteDatabaseOp::DoDatabaseWork",
|
||||||
js::ProfileEntry::Category::STORAGE);
|
js::ProfileEntry::Category::STORAGE);
|
||||||
|
|
||||||
if (!OperationMayProceed()) {
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread()) ||
|
||||||
|
!OperationMayProceed()) {
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
}
|
}
|
||||||
@ -12343,7 +12393,9 @@ DeleteDatabaseOp::BeginVersionChange()
|
|||||||
MOZ_ASSERT(mState == State_BeginVersionChange);
|
MOZ_ASSERT(mState == State_BeginVersionChange);
|
||||||
MOZ_ASSERT(mMaybeBlockedDatabases.IsEmpty());
|
MOZ_ASSERT(mMaybeBlockedDatabases.IsEmpty());
|
||||||
|
|
||||||
if (IsActorDestroyed()) {
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread()) ||
|
||||||
|
!OperationMayProceed() ||
|
||||||
|
IsActorDestroyed()) {
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
}
|
}
|
||||||
@ -12381,7 +12433,9 @@ DeleteDatabaseOp::DispatchToWorkThread()
|
|||||||
MOZ_ASSERT(mState == State_WaitingForTransactionsToComplete);
|
MOZ_ASSERT(mState == State_WaitingForTransactionsToComplete);
|
||||||
MOZ_ASSERT(mMaybeBlockedDatabases.IsEmpty());
|
MOZ_ASSERT(mMaybeBlockedDatabases.IsEmpty());
|
||||||
|
|
||||||
if (IsActorDestroyed()) {
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread()) ||
|
||||||
|
!OperationMayProceed() ||
|
||||||
|
IsActorDestroyed()) {
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
}
|
}
|
||||||
@ -12474,6 +12528,12 @@ VersionChangeOp::RunOnMainThread()
|
|||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_ASSERT(mDeleteDatabaseOp->mState == State_DatabaseWorkVersionChange);
|
MOZ_ASSERT(mDeleteDatabaseOp->mState == State_DatabaseWorkVersionChange);
|
||||||
|
|
||||||
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnMainThread()) ||
|
||||||
|
!OperationMayProceed()) {
|
||||||
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
QuotaManager* quotaManager = QuotaManager::Get();
|
QuotaManager* quotaManager = QuotaManager::Get();
|
||||||
MOZ_ASSERT(quotaManager);
|
MOZ_ASSERT(quotaManager);
|
||||||
|
|
||||||
@ -12497,7 +12557,8 @@ VersionChangeOp::RunOnIOThread()
|
|||||||
"DeleteDatabaseOp::VersionChangeOp::RunOnIOThread",
|
"DeleteDatabaseOp::VersionChangeOp::RunOnIOThread",
|
||||||
js::ProfileEntry::Category::STORAGE);
|
js::ProfileEntry::Category::STORAGE);
|
||||||
|
|
||||||
if (!OperationMayProceed()) {
|
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread()) ||
|
||||||
|
!OperationMayProceed()) {
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user