spice client: remove timer interface from platform - use Application (via ProcessLoop interface).

This commit is contained in:
Yonit Halperin 2009-11-09 18:05:40 +02:00 committed by Yaniv Kamay
parent 4c72ba138c
commit ec34856fea
9 changed files with 86 additions and 191 deletions

View File

@ -594,6 +594,33 @@ InterruptUpdate::InterruptUpdate(DisplayChannel& channel)
{
}
StreamsTimer::StreamsTimer(DisplayChannel& channel)
: _channel (channel)
{
}
void StreamsTimer::response(AbstractProcessLoop &events_loop)
{
_channel.streams_time();
}
#define RESET_TIMEOUT (1000 * 5)
class ResetTimer: public Timer {
public:
ResetTimer(RedScreen* screen, RedClient& client) : _screen(screen), _client(client) {}
virtual void response(AbstractProcessLoop &events_loop);
private:
RedScreen* _screen;
RedClient& _client;
};
void ResetTimer::response(AbstractProcessLoop &events_loop)
{
_screen->unref();
_client.deactivate_interval_timer(this);
}
class DisplayHandler: public MessageHandlerImp<DisplayChannel, RED_DISPLAY_MESSAGES_END> {
public:
DisplayHandler(DisplayChannel& channel)
@ -610,7 +637,7 @@ DisplayChannel::DisplayChannel(RedClient& client, uint32_t id,
, _glz_window (glz_window)
, _mark (false)
, _update_mark (0)
, _streams_timer (INVALID_TIMER)
, _streams_timer (new StreamsTimer(*this))
, _next_timer_time (0)
, _active_streams (NULL)
, _streams_trigger (*this)
@ -817,49 +844,6 @@ void DisplayChannel::copy_pixels(const QRegion& dest_region,
_canvas->copy_pixels(dest_region, dest_dc);
}
class CreateTimerEvent: public SyncEvent {
public:
CreateTimerEvent(timer_proc_t proc, void* user_data)
: SyncEvent()
, _proc (proc)
, _user_data (user_data)
, _timer (INVALID_TIMER)
{
}
virtual ~CreateTimerEvent()
{
ASSERT(_timer == INVALID_TIMER);
}
virtual void do_response(AbstractProcessLoop& events_loop)
{
if ((_timer = Platform::create_interval_timer(_proc, _user_data)) == INVALID_TIMER) {
THROW("create timer failed");
}
}
TimerID release() { TimerID ret = _timer; _timer = INVALID_TIMER; return ret;}
private:
timer_proc_t _proc;
void* _user_data;
TimerID _timer;
};
class DestroyTimerEvent: public Event {
public:
DestroyTimerEvent(TimerID timer) : _timer (timer) {}
virtual void response(AbstractProcessLoop& events_loop)
{
Platform::destroy_interval_timer(_timer);
}
private:
TimerID _timer;
};
class ActivateTimerEvent: public Event {
public:
ActivateTimerEvent(DisplayChannel& channel)
@ -876,19 +860,6 @@ private:
DisplayChannel& _channel;
};
void DisplayChannel::streams_timer_callback(void* opaque, TimerID timer)
{
((DisplayChannel *)opaque)->streams_time();
}
#define RESET_TIMEOUT (1000 * 5)
void DisplayChannel::reset_timer_callback(void* opaque, TimerID timer)
{
((RedScreen *)opaque)->unref();
Platform::destroy_interval_timer(timer);
}
void DisplayChannel::on_connect()
{
Message* message = new Message(REDC_DISPLAY_INIT, sizeof(RedcDisplayInit));
@ -898,13 +869,6 @@ void DisplayChannel::on_connect()
init->glz_dictionary_id = 1;
init->glz_dictionary_window_size = get_client().get_glz_window_size();
post_message(message);
AutoRef<CreateTimerEvent> event(new CreateTimerEvent(streams_timer_callback, this));
get_client().push_event(*event);
(*event)->wait();
_streams_timer = (*event)->release();
if (!(*event)->success()) {
THROW("create timer failed");
}
}
void DisplayChannel::on_disconnect()
@ -917,8 +881,7 @@ void DisplayChannel::on_disconnect()
screen()->set_update_interrupt_trigger(NULL);
}
detach_from_screen(get_client().get_application());
AutoRef<DestroyTimerEvent> event(new DestroyTimerEvent(_streams_timer));
get_client().push_event(*event);
get_client().deactivate_interval_timer(*_streams_timer);
AutoRef<SyncEvent> sync_event(new SyncEvent());
get_client().push_event(*sync_event);
(*sync_event)->wait();
@ -1096,21 +1059,16 @@ void DisplayChannel::handle_mark(RedPeer::InMessage *message)
void DisplayChannel::handle_reset(RedPeer::InMessage *message)
{
TimerID reset_timer;
screen()->set_update_interrupt_trigger(NULL);
if (_canvas.get()) {
_canvas->clear();
}
reset_timer = Platform::create_interval_timer(reset_timer_callback, screen()->ref());
if (reset_timer == INVALID_TIMER) {
THROW("invalid reset timer");
}
AutoRef<ResetTimer> reset_timer(new ResetTimer(screen()->ref(), get_client()));
detach_from_screen(get_client().get_application());
_palette_cache.clear();
Platform::activate_interval_timer(reset_timer, RESET_TIMEOUT);
get_client().activate_interval_timer(*reset_timer, RESET_TIMEOUT);
}
void DisplayChannel::handle_inval_list(RedPeer::InMessage* message)
@ -1391,10 +1349,10 @@ void DisplayChannel::streams_time()
mm_time = get_client().get_mm_time();
next_time = mm_time + 15;
if (next_time && (!_next_timer_time || int(next_time - _next_timer_time) < 0)) {
Platform::activate_interval_timer(_streams_timer, MAX(int(next_time - mm_time), 0));
get_client().activate_interval_timer(*_streams_timer, MAX(int(next_time - mm_time), 0));
_next_timer_time = next_time;
} else if (!_next_timer_time) {
Platform::deactivate_interval_timer(_streams_timer);
get_client().deactivate_interval_timer(*_streams_timer);
}
timer_lock.unlock();
lock.unlock();
@ -1417,7 +1375,7 @@ void DisplayChannel::activate_streams_timer()
return;
}
delta = _next_timer_time - get_client().get_mm_time();
Platform::activate_interval_timer(_streams_timer, delta);
get_client().activate_interval_timer(*_streams_timer, delta);
}
}

