/*
 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
 * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
 * Copyright (C) 2016 Konstantin Tokavev <annulen@yandex.ru>
 * Copyright (C) 2016 Yusuke Suzuki <utatane.tea@gmail.com>
 * Copyright (C) 2019 Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include <pthread.h>
#if HAVE(PTHREAD_NP_H)
#include <pthread_np.h>
#endif

#include <wtf/RunLoop.h>
#include <wtf/NeverDestroyed.h>
#if USE(GLIB)
#include <wtf/glib/RunLoopSourcePriority.h>
#endif

namespace WTF {

#if !HAVE(PTHREAD_MAIN_NP)
static pthread_t mainThread;
#endif

class MainThreadDispatcher {
    WTF_MAKE_FAST_ALLOCATED;
public:
    MainThreadDispatcher()
        : m_timer(RunLoop::main(), this, &MainThreadDispatcher::fired)
    {
#if USE(GLIB)
        m_timer.setPriority(RunLoopSourcePriority::MainThreadDispatcherTimer);
#endif
    }

    void schedule()
    {
        m_timer.startOneShot(0_s);
    }

private:
    void fired()
    {
        dispatchFunctionsFromMainThread();
    }

    RunLoop::Timer<MainThreadDispatcher> m_timer;
};

void initializeMainThreadPlatform()
{
#if !HAVE(PTHREAD_MAIN_NP)
    mainThread = pthread_self();
#endif
}

bool isMainThread()
{
#if HAVE(PTHREAD_MAIN_NP)
    return pthread_main_np();
#else
    return pthread_equal(pthread_self(), mainThread);
#endif
}

void scheduleDispatchFunctionsOnMainThread()
{
    // Use a RunLoop::Timer instead of RunLoop::dispatch() to be able to use a different priority and
    // avoid the double queue because dispatchOnMainThread also queues the functions.
    static NeverDestroyed<MainThreadDispatcher> dispatcher;
    dispatcher.get().schedule();
}

} // namespace WTF
