blob: 4934395a1e03664e25209d5a12e13ef8c42f9d98 [file] [log] [blame]
Darin Petkov78f63262012-03-26 01:30:24 +02001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Paul Stewartf0aae102011-10-19 12:11:44 -07002// 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
Eric Shienbrood3e20a232012-02-16 11:35:56 -050012using base::Callback;
13
Paul Stewartf0aae102011-10-19 12:11:44 -070014namespace shill {
15
16static gboolean DispatchIOHandler(GIOChannel *chan,
17 GIOCondition cond,
18 gpointer data) {
Eric Shienbrood3e20a232012-02-16 11:35:56 -050019 GlibIOReadyHandler *handler = reinterpret_cast<GlibIOReadyHandler *>(data);
Paul Stewartf65320c2011-10-13 14:34:52 -070020
Eric Shienbrood3e20a232012-02-16 11:35:56 -050021 handler->callback().Run(g_io_channel_unix_get_fd(chan));
Paul Stewartf0aae102011-10-19 12:11:44 -070022
23 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
24 return FALSE;
25
Paul Stewartf0aae102011-10-19 12:11:44 -070026 return TRUE;
27}
28
29GlibIOReadyHandler::GlibIOReadyHandler(int fd,
30 IOHandler::ReadyMode mode,
Eric Shienbrood3e20a232012-02-16 11:35:56 -050031 const Callback<void(int)> &callback)
Paul Stewartf0aae102011-10-19 12:11:44 -070032 : channel_(NULL),
33 callback_(callback),
34 source_id_(G_MAXUINT) {
35 if (mode == kModeInput) {
36 condition_ = static_cast<GIOCondition>(
37 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR);
38 } else if (mode == kModeOutput) {
39 condition_ = static_cast<GIOCondition>(
40 G_IO_OUT | G_IO_NVAL | G_IO_HUP | G_IO_ERR);
41 } else {
42 NOTREACHED() << "Unknown IO ready mode: " << mode;
43 }
44
45 channel_ = g_io_channel_unix_new(fd);
46 g_io_channel_set_close_on_unref(channel_, FALSE);
47}
48
49GlibIOReadyHandler::~GlibIOReadyHandler() {
Darin Petkov78f63262012-03-26 01:30:24 +020050 GlibIOReadyHandler::Stop();
Paul Stewartc2350ee2011-10-19 12:28:40 -070051 // NB: We don't shut down the channel since we don't own it
Paul Stewartf0aae102011-10-19 12:11:44 -070052 g_io_channel_unref(channel_);
53}
54
55void GlibIOReadyHandler::Start() {
56 if (source_id_ == G_MAXUINT) {
Eric Shienbrood3e20a232012-02-16 11:35:56 -050057 source_id_ = g_io_add_watch(channel_, condition_, DispatchIOHandler, this);
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