Reformatted event* classes.
TEST=Ran trybots. Review URL: https://webrtc-codereview.appspot.com/972012 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3253 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
3bb42ef0d6
commit
5bbe069f28
@ -12,57 +12,55 @@
|
|||||||
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_EVENT_WRAPPER_H_
|
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_EVENT_WRAPPER_H_
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
enum EventTypeWrapper
|
enum EventTypeWrapper {
|
||||||
{
|
kEventSignaled = 1,
|
||||||
kEventSignaled = 1,
|
kEventError = 2,
|
||||||
kEventError = 2,
|
kEventTimeout = 3
|
||||||
kEventTimeout = 3
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define WEBRTC_EVENT_10_SEC 10000
|
#define WEBRTC_EVENT_10_SEC 10000
|
||||||
#define WEBRTC_EVENT_INFINITE 0xffffffff
|
#define WEBRTC_EVENT_INFINITE 0xffffffff
|
||||||
|
|
||||||
class EventWrapper
|
class EventWrapper {
|
||||||
{
|
public:
|
||||||
public:
|
// Factory method. Constructor disabled.
|
||||||
// Factory method. Constructor disabled.
|
static EventWrapper* Create();
|
||||||
static EventWrapper* Create();
|
virtual ~EventWrapper() {}
|
||||||
virtual ~EventWrapper() {}
|
|
||||||
|
|
||||||
// Releases threads who are calling Wait() and has started waiting. Please
|
// Releases threads who are calling Wait() and has started waiting. Please
|
||||||
// note that a thread calling Wait() will not start waiting immediately.
|
// note that a thread calling Wait() will not start waiting immediately.
|
||||||
// assumptions to the contrary is a very common source of issues in
|
// assumptions to the contrary is a very common source of issues in
|
||||||
// multithreaded programming.
|
// multithreaded programming.
|
||||||
// Set is sticky in the sense that it will release at least one thread
|
// Set is sticky in the sense that it will release at least one thread
|
||||||
// either immediately or some time in the future.
|
// either immediately or some time in the future.
|
||||||
virtual bool Set() = 0;
|
virtual bool Set() = 0;
|
||||||
|
|
||||||
// Prevents future Wait() calls from finishing without a new Set() call.
|
// Prevents future Wait() calls from finishing without a new Set() call.
|
||||||
virtual bool Reset() = 0;
|
virtual bool Reset() = 0;
|
||||||
|
|
||||||
// Puts the calling thread into a wait state. The thread may be released
|
// Puts the calling thread into a wait state. The thread may be released
|
||||||
// by a Set() call depending on if other threads are waiting and if so on
|
// by a Set() call depending on if other threads are waiting and if so on
|
||||||
// timing. The thread that was released will call Reset() before leaving
|
// timing. The thread that was released will call Reset() before leaving
|
||||||
// preventing more threads from being released. If multiple threads
|
// preventing more threads from being released. If multiple threads
|
||||||
// are waiting for the same Set(), only one (random) thread is guaranteed to
|
// are waiting for the same Set(), only one (random) thread is guaranteed to
|
||||||
// be released. It is possible that multiple (random) threads are released
|
// be released. It is possible that multiple (random) threads are released
|
||||||
// Depending on timing.
|
// Depending on timing.
|
||||||
virtual EventTypeWrapper Wait(unsigned long maxTime) = 0;
|
virtual EventTypeWrapper Wait(unsigned long max_time) = 0;
|
||||||
|
|
||||||
// Starts a timer that will call a non-sticky version of Set() either once
|
// Starts a timer that will call a non-sticky version of Set() either once
|
||||||
// or periodically. If the timer is periodic it ensures that there is no
|
// or periodically. If the timer is periodic it ensures that there is no
|
||||||
// drift over time relative to the system clock.
|
// drift over time relative to the system clock.
|
||||||
virtual bool StartTimer(bool periodic, unsigned long time) = 0;
|
virtual bool StartTimer(bool periodic, unsigned long time) = 0;
|
||||||
|
|
||||||
virtual bool StopTimer() = 0;
|
virtual bool StopTimer() = 0;
|
||||||
|
|
||||||
// Only implemented on Windows
|
// Only implemented on Windows
|
||||||
// Returns 1 if a key has been pressed since last call to this function.
|
// Returns 1 if a key has been pressed since last call to this function.
|
||||||
// -1 indicates failure
|
// -1 indicates failure
|
||||||
// 0 indicates no key has been pressed since last call
|
// 0 indicates no key has been pressed since last call
|
||||||
// TODO(hellner) this function does not seem to belong here
|
// TODO(hellner) this function does not seem to belong here
|
||||||
static int KeyPressed();
|
static int KeyPressed();
|
||||||
};
|
};
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_EVENT_WRAPPER_H_
|
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_EVENT_WRAPPER_H_
|
||||||
|
@ -8,64 +8,55 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "event_wrapper.h"
|
#include "webrtc/system_wrappers/interface/event_wrapper.h"
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "event_win.h"
|
#include "webrtc/system_wrappers/source/event_win.h"
|
||||||
#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
|
#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
|
||||||
#include <ApplicationServices/ApplicationServices.h>
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "event_posix.h"
|
#include "webrtc/system_wrappers/source/event_posix.h"
|
||||||
#else
|
#else
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "event_posix.h"
|
#include "webrtc/system_wrappers/source/event_posix.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
EventWrapper* EventWrapper::Create()
|
EventWrapper* EventWrapper::Create() {
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
return new EventWindows();
|
return new EventWindows();
|
||||||
#else
|
#else
|
||||||
return EventPosix::Create();
|
return EventPosix::Create();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int EventWrapper::KeyPressed()
|
int EventWrapper::KeyPressed() {
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
int keyDown = 0;
|
int key_down = 0;
|
||||||
for(int key = 0x20; key < 0x90; key++)
|
for (int key = 0x20; key < 0x90; key++) {
|
||||||
{
|
short res = GetAsyncKeyState(key);
|
||||||
short res = GetAsyncKeyState(key);
|
key_down |= res % 2; // Get the LSB
|
||||||
keyDown |= res%2; // Get the LSB
|
}
|
||||||
}
|
if (key_down) {
|
||||||
if(keyDown)
|
return 1;
|
||||||
{
|
} else {
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
|
#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
|
||||||
bool keyDown = false;
|
bool key_down = false;
|
||||||
// loop through all Mac virtual key constant values
|
// loop through all Mac virtual key constant values
|
||||||
for(int keyIndex = 0; keyIndex <= 0x5C; keyIndex++)
|
for (int key_index = 0; key_index <= 0x5C; key_index++) {
|
||||||
{
|
key_down |= CGEventSourceKeyState(kCGEventSourceStateHIDSystemState,
|
||||||
keyDown |= CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, keyIndex);
|
key_index);
|
||||||
}
|
}
|
||||||
if(keyDown)
|
if (key_down) {
|
||||||
{
|
return 1;
|
||||||
return 1;
|
} else {
|
||||||
}
|
return 0;
|
||||||
else
|
}
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "event_posix.h"
|
#include "webrtc/system_wrappers/source/event_posix.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
@ -19,306 +19,265 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
const long int E6 = 1000000;
|
const long int E6 = 1000000;
|
||||||
const long int E9 = 1000 * E6;
|
const long int E9 = 1000 * E6;
|
||||||
|
|
||||||
EventWrapper* EventPosix::Create()
|
EventWrapper* EventPosix::Create() {
|
||||||
{
|
EventPosix* ptr = new EventPosix;
|
||||||
EventPosix* ptr = new EventPosix;
|
if (!ptr) {
|
||||||
if (!ptr)
|
return NULL;
|
||||||
{
|
}
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int error = ptr->Construct();
|
const int error = ptr->Construct();
|
||||||
if (error)
|
if (error) {
|
||||||
{
|
delete ptr;
|
||||||
delete ptr;
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
return ptr;
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EventPosix::EventPosix()
|
EventPosix::EventPosix()
|
||||||
: _timerThread(0),
|
: timer_thread_(0),
|
||||||
_timerEvent(0),
|
timer_event_(0),
|
||||||
_periodic(false),
|
periodic_(false),
|
||||||
_time(0),
|
time_(0),
|
||||||
_count(0),
|
count_(0),
|
||||||
_state(kDown)
|
state_(kDown) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int EventPosix::Construct()
|
int EventPosix::Construct() {
|
||||||
{
|
// Set start time to zero
|
||||||
// Set start time to zero
|
memset(&created_at_, 0, sizeof(created_at_));
|
||||||
memset(&_tCreate, 0, sizeof(_tCreate));
|
|
||||||
|
|
||||||
int result = pthread_mutex_init(&mutex, 0);
|
int result = pthread_mutex_init(&mutex_, 0);
|
||||||
if (result != 0)
|
if (result != 0) {
|
||||||
{
|
return -1;
|
||||||
return -1;
|
}
|
||||||
}
|
|
||||||
#ifdef WEBRTC_CLOCK_TYPE_REALTIME
|
#ifdef WEBRTC_CLOCK_TYPE_REALTIME
|
||||||
result = pthread_cond_init(&cond, 0);
|
result = pthread_cond_init(&cond_, 0);
|
||||||
if (result != 0)
|
if (result != 0) {
|
||||||
{
|
return -1;
|
||||||
return -1;
|
}
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
pthread_condattr_t condAttr;
|
pthread_condattr_t cond_attr;
|
||||||
result = pthread_condattr_init(&condAttr);
|
result = pthread_condattr_init(&cond_attr);
|
||||||
if (result != 0)
|
if (result != 0) {
|
||||||
{
|
return -1;
|
||||||
return -1;
|
}
|
||||||
}
|
result = pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
|
||||||
result = pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC);
|
if (result != 0) {
|
||||||
if (result != 0)
|
return -1;
|
||||||
{
|
}
|
||||||
return -1;
|
result = pthread_cond_init(&cond_, &cond_attr);
|
||||||
}
|
if (result != 0) {
|
||||||
result = pthread_cond_init(&cond, &condAttr);
|
return -1;
|
||||||
if (result != 0)
|
}
|
||||||
{
|
result = pthread_condattr_destroy(&cond_attr);
|
||||||
return -1;
|
if (result != 0) {
|
||||||
}
|
return -1;
|
||||||
result = pthread_condattr_destroy(&condAttr);
|
}
|
||||||
if (result != 0)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EventPosix::~EventPosix()
|
EventPosix::~EventPosix() {
|
||||||
{
|
StopTimer();
|
||||||
StopTimer();
|
pthread_cond_destroy(&cond_);
|
||||||
pthread_cond_destroy(&cond);
|
pthread_mutex_destroy(&mutex_);
|
||||||
pthread_mutex_destroy(&mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventPosix::Reset()
|
bool EventPosix::Reset() {
|
||||||
{
|
if (0 != pthread_mutex_lock(&mutex_)) {
|
||||||
if (0 != pthread_mutex_lock(&mutex))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
_state = kDown;
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EventPosix::Set()
|
|
||||||
{
|
|
||||||
if (0 != pthread_mutex_lock(&mutex))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
_state = kUp;
|
|
||||||
// Release all waiting threads
|
|
||||||
pthread_cond_broadcast(&cond);
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
EventTypeWrapper EventPosix::Wait(unsigned long timeout)
|
|
||||||
{
|
|
||||||
int retVal = 0;
|
|
||||||
if (0 != pthread_mutex_lock(&mutex))
|
|
||||||
{
|
|
||||||
return kEventError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kDown == _state)
|
|
||||||
{
|
|
||||||
if (WEBRTC_EVENT_INFINITE != timeout)
|
|
||||||
{
|
|
||||||
timespec tEnd;
|
|
||||||
#ifndef WEBRTC_MAC
|
|
||||||
#ifdef WEBRTC_CLOCK_TYPE_REALTIME
|
|
||||||
clock_gettime(CLOCK_REALTIME, &tEnd);
|
|
||||||
#else
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &tEnd);
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
timeval tVal;
|
|
||||||
struct timezone tZone;
|
|
||||||
tZone.tz_minuteswest = 0;
|
|
||||||
tZone.tz_dsttime = 0;
|
|
||||||
gettimeofday(&tVal,&tZone);
|
|
||||||
TIMEVAL_TO_TIMESPEC(&tVal,&tEnd);
|
|
||||||
#endif
|
|
||||||
tEnd.tv_sec += timeout / 1000;
|
|
||||||
tEnd.tv_nsec += (timeout - (timeout / 1000) * 1000) * E6;
|
|
||||||
|
|
||||||
if (tEnd.tv_nsec >= E9)
|
|
||||||
{
|
|
||||||
tEnd.tv_sec++;
|
|
||||||
tEnd.tv_nsec -= E9;
|
|
||||||
}
|
|
||||||
retVal = pthread_cond_timedwait(&cond, &mutex, &tEnd);
|
|
||||||
} else {
|
|
||||||
retVal = pthread_cond_wait(&cond, &mutex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_state = kDown;
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
|
|
||||||
switch(retVal)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
return kEventSignaled;
|
|
||||||
case ETIMEDOUT:
|
|
||||||
return kEventTimeout;
|
|
||||||
default:
|
|
||||||
return kEventError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EventTypeWrapper EventPosix::Wait(timespec& tPulse)
|
|
||||||
{
|
|
||||||
int retVal = 0;
|
|
||||||
if (0 != pthread_mutex_lock(&mutex))
|
|
||||||
{
|
|
||||||
return kEventError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kUp != _state)
|
|
||||||
{
|
|
||||||
retVal = pthread_cond_timedwait(&cond, &mutex, &tPulse);
|
|
||||||
}
|
|
||||||
_state = kDown;
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
|
|
||||||
switch(retVal)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
return kEventSignaled;
|
|
||||||
case ETIMEDOUT:
|
|
||||||
return kEventTimeout;
|
|
||||||
default:
|
|
||||||
return kEventError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EventPosix::StartTimer(bool periodic, unsigned long time)
|
|
||||||
{
|
|
||||||
if (_timerThread)
|
|
||||||
{
|
|
||||||
if(_periodic)
|
|
||||||
{
|
|
||||||
// Timer already started.
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
// New one shot timer
|
|
||||||
_time = time;
|
|
||||||
_tCreate.tv_sec = 0;
|
|
||||||
_timerEvent->Set();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the timer thread
|
|
||||||
_timerEvent = static_cast<EventPosix*>(EventWrapper::Create());
|
|
||||||
const char* threadName = "WebRtc_event_timer_thread";
|
|
||||||
_timerThread = ThreadWrapper::CreateThread(Run, this, kRealtimePriority,
|
|
||||||
threadName);
|
|
||||||
_periodic = periodic;
|
|
||||||
_time = time;
|
|
||||||
unsigned int id = 0;
|
|
||||||
if (_timerThread->Start(id))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
state_ = kDown;
|
||||||
|
pthread_mutex_unlock(&mutex_);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventPosix::Run(ThreadObj obj)
|
bool EventPosix::Set() {
|
||||||
{
|
if (0 != pthread_mutex_lock(&mutex_)) {
|
||||||
return static_cast<EventPosix*>(obj)->Process();
|
return false;
|
||||||
|
}
|
||||||
|
state_ = kUp;
|
||||||
|
// Release all waiting threads
|
||||||
|
pthread_cond_broadcast(&cond_);
|
||||||
|
pthread_mutex_unlock(&mutex_);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventPosix::Process()
|
EventTypeWrapper EventPosix::Wait(unsigned long timeout) {
|
||||||
{
|
int ret_val = 0;
|
||||||
if (_tCreate.tv_sec == 0)
|
if (0 != pthread_mutex_lock(&mutex_)) {
|
||||||
{
|
return kEventError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kDown == state_) {
|
||||||
|
if (WEBRTC_EVENT_INFINITE != timeout) {
|
||||||
|
timespec end_at;
|
||||||
#ifndef WEBRTC_MAC
|
#ifndef WEBRTC_MAC
|
||||||
#ifdef WEBRTC_CLOCK_TYPE_REALTIME
|
#ifdef WEBRTC_CLOCK_TYPE_REALTIME
|
||||||
clock_gettime(CLOCK_REALTIME, &_tCreate);
|
clock_gettime(CLOCK_REALTIME, &end_at);
|
||||||
#else
|
#else
|
||||||
clock_gettime(CLOCK_MONOTONIC, &_tCreate);
|
clock_gettime(CLOCK_MONOTONIC, &end_at);
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
timeval tVal;
|
timeval value;
|
||||||
struct timezone tZone;
|
struct timezone time_zone;
|
||||||
tZone.tz_minuteswest = 0;
|
time_zone.tz_minuteswest = 0;
|
||||||
tZone.tz_dsttime = 0;
|
time_zone.tz_dsttime = 0;
|
||||||
gettimeofday(&tVal,&tZone);
|
gettimeofday(&value, &time_zone);
|
||||||
TIMEVAL_TO_TIMESPEC(&tVal,&_tCreate);
|
TIMEVAL_TO_TIMESPEC(&value, &end_at);
|
||||||
#endif
|
#endif
|
||||||
_count=0;
|
end_at.tv_sec += timeout / 1000;
|
||||||
|
end_at.tv_nsec += (timeout - (timeout / 1000) * 1000) * E6;
|
||||||
|
|
||||||
|
if (end_at.tv_nsec >= E9) {
|
||||||
|
end_at.tv_sec++;
|
||||||
|
end_at.tv_nsec -= E9;
|
||||||
|
}
|
||||||
|
ret_val = pthread_cond_timedwait(&cond_, &mutex_, &end_at);
|
||||||
|
} else {
|
||||||
|
ret_val = pthread_cond_wait(&cond_, &mutex_);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
timespec tEnd;
|
state_ = kDown;
|
||||||
unsigned long long time = _time * ++_count;
|
pthread_mutex_unlock(&mutex_);
|
||||||
tEnd.tv_sec = _tCreate.tv_sec + time/1000;
|
|
||||||
tEnd.tv_nsec = _tCreate.tv_nsec + (time - (time/1000)*1000)*E6;
|
|
||||||
|
|
||||||
if ( tEnd.tv_nsec >= E9 )
|
switch (ret_val) {
|
||||||
{
|
case 0:
|
||||||
tEnd.tv_sec++;
|
return kEventSignaled;
|
||||||
tEnd.tv_nsec -= E9;
|
case ETIMEDOUT:
|
||||||
|
return kEventTimeout;
|
||||||
|
default:
|
||||||
|
return kEventError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EventTypeWrapper EventPosix::Wait(timespec& wake_at) {
|
||||||
|
int ret_val = 0;
|
||||||
|
if (0 != pthread_mutex_lock(&mutex_)) {
|
||||||
|
return kEventError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kUp != state_) {
|
||||||
|
ret_val = pthread_cond_timedwait(&cond_, &mutex_, &wake_at);
|
||||||
|
}
|
||||||
|
state_ = kDown;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&mutex_);
|
||||||
|
|
||||||
|
switch (ret_val) {
|
||||||
|
case 0:
|
||||||
|
return kEventSignaled;
|
||||||
|
case ETIMEDOUT:
|
||||||
|
return kEventTimeout;
|
||||||
|
default:
|
||||||
|
return kEventError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EventPosix::StartTimer(bool periodic, unsigned long time) {
|
||||||
|
if (timer_thread_) {
|
||||||
|
if (periodic_) {
|
||||||
|
// Timer already started.
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// New one shot timer
|
||||||
|
time_ = time;
|
||||||
|
created_at_.tv_sec = 0;
|
||||||
|
timer_event_->Set();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch(_timerEvent->Wait(tEnd))
|
// Start the timer thread
|
||||||
{
|
timer_event_ = static_cast<EventPosix*>(EventWrapper::Create());
|
||||||
|
const char* thread_name = "WebRtc_event_timer_thread";
|
||||||
|
timer_thread_ = ThreadWrapper::CreateThread(Run, this, kRealtimePriority,
|
||||||
|
thread_name);
|
||||||
|
periodic_ = periodic;
|
||||||
|
time_ = time;
|
||||||
|
unsigned int id = 0;
|
||||||
|
if (timer_thread_->Start(id)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EventPosix::Run(ThreadObj obj) {
|
||||||
|
return static_cast<EventPosix*>(obj)->Process();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EventPosix::Process() {
|
||||||
|
if (created_at_.tv_sec == 0) {
|
||||||
|
#ifndef WEBRTC_MAC
|
||||||
|
#ifdef WEBRTC_CLOCK_TYPE_REALTIME
|
||||||
|
clock_gettime(CLOCK_REALTIME, &created_at_);
|
||||||
|
#else
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &created_at_);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
timeval value;
|
||||||
|
struct timezone time_zone;
|
||||||
|
time_zone.tz_minuteswest = 0;
|
||||||
|
time_zone.tz_dsttime = 0;
|
||||||
|
gettimeofday(&value, &time_zone);
|
||||||
|
TIMEVAL_TO_TIMESPEC(&value, &created_at_);
|
||||||
|
#endif
|
||||||
|
count_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
timespec end_at;
|
||||||
|
unsigned long long time = time_ * ++count_;
|
||||||
|
end_at.tv_sec = created_at_.tv_sec + time / 1000;
|
||||||
|
end_at.tv_nsec = created_at_.tv_nsec + (time - (time / 1000) * 1000) * E6;
|
||||||
|
|
||||||
|
if (end_at.tv_nsec >= E9) {
|
||||||
|
end_at.tv_sec++;
|
||||||
|
end_at.tv_nsec -= E9;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (timer_event_->Wait(end_at)) {
|
||||||
case kEventSignaled:
|
case kEventSignaled:
|
||||||
return true;
|
return true;
|
||||||
case kEventError:
|
case kEventError:
|
||||||
return false;
|
return false;
|
||||||
case kEventTimeout:
|
case kEventTimeout:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(_periodic || _count==1)
|
if (periodic_ || count_ == 1) {
|
||||||
{
|
Set();
|
||||||
Set();
|
}
|
||||||
}
|
return true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventPosix::StopTimer()
|
bool EventPosix::StopTimer() {
|
||||||
{
|
if (timer_thread_) {
|
||||||
if(_timerThread)
|
timer_thread_->SetNotAlive();
|
||||||
{
|
}
|
||||||
_timerThread->SetNotAlive();
|
if (timer_event_) {
|
||||||
}
|
timer_event_->Set();
|
||||||
if (_timerEvent)
|
}
|
||||||
{
|
if (timer_thread_) {
|
||||||
_timerEvent->Set();
|
if (!timer_thread_->Stop()) {
|
||||||
}
|
return false;
|
||||||
if (_timerThread)
|
|
||||||
{
|
|
||||||
if(!_timerThread->Stop())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete _timerThread;
|
|
||||||
_timerThread = 0;
|
|
||||||
}
|
|
||||||
if (_timerEvent)
|
|
||||||
{
|
|
||||||
delete _timerEvent;
|
|
||||||
_timerEvent = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set time to zero to force new reference time for the timer.
|
delete timer_thread_;
|
||||||
memset(&_tCreate, 0, sizeof(_tCreate));
|
timer_thread_ = 0;
|
||||||
_count=0;
|
}
|
||||||
return true;
|
if (timer_event_) {
|
||||||
|
delete timer_event_;
|
||||||
|
timer_event_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set time to zero to force new reference time for the timer.
|
||||||
|
memset(&created_at_, 0, sizeof(created_at_));
|
||||||
|
count_ = 0;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -11,56 +11,55 @@
|
|||||||
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_POSIX_H_
|
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_POSIX_H_
|
||||||
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_POSIX_H_
|
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_POSIX_H_
|
||||||
|
|
||||||
#include "event_wrapper.h"
|
#include "webrtc/system_wrappers/interface/event_wrapper.h"
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "thread_wrapper.h"
|
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
enum State
|
|
||||||
{
|
enum State {
|
||||||
kUp = 1,
|
kUp = 1,
|
||||||
kDown = 2
|
kDown = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
class EventPosix : public EventWrapper
|
class EventPosix : public EventWrapper {
|
||||||
{
|
public:
|
||||||
public:
|
static EventWrapper* Create();
|
||||||
static EventWrapper* Create();
|
|
||||||
|
|
||||||
virtual ~EventPosix();
|
virtual ~EventPosix();
|
||||||
|
|
||||||
virtual EventTypeWrapper Wait(unsigned long maxTime);
|
virtual EventTypeWrapper Wait(unsigned long max_time);
|
||||||
virtual bool Set();
|
virtual bool Set();
|
||||||
virtual bool Reset();
|
virtual bool Reset();
|
||||||
|
|
||||||
virtual bool StartTimer(bool periodic, unsigned long time);
|
virtual bool StartTimer(bool periodic, unsigned long time);
|
||||||
virtual bool StopTimer();
|
virtual bool StopTimer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EventPosix();
|
EventPosix();
|
||||||
int Construct();
|
int Construct();
|
||||||
|
|
||||||
static bool Run(ThreadObj obj);
|
static bool Run(ThreadObj obj);
|
||||||
bool Process();
|
bool Process();
|
||||||
EventTypeWrapper Wait(timespec& tPulse);
|
EventTypeWrapper Wait(timespec& wake_at);
|
||||||
|
|
||||||
|
private:
|
||||||
|
pthread_cond_t cond_;
|
||||||
|
pthread_mutex_t mutex_;
|
||||||
|
|
||||||
private:
|
ThreadWrapper* timer_thread_;
|
||||||
pthread_cond_t cond;
|
EventPosix* timer_event_;
|
||||||
pthread_mutex_t mutex;
|
timespec created_at_;
|
||||||
|
|
||||||
ThreadWrapper* _timerThread;
|
bool periodic_;
|
||||||
EventPosix* _timerEvent;
|
unsigned long time_; // In ms
|
||||||
timespec _tCreate;
|
unsigned long count_;
|
||||||
|
State state_;
|
||||||
bool _periodic;
|
|
||||||
unsigned long _time; // In ms
|
|
||||||
unsigned long _count;
|
|
||||||
State _state;
|
|
||||||
};
|
};
|
||||||
} // namespace webrtc
|
|
||||||
|
|
||||||
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_POSIX_H_
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_POSIX_H_
|
||||||
|
@ -8,77 +8,68 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "event_win.h"
|
#include "webrtc/system_wrappers/source/event_win.h"
|
||||||
|
|
||||||
#include "Mmsystem.h"
|
#include "Mmsystem.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
EventWindows::EventWindows()
|
EventWindows::EventWindows()
|
||||||
: _event(::CreateEvent(NULL /* security attributes */,
|
: event_(::CreateEvent(NULL, // security attributes
|
||||||
FALSE /* manual reset */,
|
FALSE, // manual reset
|
||||||
FALSE /* initial state */,
|
FALSE, // initial state
|
||||||
NULL /* name of event */)),
|
NULL)), // name of event
|
||||||
_timerID(NULL)
|
timerID_(NULL) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EventWindows::~EventWindows()
|
EventWindows::~EventWindows() {
|
||||||
{
|
CloseHandle(event_);
|
||||||
CloseHandle(_event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventWindows::Set()
|
bool EventWindows::Set() {
|
||||||
{
|
// Note: setting an event that is already set has no effect.
|
||||||
// Note: setting an event that is already set has no effect.
|
return SetEvent(event_) == 1 ? true : false;
|
||||||
return SetEvent(_event) == 1 ? true : false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventWindows::Reset()
|
bool EventWindows::Reset() {
|
||||||
{
|
return ResetEvent(event_) == 1 ? true : false;
|
||||||
return ResetEvent(_event) == 1 ? true : false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EventTypeWrapper EventWindows::Wait(unsigned long maxTime)
|
EventTypeWrapper EventWindows::Wait(unsigned long max_time) {
|
||||||
{
|
unsigned long res = WaitForSingleObject(event_, max_time);
|
||||||
unsigned long res = WaitForSingleObject(_event, maxTime);
|
switch (res) {
|
||||||
switch(res)
|
|
||||||
{
|
|
||||||
case WAIT_OBJECT_0:
|
case WAIT_OBJECT_0:
|
||||||
return kEventSignaled;
|
return kEventSignaled;
|
||||||
case WAIT_TIMEOUT:
|
case WAIT_TIMEOUT:
|
||||||
return kEventTimeout;
|
return kEventTimeout;
|
||||||
default:
|
default:
|
||||||
return kEventError;
|
return kEventError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventWindows::StartTimer(bool periodic, unsigned long time)
|
bool EventWindows::StartTimer(bool periodic, unsigned long time) {
|
||||||
{
|
if (timerID_ != NULL) {
|
||||||
if (_timerID != NULL)
|
timeKillEvent(timerID_);
|
||||||
{
|
timerID_ = NULL;
|
||||||
timeKillEvent(_timerID);
|
}
|
||||||
_timerID=NULL;
|
if (periodic) {
|
||||||
}
|
timerID_ = timeSetEvent(time, 0, (LPTIMECALLBACK)HANDLE(event_), 0,
|
||||||
if (periodic)
|
TIME_PERIODIC | TIME_CALLBACK_EVENT_PULSE);
|
||||||
{
|
} else {
|
||||||
_timerID=timeSetEvent(time, 0,(LPTIMECALLBACK)HANDLE(_event),0,
|
timerID_ = timeSetEvent(time, 0, (LPTIMECALLBACK)HANDLE(event_), 0,
|
||||||
TIME_PERIODIC|TIME_CALLBACK_EVENT_PULSE);
|
TIME_ONESHOT | TIME_CALLBACK_EVENT_SET);
|
||||||
} else {
|
}
|
||||||
_timerID=timeSetEvent(time, 0,(LPTIMECALLBACK)HANDLE(_event),0,
|
|
||||||
TIME_ONESHOT|TIME_CALLBACK_EVENT_SET);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_timerID == NULL)
|
if (timerID_ == NULL) {
|
||||||
{
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
return true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventWindows::StopTimer()
|
bool EventWindows::StopTimer() {
|
||||||
{
|
timeKillEvent(timerID_);
|
||||||
timeKillEvent(_timerID);
|
timerID_ = NULL;
|
||||||
_timerID = NULL;
|
return true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
} // namespace webrtc
|
|
||||||
|
} // namespace webrtc
|
||||||
|
@ -8,33 +8,34 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_WINDOWS_H_
|
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_WIN_H_
|
||||||
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_WINDOWS_H_
|
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_WIN_H_
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include "event_wrapper.h"
|
#include "webrtc/system_wrappers/interface/event_wrapper.h"
|
||||||
|
|
||||||
#include "typedefs.h"
|
#include "webrtc/typedefs.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
class EventWindows : public EventWrapper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EventWindows();
|
|
||||||
virtual ~EventWindows();
|
|
||||||
|
|
||||||
virtual EventTypeWrapper Wait(unsigned long maxTime);
|
class EventWindows : public EventWrapper {
|
||||||
virtual bool Set();
|
public:
|
||||||
virtual bool Reset();
|
EventWindows();
|
||||||
|
virtual ~EventWindows();
|
||||||
|
|
||||||
virtual bool StartTimer(bool periodic, unsigned long time);
|
virtual EventTypeWrapper Wait(unsigned long max_time);
|
||||||
virtual bool StopTimer();
|
virtual bool Set();
|
||||||
|
virtual bool Reset();
|
||||||
|
|
||||||
private:
|
virtual bool StartTimer(bool periodic, unsigned long time);
|
||||||
HANDLE _event;
|
virtual bool StopTimer();
|
||||||
WebRtc_UWord32 _timerID;
|
|
||||||
|
private:
|
||||||
|
HANDLE event_;
|
||||||
|
WebRtc_UWord32 timerID_;
|
||||||
};
|
};
|
||||||
} // namespace webrtc
|
|
||||||
|
|
||||||
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_WINDOWS_H_
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_WIN_H_
|
||||||
|
Loading…
x
Reference in New Issue
Block a user