blob: 985b2254dbe3be7732b1d6eee2a99189ad948f85 [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
Paul Stewartf0aae102011-10-19 12:11:44 -07007#include <glib.h>
8#include <stdio.h>
9#include <sys/socket.h>
10
Christopher Wileyb691efd2012-08-09 13:51:51 -070011#include "shill/logging.h"
12
Eric Shienbrood3e20a232012-02-16 11:35:56 -050013using base::Callback;
14
Paul Stewartf0aae102011-10-19 12:11:44 -070015namespace shill {
16
17static gboolean DispatchIOHandler(GIOChannel *chan,
18 GIOCondition cond,
19 gpointer data) {
Eric Shienbrood3e20a232012-02-16 11:35:56 -050020 GlibIOReadyHandler *handler = reinterpret_cast<GlibIOReadyHandler *>(data);
Paul Stewartf65320c2011-10-13 14:34:52 -070021
Eric Shienbrood3e20a232012-02-16 11:35:56 -050022 handler->callback().Run(g_io_channel_unix_get_fd(chan));
Paul Stewartf0aae102011-10-19 12:11:44 -070023
24 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
25 return FALSE;
26
Paul Stewartf0aae102011-10-19 12:11:44 -070027 return TRUE;
28}
29
30GlibIOReadyHandler::GlibIOReadyHandler(int fd,
31 IOHandler::ReadyMode mode,
Eric Shienbrood3e20a232012-02-16 11:35:56 -050032 const Callback<void(int)> &callback)
Paul Stewartf0aae102011-10-19 12:11:44 -070033 : channel_(NULL),
34 callback_(callback),
35 source_id_(G_MAXUINT) {
36 if (mode == kModeInput) {
37 condition_ = static_cast<GIOCondition>(
38 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR);
39 } else if (mode == kModeOutput) {
40 condition_ = static_cast<GIOCondition>(
41 G_IO_OUT | G_IO_NVAL | G_IO_HUP | G_IO_ERR);
42 } else {
43 NOTREACHED() << "Unknown IO ready mode: " << mode;
44 }
45
46 channel_ = g_io_channel_unix_new(fd);
47 g_io_channel_set_close_on_unref(channel_, FALSE);
48}
49
50GlibIOReadyHandler::~GlibIOReadyHandler() {
Darin Petkov78f63262012-03-26 01:30:24 +020051 GlibIOReadyHandler::Stop();
Paul Stewartc2350ee2011-10-19 12:28:40 -070052 // NB: We don't shut down the channel since we don't own it
Paul Stewartf0aae102011-10-19 12:11:44 -070053 g_io_channel_unref(channel_);
54}
55
56void GlibIOReadyHandler::Start() {
57 if (source_id_ == G_MAXUINT) {
Eric Shienbrood3e20a232012-02-16 11:35:56 -050058 source_id_ = g_io_add_watch(channel_, condition_, DispatchIOHandler, this);
Paul Stewartf0aae102011-10-19 12:11:44 -070059 }
60}
61
62void GlibIOReadyHandler::Stop() {
63 if (source_id_ != G_MAXUINT) {
64 g_source_remove(source_id_);
65 source_id_ = G_MAXUINT;
66 }
67}
68
69} // namespace shill