1/*
2 * Copyright (C) 2012 ProFUSION embedded systems. All rights reserved.
3 * Copyright (C) 2012 Samsung Electronics
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28#include "RunLoop.h"
29
30#include <Ecore.h>
31#include <wtf/OwnPtr.h>
32#include <wtf/PassOwnPtr.h>
33
34static const int ecorePipeMessageSize = 1;
35static const char wakupEcorePipeMessage[] = "W";
36
37namespace WTF {
38
39RunLoop::RunLoop()
40    : m_wakeUpEventRequested(false)
41{
42    m_pipe = EflUniquePtr<Ecore_Pipe>(ecore_pipe_add(wakeUpEvent, this));
43}
44
45RunLoop::~RunLoop()
46{
47}
48
49void RunLoop::run()
50{
51    ecore_main_loop_begin();
52}
53
54void RunLoop::stop()
55{
56    ecore_main_loop_quit();
57}
58
59void RunLoop::wakeUpEvent(void* data, void*, unsigned)
60{
61    RunLoop* loop = static_cast<RunLoop*>(data);
62
63    {
64        MutexLocker locker(loop->m_wakeUpEventRequestedLock);
65        loop->m_wakeUpEventRequested = false;
66    }
67
68    loop->performWork();
69}
70
71void RunLoop::wakeUp()
72{
73    {
74        MutexLocker locker(m_wakeUpEventRequestedLock);
75        if (m_wakeUpEventRequested)
76            return;
77        m_wakeUpEventRequested = true;
78    }
79
80    {
81        MutexLocker locker(m_pipeLock);
82        ecore_pipe_write(m_pipe.get(), wakupEcorePipeMessage, ecorePipeMessageSize);
83    }
84}
85
86RunLoop::TimerBase::TimerBase(RunLoop& runLoop)
87    : m_runLoop(runLoop)
88    , m_timer(0)
89    , m_isRepeating(false)
90{
91}
92
93RunLoop::TimerBase::~TimerBase()
94{
95    stop();
96}
97
98bool RunLoop::TimerBase::timerFired(void* data)
99{
100    RunLoop::TimerBase* timer = static_cast<RunLoop::TimerBase*>(data);
101
102    if (!timer->m_isRepeating)
103        timer->m_timer = 0;
104
105    timer->fired();
106
107    return timer->m_isRepeating ? ECORE_CALLBACK_RENEW : ECORE_CALLBACK_CANCEL;
108}
109
110void RunLoop::TimerBase::start(double nextFireInterval, bool repeat)
111{
112    if (isActive())
113        stop();
114
115    m_isRepeating = repeat;
116    ASSERT(!m_timer);
117    m_timer = ecore_timer_add(nextFireInterval, reinterpret_cast<Ecore_Task_Cb>(timerFired), this);
118}
119
120void RunLoop::TimerBase::stop()
121{
122    if (m_timer) {
123        ecore_timer_del(m_timer);
124        m_timer = 0;
125    }
126}
127
128bool RunLoop::TimerBase::isActive() const
129{
130    return (m_timer) ? true : false;
131}
132
133} // namespace WTF
134