blob: a4418f4f71e3c0957bd38df8b6653791f59ee758 [file] [log] [blame]
Paul Stewart25379f12011-05-26 06:41:38 -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
Paul Stewartf0aae102011-10-19 12:11:44 -07005#include "shill/glib_io_input_handler.h"
Paul Stewart26b327e2011-10-19 11:38:09 -07006
Paul Stewart25379f12011-05-26 06:41:38 -07007#include <stdio.h>
8#include <glib.h>
9
Paul Stewart25379f12011-05-26 06:41:38 -070010namespace shill {
11
12static gboolean DispatchIOHandler(GIOChannel *chan,
13 GIOCondition cond,
Paul Stewart25379f12011-05-26 06:41:38 -070014 gpointer data) {
Paul Stewartf0aae102011-10-19 12:11:44 -070015 Callback1<InputData*>::Type *callback =
16 static_cast<Callback1<InputData*>::Type *>(data);
Paul Stewart25379f12011-05-26 06:41:38 -070017 unsigned char buf[4096];
18 gsize len;
19 GIOError err;
Paul Stewartf65320c2011-10-13 14:34:52 -070020 gboolean ret = TRUE;
Paul Stewart25379f12011-05-26 06:41:38 -070021
22 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
23 return FALSE;
24
25 err = g_io_channel_read(chan, reinterpret_cast<gchar *>(buf), sizeof(buf),
26 &len);
27 if (err) {
28 if (err == G_IO_ERROR_AGAIN)
29 return TRUE;
Paul Stewartf65320c2011-10-13 14:34:52 -070030 len = 0;
31 ret = FALSE;
Paul Stewart25379f12011-05-26 06:41:38 -070032 }
33
Darin Petkov633ac6f2011-07-08 13:56:13 -070034 InputData input_data(buf, len);
Paul Stewartf0aae102011-10-19 12:11:44 -070035 callback->Run(&input_data);
Paul Stewart25379f12011-05-26 06:41:38 -070036
Paul Stewartf65320c2011-10-13 14:34:52 -070037 return ret;
Paul Stewart25379f12011-05-26 06:41:38 -070038}
39
Paul Stewartf0aae102011-10-19 12:11:44 -070040GlibIOInputHandler::GlibIOInputHandler(int fd,
41 Callback1<InputData*>::Type *callback)
42 : channel_(g_io_channel_unix_new(fd)),
43 callback_(callback),
44 source_id_(G_MAXUINT) {
45 g_io_channel_set_close_on_unref(channel_, TRUE);
46}
47
48GlibIOInputHandler::~GlibIOInputHandler() {
49 g_source_remove(source_id_);
50 g_io_channel_shutdown(channel_, TRUE, NULL);
51 g_io_channel_unref(channel_);
52}
53
54void GlibIOInputHandler::Start() {
55 if (source_id_ == G_MAXUINT) {
56 source_id_ = g_io_add_watch(channel_,
57 static_cast<GIOCondition>(
58 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR),
59 DispatchIOHandler, callback_);
60 }
61}
62
63void GlibIOInputHandler::Stop() {
64 if (source_id_ != G_MAXUINT) {
65 g_source_remove(source_id_);
66 source_id_ = G_MAXUINT;
67 }
68}
69
Paul Stewart25379f12011-05-26 06:41:38 -070070} // namespace shill