blob: e1b898637ae34d4a0864636bc927f1f353f72729 [file] [log] [blame]
// Copyright 2014 The Android Open Source Project
//
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Include this first to avoid compiler warning.
#include "android/base/Limits.h"
#include "android/looper-base.h"
#include "android/base/async/Looper.h"
#include "android/base/sockets/SocketUtils.h"
#include "android/qemu/base/async/Looper.h"
// An implementation of the C Looper type based on the C++
// android::base::Looper class.
namespace android {
namespace internal {
namespace {
typedef ::Duration CDuration;
typedef ::android::base::Looper::Duration BaseDuration;
typedef ::android::base::Looper::Timer BaseTimer;
typedef ::android::base::Looper::FdWatch BaseFdWatch;
// Forward declarations.
GLooper* asGLooper(CLooper* looper);
BaseLooper* asBaseLooper(CLooper* looper);
/**********************************************************************
**********************************************************************
*****
***** T I M E R S
*****
**********************************************************************
**********************************************************************/
BaseTimer* asBaseTimer(void* impl) {
return reinterpret_cast<BaseTimer*>(impl);
}
void glooptimer_stop(void* impl) {
asBaseTimer(impl)->stop();
}
void glooptimer_startAbsolute(void* impl, Duration deadline_ms) {
asBaseTimer(impl)->startAbsolute(deadline_ms);
}
void glooptimer_startRelative(void* impl, Duration timeout_ms) {
asBaseTimer(impl)->startRelative(timeout_ms);
}
int glooptimer_isActive(void* impl) {
return asBaseTimer(impl)->isActive();
}
void glooptimer_free(void* impl) {
delete asBaseTimer(impl);
}
const LoopTimerClass glooptimer_class = {
glooptimer_startRelative,
glooptimer_startAbsolute,
glooptimer_stop,
glooptimer_isActive,
glooptimer_free
};
void glooper_timer_init(CLooper* looper,
LoopTimer* timer,
LoopTimerFunc callback,
void* opaque) {
timer->impl = static_cast<void*>(
asBaseLooper(looper)->createTimer(callback, opaque));
timer->clazz = (LoopTimerClass*) &glooptimer_class;
}
/**********************************************************************
**********************************************************************
*****
***** I / O
*****
**********************************************************************
**********************************************************************/
BaseFdWatch* asBaseFdWatch(void* impl) {
return reinterpret_cast<BaseFdWatch*>(impl);
}
void gloopio_wantRead(void* impl) {
asBaseFdWatch(impl)->wantRead();
}
void gloopio_wantWrite(void* impl) {
asBaseFdWatch(impl)->wantWrite();
}
void gloopio_dontWantRead(void* impl) {
asBaseFdWatch(impl)->dontWantRead();
}
void gloopio_dontWantWrite(void* impl) {
asBaseFdWatch(impl)->dontWantWrite();
}
static unsigned gloopio_poll(void* impl) {
return asBaseFdWatch(impl)->poll();
};
void gloopio_free(void* impl) {
delete asBaseFdWatch(impl);
}
LoopIoClass gloopio_class = {
gloopio_wantRead,
gloopio_wantWrite,
gloopio_dontWantRead,
gloopio_dontWantWrite,
gloopio_poll,
gloopio_free
};
void glooper_io_init(Looper* looper,
LoopIo* user,
int fd,
LoopIoFunc callback,
void* opaque) {
android::base::socketSetNonBlocking(fd);
user->impl = asBaseLooper(looper)->createFdWatch(fd, callback, opaque);
user->clazz = (LoopIoClass*) &gloopio_class;
}
/**********************************************************************
**********************************************************************
*****
***** L O O P E R
*****
**********************************************************************
**********************************************************************/
GLooper* asGLooper(CLooper* ll) {
return reinterpret_cast<GLooper*>(ll);
}
BaseLooper* asBaseLooper(CLooper* ll) {
return asGLooper(ll)->baseLooper;
}
CDuration glooper_now(CLooper* ll) {
return asBaseLooper(ll)->nowMs();
}
void glooper_forceQuit(CLooper* ll) {
asBaseLooper(ll)->forceQuit();
}
int glooper_run(CLooper* ll, Duration loop_deadline_ms) {
return asBaseLooper(ll)->runWithDeadlineMs(loop_deadline_ms);
}
void glooper_free(Looper* ll) {
delete asGLooper(ll);
}
} // namespace
GLooper::GLooper(BaseLooper* baseLooper_) :
looper(),
baseLooper(baseLooper_) {
looper.now = glooper_now;
looper.timer_init = glooper_timer_init;
looper.io_init = glooper_io_init;
looper.run = glooper_run;
looper.forceQuit = glooper_forceQuit;
looper.destroy = glooper_free;
}
GLooper::~GLooper() {
delete baseLooper;
}
BaseLooper* toBaseLooper(CLooper* looper) {
return asBaseLooper(looper);
}
} // namespace internal
} // namespace android