4
* Copyright (c) 2006 Ryo Dairiki <ryo-dairiki@users.sourceforge.net>
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation and
10
* appearing in the file LICENSE.LGPL included in the package of this file.
11
* You can also redistribute it and/or modify it under the terms of
12
* the GNU General Public License as published by the Free Software Foundation and
13
* appearing in the file LICENSE.GPL included in the package of this file.
15
* This library is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26
#include <sys/socket.h>
27
#include <sys/types.h>
29
#include "scim-bridge-output.h"
31
#include "scim-bridge-agent-interruption-listener.h"
33
/* Class definition */
34
class ScimBridgeAgentInterruptionListenerImpl: public ScimBridgeAgentInterruptionListener
39
ScimBridgeAgentInterruptionListenerImpl ();
40
~ScimBridgeAgentInterruptionListenerImpl ();
42
retval_t initialize ();
44
int get_socket_fd () const;
46
scim_bridge_agent_event_type_t get_trigger_events () const;
48
bool handle_event (scim_bridge_agent_event_type_t event_type);
50
bool is_interrupted () const;
54
void clear_interruption ();
66
ScimBridgeAgentInterruptionListener *ScimBridgeAgentInterruptionListener::alloc ()
69
ScimBridgeAgentInterruptionListenerImpl *interruption_listener = new ScimBridgeAgentInterruptionListenerImpl ();
70
if (interruption_listener->initialize ()) {
71
delete interruption_listener;
72
interruption_listener = NULL;
75
return interruption_listener;
79
ScimBridgeAgentInterruptionListenerImpl::ScimBridgeAgentInterruptionListenerImpl (): interrupted (false), pipe_in (-1), pipe_out (-1)
84
ScimBridgeAgentInterruptionListenerImpl::~ScimBridgeAgentInterruptionListenerImpl ()
86
if (pipe_in >= 0) close (pipe_in);
87
if (pipe_out >= 0) close (pipe_out);
91
retval_t ScimBridgeAgentInterruptionListenerImpl::initialize ()
95
if (socketpair (PF_UNIX, SOCK_STREAM, 0, pipe_pair)) {
96
scim_bridge_perrorln ("Cannot make a pipe for a interruption listener: %s", strerror (errno));
100
pipe_out = pipe_pair[0];
101
pipe_in = pipe_pair[1];
102
scim_bridge_pdebugln (2, "The interruption pipe: (%d, %d)", pipe_in, pipe_out);
104
return RETVAL_SUCCEEDED;
108
int ScimBridgeAgentInterruptionListenerImpl::get_socket_fd () const
114
scim_bridge_agent_event_type_t ScimBridgeAgentInterruptionListenerImpl::get_trigger_events () const
116
return SCIM_BRIDGE_AGENT_EVENT_READ;
120
bool ScimBridgeAgentInterruptionListenerImpl::handle_event (scim_bridge_agent_event_type_t event_type)
126
void ScimBridgeAgentInterruptionListenerImpl::interrupt ()
128
scim_bridge_pdebugln (1, "An interruption occurred");
129
if (interrupted) return;
132
if (send (pipe_in, " ", sizeof (char), MSG_NOSIGNAL | MSG_DONTWAIT) < 0 && errno != EAGAIN) {
133
scim_bridge_perrorln ("Failed to make an interruption: %s", strerror (errno));
138
bool ScimBridgeAgentInterruptionListenerImpl::is_interrupted () const
144
void ScimBridgeAgentInterruptionListenerImpl::clear_interruption ()
146
scim_bridge_pdebugln (1, "The interruption is cleared");
148
recv (pipe_out, &c, sizeof (char), MSG_DONTWAIT);