1e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent/*
2e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *
4e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  Use of this source code is governed by a BSD-style license
5e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  that can be found in the LICENSE file in the root of the source
6e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  tree. An additional intellectual property rights grant can be found
7e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  in the file PATENTS.  All contributing project authors may
8e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  be found in the AUTHORS file in the root of the source tree.
9e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent */
10e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
11c55a96383497a772a307b346368133960b02ad03Eric Laurent#include "event_posix.h"
12e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
13e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include <errno.h>
14e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include <pthread.h>
15e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include <signal.h>
16e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include <stdio.h>
17e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include <string.h>
18e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include <sys/time.h>
19e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include <unistd.h>
20e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
21e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentnamespace webrtc {
22e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentconst long int E6 = 1000000;
23e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentconst long int E9 = 1000 * E6;
24e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
25c55a96383497a772a307b346368133960b02ad03Eric LaurentEventWrapper* EventPosix::Create()
26e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
27c55a96383497a772a307b346368133960b02ad03Eric Laurent    EventPosix* ptr = new EventPosix;
28e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (!ptr)
29e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
30e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return NULL;
31e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
32e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
33e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    const int error = ptr->Construct();
34e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (error)
35e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
36e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        delete ptr;
37e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return NULL;
38e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
39e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    return ptr;
40e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
41e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
42e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
43c55a96383497a772a307b346368133960b02ad03Eric LaurentEventPosix::EventPosix()
44e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    : _timerThread(0),
45e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent      _timerEvent(0),
46e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent      _periodic(false),
47e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent      _time(0),
48e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent      _count(0),
49e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent      _state(kDown)
50e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
51e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
52e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
53c55a96383497a772a307b346368133960b02ad03Eric Laurentint EventPosix::Construct()
54e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
55e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    // Set start time to zero
56e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    memset(&_tCreate, 0, sizeof(_tCreate));
57e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
58e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    int result = pthread_mutex_init(&mutex, 0);
59e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (result != 0)
60e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
61e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return -1;
62e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
63e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#ifdef WEBRTC_CLOCK_TYPE_REALTIME
64e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    result = pthread_cond_init(&cond, 0);
65e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (result != 0)
66e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
67e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return -1;
68e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
69e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#else
70e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    pthread_condattr_t condAttr;
71e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    result = pthread_condattr_init(&condAttr);
72e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (result != 0)
73e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
74e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return -1;
75e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
76e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    result = pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC);
77e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (result != 0)
78e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
79e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return -1;
80e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
81e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    result = pthread_cond_init(&cond, &condAttr);
82e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (result != 0)
83e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
84e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return -1;
85e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
86e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    result = pthread_condattr_destroy(&condAttr);
87e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (result != 0)
88e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
89e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return -1;
90e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
91e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#endif
92e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    return 0;
93e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
94e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
95c55a96383497a772a307b346368133960b02ad03Eric LaurentEventPosix::~EventPosix()
96e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
97e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    StopTimer();
98e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    pthread_cond_destroy(&cond);
99e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    pthread_mutex_destroy(&mutex);
100e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
101e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
102c55a96383497a772a307b346368133960b02ad03Eric Laurentbool EventPosix::Reset()
103e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
104e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (0 != pthread_mutex_lock(&mutex))
105e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
106e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return false;
107e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
108e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _state = kDown;
109e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    pthread_mutex_unlock(&mutex);
110e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    return true;
111e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
112e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
113c55a96383497a772a307b346368133960b02ad03Eric Laurentbool EventPosix::Set()
114e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
115e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (0 != pthread_mutex_lock(&mutex))
116e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
117e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return false;
118e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
119e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _state = kUp;
120e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent     // Release all waiting threads
121e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    pthread_cond_broadcast(&cond);
122e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    pthread_mutex_unlock(&mutex);
123e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    return true;
124e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
125e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
126c55a96383497a772a307b346368133960b02ad03Eric LaurentEventTypeWrapper EventPosix::Wait(unsigned long timeout)
127e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
128e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    int retVal = 0;
129e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (0 != pthread_mutex_lock(&mutex))
130e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
131e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return kEventError;
132e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
133e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
134e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (kDown == _state)
135e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
136e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        if (WEBRTC_EVENT_INFINITE != timeout)
137e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        {
138e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            timespec tEnd;
139e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#ifndef WEBRTC_MAC
140e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#ifdef WEBRTC_CLOCK_TYPE_REALTIME
141e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            clock_gettime(CLOCK_REALTIME, &tEnd);
142e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#else
143e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            clock_gettime(CLOCK_MONOTONIC, &tEnd);
144e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#endif
145e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#else
146e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            timeval tVal;
147e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            struct timezone tZone;
148e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            tZone.tz_minuteswest = 0;
149e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            tZone.tz_dsttime = 0;
150e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            gettimeofday(&tVal,&tZone);
151e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            TIMEVAL_TO_TIMESPEC(&tVal,&tEnd);
152e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#endif
153e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            tEnd.tv_sec  += timeout / 1000;
154e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            tEnd.tv_nsec += (timeout - (timeout / 1000) * 1000) * E6;
155e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
156e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            if (tEnd.tv_nsec >= E9)
157e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            {
158e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent                tEnd.tv_sec++;
159e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent                tEnd.tv_nsec -= E9;
160e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            }
161e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            retVal = pthread_cond_timedwait(&cond, &mutex, &tEnd);
162e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        } else {
163e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            retVal = pthread_cond_wait(&cond, &mutex);
164e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        }
165e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
166e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
167e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _state = kDown;
168e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    pthread_mutex_unlock(&mutex);
169e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
170e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    switch(retVal)
171e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
172e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    case 0:
173e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return kEventSignaled;
174e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    case ETIMEDOUT:
175e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return kEventTimeout;
176e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    default:
177e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return kEventError;
178e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
179e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
180e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
181c55a96383497a772a307b346368133960b02ad03Eric LaurentEventTypeWrapper EventPosix::Wait(timespec& tPulse)
182e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
183e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    int retVal = 0;
184e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (0 != pthread_mutex_lock(&mutex))
185e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
186e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return kEventError;
187e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
188e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
189e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (kUp != _state)
190e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
191e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        retVal = pthread_cond_timedwait(&cond, &mutex, &tPulse);
192e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
193e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _state = kDown;
194e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
195e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    pthread_mutex_unlock(&mutex);
196e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
197e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    switch(retVal)
198e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
199e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    case 0:
200e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return kEventSignaled;
201e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    case ETIMEDOUT:
202e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return kEventTimeout;
203e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    default:
204e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return kEventError;
205e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
206e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
207e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
208c55a96383497a772a307b346368133960b02ad03Eric Laurentbool EventPosix::StartTimer(bool periodic, unsigned long time)
209e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
210e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (_timerThread)
211e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
212e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        if(_periodic)
213e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        {
214e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            // Timer already started.
215e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            return false;
216e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        } else  {
217e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            // New one shot timer
218e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            _time = time;
219e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            _tCreate.tv_sec = 0;
220e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            _timerEvent->Set();
221e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            return true;
222e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        }
223e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
224e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
225e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    // Start the timer thread
226c55a96383497a772a307b346368133960b02ad03Eric Laurent    _timerEvent = static_cast<EventPosix*>(EventWrapper::Create());
227e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    const char* threadName = "WebRtc_event_timer_thread";
228e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _timerThread = ThreadWrapper::CreateThread(Run, this, kRealtimePriority,
229e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent                                               threadName);
230e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _periodic = periodic;
231e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _time = time;
232e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    unsigned int id = 0;
233e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (_timerThread->Start(id))
234e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
235e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return true;
236e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
237e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    return false;
238e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
239e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
240c55a96383497a772a307b346368133960b02ad03Eric Laurentbool EventPosix::Run(ThreadObj obj)
241e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
242c55a96383497a772a307b346368133960b02ad03Eric Laurent    return static_cast<EventPosix*>(obj)->Process();
243e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
244e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
245c55a96383497a772a307b346368133960b02ad03Eric Laurentbool EventPosix::Process()
246e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
247e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (_tCreate.tv_sec == 0)
248e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
249e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#ifndef WEBRTC_MAC
250e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#ifdef WEBRTC_CLOCK_TYPE_REALTIME
251e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        clock_gettime(CLOCK_REALTIME, &_tCreate);
252e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#else
253e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        clock_gettime(CLOCK_MONOTONIC, &_tCreate);
254e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#endif
255e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#else
256e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        timeval tVal;
257e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        struct timezone tZone;
258e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        tZone.tz_minuteswest = 0;
259e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        tZone.tz_dsttime = 0;
260e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        gettimeofday(&tVal,&tZone);
261e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        TIMEVAL_TO_TIMESPEC(&tVal,&_tCreate);
262e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#endif
263e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        _count=0;
264e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
265e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
266e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    timespec tEnd;
267e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    unsigned long long time = _time * ++_count;
268e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    tEnd.tv_sec  = _tCreate.tv_sec + time/1000;
269e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    tEnd.tv_nsec = _tCreate.tv_nsec + (time - (time/1000)*1000)*E6;
270e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
271e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if ( tEnd.tv_nsec >= E9 )
272e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
273e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        tEnd.tv_sec++;
274e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        tEnd.tv_nsec -= E9;
275e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
276e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
277e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    switch(_timerEvent->Wait(tEnd))
278e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
279e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    case kEventSignaled:
280e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return true;
281e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    case kEventError:
282e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return false;
283e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    case kEventTimeout:
284e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        break;
285e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
286e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if(_periodic || _count==1)
287e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
288e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        Set();
289e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
290e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    return true;
291e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
292e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
293c55a96383497a772a307b346368133960b02ad03Eric Laurentbool EventPosix::StopTimer()
294e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
295e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if(_timerThread)
296e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
297e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        _timerThread->SetNotAlive();
298e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
299e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (_timerEvent)
300e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
301e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        _timerEvent->Set();
302e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
303e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (_timerThread)
304e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
305e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        if(!_timerThread->Stop())
306e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        {
307e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            return false;
308e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        }
309e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
310e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        delete _timerThread;
311e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        _timerThread = 0;
312e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
313e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (_timerEvent)
314e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
315e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        delete _timerEvent;
316e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        _timerEvent = 0;
317e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
318e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
319e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    // Set time to zero to force new reference time for the timer.
320e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    memset(&_tCreate, 0, sizeof(_tCreate));
321e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    _count=0;
322e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    return true;
323e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
324e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} // namespace webrtc
325