View File

@ -70,6 +70,13 @@ private:
DisplayChannel& _channel;
};
class StreamsTimer: public Timer {
public:
StreamsTimer(DisplayChannel& channel);
virtual void response(AbstractProcessLoop& events_loop);
private:
DisplayChannel& _channel;
};
class DisplayChannel: public RedChannel, public ScreenLayer {
public:
@ -145,9 +152,6 @@ private:
static void set_clip_rects(const Clip& clip, uint32_t& num_clip_rects, Rect*& clip_rects,
unsigned long addr_offset, uint8_t *min, uint8_t *max);
static void streams_timer_callback(void* opaque, TimerID timer);
static void reset_timer_callback(void* opaque, TimerID timer);
private:
std::auto_ptr<Canvas> _canvas;
PixmapCache& _pixmap_cache;
@ -168,7 +172,7 @@ private:
Mutex _streams_lock;
Mutex _timer_lock;
TimerID _streams_timer;
AutoRef<StreamsTimer> _streams_timer;
uint32_t _next_timer_time;
std::vector<VideoStream*> _streams;
@ -183,7 +187,7 @@ private:
friend class VideoStream;
friend class StreamsTrigger;
friend class GLInterupt;
friend void streams_timer_callback(void* opaque, TimerID timer);
friend class StreamsTimer;
};
#endif

View File

