Changeset 162235 in webkit


Ignore:
Timestamp:
Jan 17, 2014 5:58:16 PM (10 years ago)
Author:
andersca@apple.com
Message:

Add a callOnMainThreadAndWait variant in SocketStreamHandle
https://bugs.webkit.org/show_bug.cgi?id=127180

Reviewed by Geoffrey Garen.

Source/WebCore:

WTF::callOnMainThreadAndWait was only used inside SocketStreamHandleCFNet.cpp,
so add an improved version there which is implemented in terms of callOnMainThread and
with the bonus of handling spurious wake-ups correctly (the old version didn't).

  • platform/network/cf/SocketStreamHandle.h:
  • platform/network/cf/SocketStreamHandleCFNet.cpp:

(WebCore::callOnMainThreadAndWait):
(WebCore::SocketStreamHandle::pacExecutionCallback):
(WebCore::SocketStreamHandle::readStreamCallback):
(WebCore::SocketStreamHandle::writeStreamCallback):

Source/WTF:

Remove callOnMainThreadAndWait from WTF.

  • wtf/MainThread.cpp:
  • wtf/MainThread.h:
Location:
trunk/Source
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r162198 r162235  
     12014-01-17  Anders Carlsson  <andersca@apple.com>
     2
     3        Add a callOnMainThreadAndWait variant in SocketStreamHandle
     4        https://bugs.webkit.org/show_bug.cgi?id=127180
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Remove callOnMainThreadAndWait from WTF.
     9
     10        * wtf/MainThread.cpp:
     11        * wtf/MainThread.h:
     12
    1132014-01-17  Peter Molnar  <pmolnar.u-szeged@partner.samsung.com>
    214
  • trunk/Source/WTF/wtf/MainThread.cpp

    r161886 r162235  
    195195}
    196196
    197 void callOnMainThreadAndWait(MainThreadFunction* function, void* context)
    198 {
    199     ASSERT(function);
    200 
    201     if (isMainThread()) {
    202         function(context);
    203         return;
    204     }
    205 
    206     ThreadCondition syncFlag;
    207     Mutex& functionQueueMutex = mainThreadFunctionQueueMutex();
    208     MutexLocker locker(functionQueueMutex);
    209     functionQueue().append(FunctionWithContext(function, context, &syncFlag));
    210     if (functionQueue().size() == 1)
    211         scheduleDispatchFunctionsOnMainThread();
    212     syncFlag.wait(functionQueueMutex);
    213 }
    214 
    215197void cancelCallOnMainThread(MainThreadFunction* function, void* context)
    216198{
  • trunk/Source/WTF/wtf/MainThread.h

    r161886 r162235  
    4343
    4444WTF_EXPORT_PRIVATE void callOnMainThread(MainThreadFunction*, void* context);
    45 WTF_EXPORT_PRIVATE void callOnMainThreadAndWait(MainThreadFunction*, void* context);
    4645WTF_EXPORT_PRIVATE void cancelCallOnMainThread(MainThreadFunction*, void* context);
    4746
     
    9594
    9695using WTF::callOnMainThread;
    97 using WTF::callOnMainThreadAndWait;
    9896using WTF::cancelCallOnMainThread;
    9997using WTF::setMainThreadCallbacksPaused;
  • trunk/Source/WebCore/ChangeLog

    r162234 r162235  
     12014-01-17  Anders Carlsson  <andersca@apple.com>
     2
     3        Add a callOnMainThreadAndWait variant in SocketStreamHandle
     4        https://bugs.webkit.org/show_bug.cgi?id=127180
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        WTF::callOnMainThreadAndWait was only used inside SocketStreamHandleCFNet.cpp,
     9        so add an improved version there which is implemented in terms of callOnMainThread and
     10        with the bonus of handling spurious wake-ups correctly (the old version didn't).
     11
     12        * platform/network/cf/SocketStreamHandle.h:
     13        * platform/network/cf/SocketStreamHandleCFNet.cpp:
     14        (WebCore::callOnMainThreadAndWait):
     15        (WebCore::SocketStreamHandle::pacExecutionCallback):
     16        (WebCore::SocketStreamHandle::readStreamCallback):
     17        (WebCore::SocketStreamHandle::writeStreamCallback):
     18
    1192014-01-17  Anders Carlsson  <andersca@apple.com>
    220
  • trunk/Source/WebCore/platform/network/cf/SocketStreamHandle.h

    r156550 r162235  
    6767    RetainPtr<CFRunLoopSourceRef> m_pacRunLoopSource;
    6868    static void pacExecutionCallback(void* client, CFArrayRef proxyList, CFErrorRef error);
    69     static void pacExecutionCallbackMainThread(void*);
    7069    static CFStringRef copyPACExecutionDescription(void*);
    7170
     
    8079    static void readStreamCallback(CFReadStreamRef, CFStreamEventType, void*);
    8180    static void writeStreamCallback(CFWriteStreamRef, CFStreamEventType, void*);
    82 #if PLATFORM(WIN)
    83     static void readStreamCallbackMainThread(void*);
    84     static void writeStreamCallbackMainThread(void*);
    85 #endif
    8681    void readStreamCallback(CFStreamEventType);
    8782    void writeStreamCallback(CFStreamEventType);
  • trunk/Source/WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp

    r161589 r162235  
    3939#include "SocketStreamError.h"
    4040#include "SocketStreamHandleClient.h"
     41#include <condition_variable>
     42#include <mutex>
    4143#include <wtf/MainThread.h>
    4244#include <wtf/text/WTFString.h>
     
    126128}
    127129
     130static void callOnMainThreadAndWait(std::function<void ()> function)
     131{
     132    if (isMainThread()) {
     133        function();
     134        return;
     135    }
     136
     137    std::mutex mutex;
     138    std::condition_variable conditionVariable;
     139
     140    bool isFinished = false;
     141
     142    callOnMainThread([&] {
     143        function();
     144
     145        std::lock_guard<std::mutex> lock(mutex);
     146        isFinished = true;
     147        conditionVariable.notify_one();
     148    });
     149
     150    std::unique_lock<std::mutex> lock(mutex);
     151    conditionVariable.wait(lock, [&] { return isFinished; });
     152}
     153
    128154struct MainThreadPACCallbackInfo {
    129155    MainThreadPACCallbackInfo(SocketStreamHandle* handle, CFArrayRef proxyList) : handle(handle), proxyList(proxyList) { }
     
    135161{
    136162    SocketStreamHandle* handle = static_cast<SocketStreamHandle*>(client);
    137     MainThreadPACCallbackInfo info(handle, proxyList);
    138     // If we're already on main thread (e.g. on Mac), callOnMainThreadAndWait() will be just a function call.
    139     callOnMainThreadAndWait(pacExecutionCallbackMainThread, &info);
    140 }
    141 
    142 void SocketStreamHandle::pacExecutionCallbackMainThread(void* invocation)
    143 {
    144     MainThreadPACCallbackInfo* info = static_cast<MainThreadPACCallbackInfo*>(invocation);
    145     ASSERT(info->handle->m_connectingSubstate == ExecutingPACFile);
    146     // This time, the array won't have PAC as a first entry.
    147     if (info->handle->m_state != Connecting)
    148         return;
    149     info->handle->chooseProxyFromArray(info->proxyList);
    150     info->handle->createStreams();
    151     info->handle->scheduleStreams();
     163
     164    callOnMainThreadAndWait([&] {
     165        ASSERT(handle->m_connectingSubstate == ExecutingPACFile);
     166        // This time, the array won't have PAC as a first entry.
     167        if (handle->m_state != Connecting)
     168            return;
     169        handle->chooseProxyFromArray(proxyList);
     170        handle->createStreams();
     171        handle->scheduleStreams();
     172    });
    152173}
    153174
     
    400421}
    401422
    402 struct MainThreadEventCallbackInfo {
    403     MainThreadEventCallbackInfo(CFStreamEventType type, SocketStreamHandle* handle) : type(type), handle(handle) { }
    404     CFStreamEventType type;
    405     RefPtr<SocketStreamHandle> handle;
    406 };
    407 
    408423void SocketStreamHandle::readStreamCallback(CFReadStreamRef stream, CFStreamEventType type, void* clientCallBackInfo)
    409424{
     
    411426    ASSERT_UNUSED(stream, stream == handle->m_readStream.get());
    412427#if PLATFORM(WIN)
    413     MainThreadEventCallbackInfo info(type, handle);
    414     callOnMainThreadAndWait(readStreamCallbackMainThread, &info);
     428    callOnMainThreadAndWait([&] {
     429        handle->readStreamCallback(type);
     430    });
    415431#else
    416432    ASSERT(isMainThread());
     
    424440    ASSERT_UNUSED(stream, stream == handle->m_writeStream.get());
    425441#if PLATFORM(WIN)
    426     MainThreadEventCallbackInfo info(type, handle);
    427     callOnMainThreadAndWait(writeStreamCallbackMainThread, &info);
     442    callOnMainThreadAndWait([&] {
     443        handle->writeStreamCallback(type);
     444    });
    428445#else
    429446    ASSERT(isMainThread());
     
    431448#endif
    432449}
    433 
    434 #if PLATFORM(WIN)
    435 void SocketStreamHandle::readStreamCallbackMainThread(void* invocation)
    436 {
    437     MainThreadEventCallbackInfo* info = static_cast<MainThreadEventCallbackInfo*>(invocation);
    438     info->handle->readStreamCallback(info->type);
    439 }
    440 
    441 void SocketStreamHandle::writeStreamCallbackMainThread(void* invocation)
    442 {
    443     MainThreadEventCallbackInfo* info = static_cast<MainThreadEventCallbackInfo*>(invocation);
    444     info->handle->writeStreamCallback(info->type);
    445 }
    446 #endif // PLATFORM(WIN)
    447450
    448451void SocketStreamHandle::readStreamCallback(CFStreamEventType type)
Note: See TracChangeset for help on using the changeset viewer.