WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
NEW
59801
fast/workers/storage/use-same-database-in-page-and-workers.html sometimes asserts in WorkerThread::workerThread
https://bugs.webkit.org/show_bug.cgi?id=59801
Summary
fast/workers/storage/use-same-database-in-page-and-workers.html sometimes ass...
Adam Roben (:aroben)
Reported
2011-04-29 09:49:00 PDT
fast/workers/storage/use-same-database-in-page-and-workers.html sometimes asserts in WorkerThread::workerThread. See <
http://build.webkit.org/results/Leopard%20Intel%20Debug%20(Tests)/r85325%20(29670)/fast/workers/storage/use-same-database-in-page-and-workers-crash-log.txt
> for an example.
Attachments
Add attachment
proposed patch, testcase, etc.
Adam Roben (:aroben)
Comment 1
2011-04-29 09:49:15 PDT
<
rdar://problem/9358641
>
Michael Nordman
Comment 2
2011-04-29 13:15:33 PDT
void* WorkerThread::workerThread() { { MutexLocker lock(m_threadCreationMutex); m_workerContext = createWorkerContext(m_startupData->m_scriptURL, m_startupData->m_userAgent); if (m_runLoop.terminated()) { // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet, // forbidExecution() couldn't be called from stop(). m_workerContext->script()->forbidExecution(); } } WorkerScriptController* script = m_workerContext->script(); script->evaluate(ScriptSourceCode(m_startupData->m_sourceCode, m_startupData->m_scriptURL)); // Free the startup data to cause its member variable deref's happen on the worker's thread (since // all ref/derefs of these objects are happening on the thread at this point). Note that // WorkerThread::~WorkerThread happens on a different thread where it was created. m_startupData.clear(); runEventLoop(); ThreadIdentifier threadID = m_threadID; ASSERT(m_workerContext->hasOneRef()); ******* TRIPPING ON THIS (?) ******* // The below assignment will destroy the context, which will in turn notify messaging proxy. // We cannot let any objects survive past thread exit, because no other thread will run GC or otherwise destroy them. m_workerContext = 0; // Clean up WebCore::ThreadGlobalData before WTF::WTFThreadData goes away! threadGlobalData().destroy(); // The thread object may be already destroyed from notification now, don't try to access "this". detachThread(threadID); return 0; }
Adam Roben (:aroben)
Comment 3
2011-04-29 13:25:33 PDT
From <
http://build.webkit.org/results/Leopard%20Intel%20Debug%20(Tests)/r85325%20(29670)/fast/workers/storage/use-same-database-in-page-and-workers-stderr.txt
>: ASSERTION FAILED: m_workerContext->hasOneRef() /Volumes/Big/WebKit-BuildSlave/leopard-intel-debug/build/Source/WebCore/workers/WorkerThread.cpp(145) : void* WebCore::WorkerThread::workerThread() 1 WebCore::WorkerThread::workerThreadCount() 2 WebCore::WorkerThread::workerThreadCount() 3 WTF::createThread(void* (*)(void*), void*) 4 _pthread_start 5 thread_start
Alexey Proskuryakov
Comment 4
2011-04-29 13:26:17 PDT
That's a fairly important assertion - if that fails, the worker context may leak (since no GC will happen after the thread has exited).
Michael Nordman
Comment 5
2011-04-29 17:05:08 PDT
This may be contributing to the problem. Databases hold a reference to their ScriptExecutionContext and there is no guarantee that a Database is finally released and deleted on the context thread. Database::~Database() { // The reference to the ScriptExecutionContext needs to be cleared on the JavaScript thread. // If we're on that thread already, we can just let the RefPtr's destruction do the dereffing. if (!m_scriptExecutionContext->isContextThread()) { // Grab a pointer to the script execution here because we're releasing it when we pass it to // DerefContextTask::create. ScriptExecutionContext* scriptExecutionContext = m_scriptExecutionContext.get(); scriptExecutionContext->postTask(DerefContextTask::create(m_scriptExecutionContext.release())); } } A similar situation exists with SQLTransactions and SQLStatements and the callback objects they hold, there is no guarantee that SQLTransactions and SQLStatements are deleted on the context thread, but the callback must be released on the context thread... see class SQLCallbackWrapper. Maybe something that could help would be to have the safeRelease task created by SQLCallbackWrapper use the isCleanupTask() feature of ScriptExecutionContext::Task as does DerefContextTask? class SQLCallbackWrapper { ... void clear() { ScriptExecutionContext* context; T* callback; { MutexLocker locker(m_mutex); if (!m_callback) { ASSERT(!m_scriptExecutionContext); return; } if (m_scriptExecutionContext->isContextThread()) { m_callback = 0; m_scriptExecutionContext = 0; return; } context = m_scriptExecutionContext.release().leakRef(); callback = m_callback.release().leakRef(); } context->postTask(createCallbackTask(&safeRelease, callback)); ******* THIS TASK ****** } class ScriptExecutionContext { ... class Task { WTF_MAKE_NONCOPYABLE(Task); WTF_MAKE_FAST_ALLOCATED; public: Task() { } virtual ~Task(); virtual void performTask(ScriptExecutionContext*) = 0; // Certain tasks get marked specially so that they aren't discarded, and are executed, // when the context is shutting down its message queue. virtual bool isCleanupTask() const { return false; } ****** USE THIS FEATURE ****** };
Ryosuke Niwa
Comment 6
2012-01-10 02:05:32 PST
***
Bug 49869
has been marked as a duplicate of this bug. ***
Gustavo Noronha (kov)
Comment 7
2012-05-02 14:32:04 PDT
***
Bug 56147
has been marked as a duplicate of this bug. ***
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug