blob: 012872a33de607e04bf19cd65c4da0edc41ad489 [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
Eric Shienbrood3e20a232012-02-16 11:35:56 -050010using base::Callback;
11
Paul Stewart25379f12011-05-26 06:41:38 -070012namespace shill {
13
14static gboolean DispatchIOHandler(GIOChannel *chan,
15 GIOCondition cond,
Paul Stewart25379f12011-05-26 06:41:38 -070016 gpointer data) {
Eric Shienbrood3e20a232012-02-16 11:35:56 -050017 GlibIOInputHandler *handler = reinterpret_cast<GlibIOInputHandler *>(data);
Paul Stewart25379f12011-05-26 06:41:38 -070018 unsigned char buf[4096];
19 gsize len;
20 GIOError err;
Paul Stewartf65320c2011-10-13 14:34:52 -070021 gboolean ret = TRUE;
Paul Stewart25379f12011-05-26 06:41:38 -070022
23 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
24 return FALSE;
25
26 err = g_io_channel_read(chan, reinterpret_cast<gchar *>(buf), sizeof(buf),
27 &len);
28 if (err) {
29 if (err == G_IO_ERROR_AGAIN)
30 return TRUE;
Paul Stewartf65320c2011-10-13 14:34:52 -070031 len = 0;
32 ret = FALSE;
Paul Stewart25379f12011-05-26 06:41:38 -070033 }
34
Darin Petkov633ac6f2011-07-08 13:56:13 -070035 InputData input_data(buf, len);
Eric Shienbrood3e20a232012-02-16 11:35:56 -050036 handler->callback().Run(&input_data);
Paul Stewart25379f12011-05-26 06:41:38 -070037
Paul Stewartf65320c2011-10-13 14:34:52 -070038 return ret;
Paul Stewart25379f12011-05-26 06:41:38 -070039}
40
Eric Shienbrood3e20a232012-02-16 11:35:56 -050041GlibIOInputHandler::GlibIOInputHandler(
42 int fd, const Callback<void(InputData *)> &callback)
Paul Stewartf0aae102011-10-19 12:11:44 -070043 : channel_(g_io_channel_unix_new(fd)),
44 callback_(callback),
45 source_id_(G_MAXUINT) {
46 g_io_channel_set_close_on_unref(channel_, TRUE);
47}
48
49GlibIOInputHandler::~GlibIOInputHandler() {
50 g_source_remove(source_id_);
51 g_io_channel_shutdown(channel_, TRUE, NULL);
52 g_io_channel_unref(channel_);
53}
54
55void GlibIOInputHandler::Start() {
56 if (source_id_ == G_MAXUINT) {
57 source_id_ = g_io_add_watch(channel_,
58 static_cast<GIOCondition>(
59 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR),
Eric Shienbrood3e20a232012-02-16 11:35:56 -050060 DispatchIOHandler, this);
Paul Stewartf0aae102011-10-19 12:11:44 -070061 }
62}
63
64void GlibIOInputHandler::Stop() {
65 if (source_id_ != G_MAXUINT) {
66 g_source_remove(source_id_);
67 source_id_ = G_MAXUINT;
68 }
69}
70
Paul Stewart25379f12011-05-26 06:41:38 -070071} // namespace shill