@ -30,13 +30,6 @@ class Icon;
class Monitor;
typedef std::list<Monitor*> MonitorsList;
/* TODO: tmp till each channel will handle its own thread
timers or directly through the main thread */
#define INVALID_TIMER (~TimerID(0))
typedef unsigned long TimerID;
typedef void (*timer_proc_t)(void* opaque, TimerID timer);
class Platform {
public:
static void init();
@ -98,12 +91,6 @@ public:
class DisplayModeListner;
static void set_display_mode_listner(DisplayModeListner* listener);
/* TODO: tmp till each channel will handle its own thread
timers or directly through the main thread */
static TimerID create_interval_timer(timer_proc_t proc, void* opaque);
static bool activate_interval_timer(TimerID timer, unsigned int millisec);
static bool deactivate_interval_timer(TimerID timer);
static void destroy_interval_timer(TimerID timer);
};
class Platform::EventListener {

View File

@ -217,9 +217,10 @@ bool Migrate::abort()
#define AGENT_TIMEOUT (1000 * 30)
void agent_timer_proc(void *opaque, TimerID timer)
void AgentTimer::response(AbstractProcessLoop& events_loop)
{
Platform::deactivate_interval_timer(timer);
Application* app = static_cast<Application*>(events_loop.get_owner());
app->deactivate_interval_timer(this);
THROW_ERR(SPICEC_ERROR_CODE_AGENT_TIMEOUT, "vdagent timeout");
}
@ -241,7 +242,7 @@ RedClient::RedClient(Application& application)
, _agent_msg_data (NULL)
, _agent_msg_pos (0)
, _agent_tokens (0)
, _agent_timer (Platform::create_interval_timer(agent_timer_proc, NULL))
, _agent_timer (new AgentTimer())
, _migrate (*this)
, _glz_window (0, _glz_debug)
{
@ -273,16 +274,13 @@ RedClient::RedClient(Application& application)
message_loop->set_handler(RED_AGENT_DATA, &RedClient::handle_agent_data, 0);
message_loop->set_handler(RED_AGENT_TOKEN, &RedClient::handle_agent_tokens,
sizeof(RedAgentTokens));
if (_agent_timer == INVALID_TIMER) {
THROW("invalid agent timer");
}
start();
}
RedClient::~RedClient()
{
ASSERT(_channels.empty());
Platform::destroy_interval_timer(_agent_timer);
_application.deactivate_interval_timer(*_agent_timer);
delete _agent_msg;
}
@ -313,6 +311,16 @@ void RedClient::push_event(Event* event)
_application.push_event(event);
}
void RedClient::activate_interval_timer(Timer* timer, unsigned int millisec)
{
_application.activate_interval_timer(timer, millisec);
}
void RedClient::deactivate_interval_timer(Timer* timer)
{
_application.deactivate_interval_timer(timer);
}
void RedClient::on_connecting()
{
_notify_disconnect = true;
@ -329,7 +337,7 @@ void RedClient::on_disconnect()
{
_migrate.abort();
_connection_id = 0;
Platform::deactivate_interval_timer(_agent_timer);
_application.deactivate_interval_timer(*_agent_timer);
_agent_mon_config_sent = false;
delete[] _agent_msg_data;
_agent_msg_data = NULL;
@ -632,7 +640,7 @@ void RedClient::handle_init(RedPeer::InMessage* message)
post_message(msg);
}
if (_auto_display_res) {
Platform::activate_interval_timer(_agent_timer, AGENT_TIMEOUT);
_application.activate_interval_timer(*_agent_timer, AGENT_TIMEOUT);
if (_agent_connected) {
send_agent_monitors_config();
}
@ -694,7 +702,7 @@ void RedClient::on_agent_reply(VDAgentReply* reply)
switch (reply->type) {
case VD_AGENT_MONITORS_CONFIG:
post_message(new Message(REDC_ATTACH_CHANNELS, 0));
Platform::deactivate_interval_timer(_agent_timer);
_application.deactivate_interval_timer(*_agent_timer);
break;
default:
THROW("unexpected vdagent reply type");

View File

@ -112,6 +112,10 @@ public:
}
};
class AgentTimer: public Timer {
virtual void response(AbstractProcessLoop& events_loop);
};
typedef std::map< int, RedPeer::ConnectionOptions::Type> PeerConnectionOptMap;
class RedClient: public RedChannel {
@ -131,6 +135,8 @@ public:
virtual bool abort();
void push_event(Event* event);
void activate_interval_timer(Timer* timer, unsigned int millisec);
void deactivate_interval_timer(Timer* timer);
void set_target(const char* host, uint16_t port, uint16_t sport);
const char* get_password() { return _password.c_str();}
@ -206,7 +212,7 @@ private:
uint8_t* _agent_msg_data;
uint32_t _agent_msg_pos;
uint32_t _agent_tokens;
TimerID _agent_timer;
AutoRef<AgentTimer> _agent_timer;
PeerConnectionOptMap _con_opt_map;
Migrate _migrate;

View File

@ -43,11 +43,9 @@ private:
int _screen;
};
void periodic_update_proc(void *opaque, TimerID timer)
void UpdateTimer::response(AbstractProcessLoop& events_loop)
{
RedScreen* screen = (RedScreen*)opaque;
screen->periodic_update();
_screen->periodic_update();
}
RedScreen::RedScreen(Application& owner, int id, const std::wstring& name, int width, int height)
@ -65,7 +63,7 @@ RedScreen::RedScreen(Application& owner, int id, const std::wstring& name, int w
, _key_interception (false)
, _update_by_timer (true)
, _forec_update_timer (0)
, _update_timer (INVALID_TIMER)
, _update_timer (new UpdateTimer(this))
, _composit_area (NULL)
, _update_mark (1)
, _monitor (NULL)
@ -84,10 +82,6 @@ RedScreen::RedScreen(Application& owner, int id, const std::wstring& name, int w
create_composit_area();
_window.resize(_size.x, _size.y);
save_position();
_update_timer = Platform::create_interval_timer(periodic_update_proc, this);
if (_update_timer == INVALID_TIMER) {
THROW("create timer failed");
}
if ((_default_cursor = Platform::create_default_cursor()) == NULL) {
THROW("create default cursor failed");
}
@ -106,7 +100,7 @@ RedScreen::~RedScreen()
bool captured = is_captured();
relase_inputs();
destroy_composit_area();
Platform::destroy_interval_timer(_update_timer);
_owner.deactivate_interval_timer(*_update_timer);
_owner.on_screen_destroyed(_id, captured);
region_destroy(&_dirty_region);
if (_default_cursor) {
@ -333,7 +327,7 @@ void RedScreen::periodic_update()
need_update = true;
} else {
if (!_forec_update_timer) {
Platform::deactivate_interval_timer(_update_timer);
_owner.deactivate_interval_timer(*_update_timer);
_periodic_update = false;
}
need_update = false;
@ -357,9 +351,7 @@ void RedScreen::activate_timer()
}
_periodic_update = true;
lock.unlock();
if (!Platform::activate_interval_timer(_update_timer, 1000 / 30)) {
LOG_WARN("failed");
}
_owner.activate_interval_timer(*_update_timer, 1000 / 30);
}
void RedScreen::update()

View File

@ -27,10 +27,12 @@
#include "platform.h"
#include "process_loop.h"
#include "threads.h"
#include "utils.h"
class Application;
class ScreenLayer;
class Monitor;
class RedScreen;
enum {
SCREEN_LAYER_DISPLAY,
@ -38,6 +40,14 @@ enum {
SCREEN_LAYER_GUI,
};
class UpdateTimer: public Timer {
public:
UpdateTimer(RedScreen* screen) : _screen (screen) {}
virtual void response(AbstractProcessLoop& events_loop);
private:
RedScreen* _screen;
};
class RedScreen: public RedWindow::Listener {
public:
RedScreen(Application& owner, int id, const std::wstring& name, int width, int height);
@ -87,8 +97,8 @@ public:
void update();
private:
friend void periodic_update_proc(void *opaque, TimerID timer);
friend class UpdateEvent;
friend class UpdateTimer;
virtual ~RedScreen();
void create_composit_area();
@ -153,7 +163,7 @@ private:
bool _key_interception;
bool _update_by_timer;
int _forec_update_timer;
TimerID _update_timer;
AutoRef<UpdateTimer> _update_timer;
RedDrawable* _composit_area;
uint64_t _update_mark;

View File

@ -618,38 +618,3 @@ Icon* Platform::load_icon(int id)
}
return new WinIcon(icon);
}
class PlatformTimer: public Timer {
public:
PlatformTimer(timer_proc_t proc, void* opaque) : _proc (proc), _opaque (opaque) {}
void response(AbstractProcessLoop& events_loop) {_proc(_opaque, (TimerID)this);}
private:
timer_proc_t _proc;
void* _opaque;
};
TimerID Platform::create_interval_timer(timer_proc_t proc, void* opaque)
{
return (TimerID)(new PlatformTimer(proc, opaque));
}
bool Platform::activate_interval_timer(TimerID timer, unsigned int millisec)
{
ASSERT(main_loop);
main_loop->activate_interval_timer((PlatformTimer*)timer, millisec);
return true;
}
bool Platform::deactivate_interval_timer(TimerID timer)
{
ASSERT(main_loop);
main_loop->deactivate_interval_timer((PlatformTimer*)timer);
return true;
}
void Platform::destroy_interval_timer(TimerID timer)
{
deactivate_interval_timer(timer);
((PlatformTimer*)timer)->unref();
}

View File

@ -2422,38 +2422,3 @@ LocalCursor* Platform::create_default_cursor()
{
return new XDefaultCursor();
}
class PlatformTimer: public Timer {
public:
PlatformTimer(timer_proc_t proc, void* opaque) : _proc(proc), _opaque(opaque) {}
void response(AbstractProcessLoop& events_loop) {_proc(_opaque, (TimerID)this);}
private:
timer_proc_t _proc;
void* _opaque;
};
TimerID Platform::create_interval_timer(timer_proc_t proc, void* opaque)
{
return (TimerID)(new PlatformTimer(proc, opaque));
}
bool Platform::activate_interval_timer(TimerID timer, unsigned int millisec)
{
ASSERT(main_loop);
main_loop->activate_interval_timer((PlatformTimer*)timer, millisec);
return true;
}
bool Platform::deactivate_interval_timer(TimerID timer)
{
ASSERT(main_loop);
main_loop->deactivate_interval_timer((PlatformTimer*)timer);
return true;
}
void Platform::destroy_interval_timer(TimerID timer)
{
deactivate_interval_timer(timer);
((PlatformTimer*)timer)->unref();
}