blob: e49ad55756db2acae801427af1baa699b2fbc2a7 [file] [log] [blame]
Paul Stewart75897df2011-04-27 09:05:53 -07001// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <stdio.h>
6#include <glib.h>
7
Chris Masone0e1d1042011-05-09 18:07:03 -07008#include <base/callback.h>
9#include <base/message_loop_proxy.h>
10
Paul Stewart75897df2011-04-27 09:05:53 -070011#include "shill/shill_event.h"
12
13namespace shill {
14
Chris Masone0e1d1042011-05-09 18:07:03 -070015static gboolean DispatchIOHandler(GIOChannel *chan,
16 GIOCondition cond,
Paul Stewarta43d9232011-05-10 11:40:22 -070017 gpointer data);
18
19class GlibIOInputHandler : public IOInputHandler {
20public:
21 GIOChannel *channel_;
Chris Masone0e1d1042011-05-09 18:07:03 -070022 Callback1<InputData *>::Type *callback_;
Paul Stewarta43d9232011-05-10 11:40:22 -070023 guint source_id_;
Paul Stewarta43d9232011-05-10 11:40:22 -070024
Chris Masone0e1d1042011-05-09 18:07:03 -070025 GlibIOInputHandler(int fd, Callback1<InputData*>::Type *callback)
26 : callback_(callback) {
Paul Stewarta43d9232011-05-10 11:40:22 -070027 channel_ = g_io_channel_unix_new(fd);
28 g_io_channel_set_close_on_unref(channel_, TRUE);
29 source_id_ = g_io_add_watch(channel_,
30 (GIOCondition)(G_IO_IN | G_IO_NVAL |
31 G_IO_HUP | G_IO_ERR),
32 DispatchIOHandler, this);
33 }
34
35 ~GlibIOInputHandler() {
36 g_source_remove(source_id_);
37 g_io_channel_shutdown(channel_, TRUE, NULL);
38 g_io_channel_unref(channel_);
39 }
40};
41
Chris Masone0e1d1042011-05-09 18:07:03 -070042static gboolean DispatchIOHandler(GIOChannel *chan,
43 GIOCondition cond,
Paul Stewarta43d9232011-05-10 11:40:22 -070044 gpointer data) {
45 GlibIOInputHandler *handler = static_cast<GlibIOInputHandler *>(data);
46 unsigned char buf[4096];
47 gsize len;
48 GIOError err;
49
50 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
51 return FALSE;
52
53 err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len);
54 if (err) {
55 if (err == G_IO_ERROR_AGAIN)
56 return TRUE;
57 return FALSE;
58 }
59
60 InputData input_data = { buf, len };
61 handler->callback_->Run(&input_data);
62
63 return TRUE;
64}
Chris Masone0e1d1042011-05-09 18:07:03 -070065EventDispatcher::EventDispatcher()
66 : dont_use_directly_(new MessageLoopForUI),
67 message_loop_proxy_(base::MessageLoopProxy::CreateForCurrentThread()) {
68}
Paul Stewarta43d9232011-05-10 11:40:22 -070069
Chris Masone0e1d1042011-05-09 18:07:03 -070070EventDispatcher::~EventDispatcher() {}
71
72void EventDispatcher::DispatchForever() {
73 MessageLoop::current()->Run();
74}
75
76bool EventDispatcher::PostTask(Task* task) {
77 message_loop_proxy_->PostTask(FROM_HERE, task);
78}
79
80bool EventDispatcher::PostDelayedTask(Task* task, int64 delay_ms) {
81 message_loop_proxy_->PostDelayedTask(FROM_HERE, task, delay_ms);
82}
83
84IOInputHandler *EventDispatcher::CreateInputHandler(
85 int fd,
86 Callback1<InputData*>::Type *callback) {
87 return new GlibIOInputHandler(fd, callback);
Paul Stewarta43d9232011-05-10 11:40:22 -070088}
89
Paul Stewart75897df2011-04-27 09:05:53 -070090} // namespace shill