blob: b72ca0e47e041fcbee920eab86bc647e1ba08c42 [file] [log] [blame]
Paul Stewartf0aae102011-10-19 12:11:44 -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 "shill/glib_io_ready_handler.h"
6
7#include <base/logging.h>
8#include <glib.h>
9#include <stdio.h>
10#include <sys/socket.h>
11
12namespace shill {
13
14static gboolean DispatchIOHandler(GIOChannel *chan,
15 GIOCondition cond,
16 gpointer data) {
Eric Shienbroodb5c89402012-03-13 08:29:25 -070017 Callback1<int>::Type *callback =
18 reinterpret_cast<Callback1<int>::Type *>(data);
Paul Stewartf65320c2011-10-13 14:34:52 -070019
Eric Shienbroodb5c89402012-03-13 08:29:25 -070020 callback->Run(g_io_channel_unix_get_fd(chan));
Paul Stewartf0aae102011-10-19 12:11:44 -070021
22 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
23 return FALSE;
24
Paul Stewartf0aae102011-10-19 12:11:44 -070025 return TRUE;
26}
27
28GlibIOReadyHandler::GlibIOReadyHandler(int fd,
29 IOHandler::ReadyMode mode,
Eric Shienbroodb5c89402012-03-13 08:29:25 -070030 Callback1<int>::Type *callback)
Paul Stewartf0aae102011-10-19 12:11:44 -070031 : channel_(NULL),
32 callback_(callback),
33 source_id_(G_MAXUINT) {
34 if (mode == kModeInput) {
35 condition_ = static_cast<GIOCondition>(
36 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR);
37 } else if (mode == kModeOutput) {
38 condition_ = static_cast<GIOCondition>(
39 G_IO_OUT | G_IO_NVAL | G_IO_HUP | G_IO_ERR);
40 } else {
41 NOTREACHED() << "Unknown IO ready mode: " << mode;
42 }
43
44 channel_ = g_io_channel_unix_new(fd);
45 g_io_channel_set_close_on_unref(channel_, FALSE);
46}
47
48GlibIOReadyHandler::~GlibIOReadyHandler() {
49 g_source_remove(source_id_);
Paul Stewartc2350ee2011-10-19 12:28:40 -070050 // NB: We don't shut down the channel since we don't own it
Paul Stewartf0aae102011-10-19 12:11:44 -070051 g_io_channel_unref(channel_);
52}
53
54void GlibIOReadyHandler::Start() {
55 if (source_id_ == G_MAXUINT) {
Eric Shienbroodb5c89402012-03-13 08:29:25 -070056 source_id_ = g_io_add_watch(channel_, condition_, DispatchIOHandler,
57 callback_);
Paul Stewartf0aae102011-10-19 12:11:44 -070058 }
59}
60
61void GlibIOReadyHandler::Stop() {
62 if (source_id_ != G_MAXUINT) {
63 g_source_remove(source_id_);
64 source_id_ = G_MAXUINT;
65 }
66}
67
68} // namespace shill