1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-transport.c DBusTransport object (internal to D-BUS implementation)
4 * Copyright (C) 2002 Red Hat Inc.
6 * Licensed under the Academic Free License version 1.2
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "dbus-transport-protected.h"
25 #include "dbus-transport-unix.h"
26 #include "dbus-connection-internal.h"
29 * @defgroup DBusTransport DBusTransport object
30 * @ingroup DBusInternals
31 * @brief "Backend" for a DBusConnection.
33 * Types and functions related to DBusTransport. A transport is an
34 * abstraction that can send and receive data via various kinds of
35 * network connections or other IPC mechanisms.
41 * @typedef DBusTransport
43 * Opaque object representing a way message stream.
44 * DBusTransport abstracts various kinds of actual
45 * transport mechanism, such as different network protocols,
46 * or encryption schemes.
50 * Initializes the base class members of DBusTransport.
51 * Chained up to by subclasses in their constructor.
53 * @param transport the transport being created.
54 * @param vtable the subclass vtable.
55 * @returns #TRUE on success.
58 _dbus_transport_init_base (DBusTransport *transport,
59 const DBusTransportVTable *vtable)
61 DBusMessageLoader *loader;
63 loader = _dbus_message_loader_new ();
67 transport->refcount = 1;
68 transport->vtable = vtable;
69 transport->loader = loader;
75 * Finalizes base class members of DBusTransport.
76 * Chained up to from subclass finalizers.
78 * @param transport the transport.
81 _dbus_transport_finalize_base (DBusTransport *transport)
83 if (!transport->disconnected)
84 _dbus_transport_disconnect (transport);
86 _dbus_message_loader_unref (transport->loader);
90 * Opens a new transport for the given address.
92 * @todo right now the address is just a Unix domain socket path.
94 * @param address the address.
95 * @param result location to store reason for failure.
96 * @returns new transport of #NULL on failure.
99 _dbus_transport_open (const char *address,
100 DBusResultCode *result)
102 DBusTransport *transport;
104 /* FIXME parse the address - whatever format
105 * we decide addresses are in - and find the
106 * appropriate transport.
109 /* Pretend it's just a unix domain socket name for now */
110 transport = _dbus_transport_new_for_domain_socket (address, result);
116 * Increments the reference count for the transport.
118 * @param transport the transport.
121 _dbus_transport_ref (DBusTransport *transport)
123 transport->refcount += 1;
127 * Decrements the reference count for the transport.
128 * Disconnects and finalizes the transport if
129 * the reference count reaches zero.
131 * @param transport the transport.
134 _dbus_transport_unref (DBusTransport *transport)
136 _dbus_assert (transport != NULL);
137 _dbus_assert (transport->refcount > 0);
139 transport->refcount -= 1;
140 if (transport->refcount == 0)
142 _dbus_assert (transport->vtable->finalize != NULL);
144 (* transport->vtable->finalize) (transport);
149 * Closes our end of the connection to a remote application. Further
150 * attempts to use this transport will fail. Only the first call to
151 * _dbus_transport_disconnect() will have an effect.
153 * @param transport the transport.
157 _dbus_transport_disconnect (DBusTransport *transport)
159 _dbus_assert (transport->vtable->disconnect != NULL);
161 if (transport->disconnected)
164 (* transport->vtable->disconnect) (transport);
166 transport->disconnected = TRUE;
170 * Returns #TRUE if the transport has not been disconnected.
171 * Disconnection can result from _dbus_transport_disconnect()
172 * or because the server drops its end of the connection.
174 * @param transport the transport.
177 _dbus_transport_get_is_connected (DBusTransport *transport)
179 return !transport->disconnected;
183 * Handles a watch by reading data, writing data, or disconnecting
184 * the transport, as appropriate for the given condition.
186 * @param transport the transport.
187 * @param watch the watch.
188 * @param condition the current state of the watched file descriptor.
191 _dbus_transport_handle_watch (DBusTransport *transport,
193 unsigned int condition)
195 _dbus_assert (transport->vtable->handle_watch != NULL);
197 if (transport->disconnected)
199 _dbus_connection_transport_error (transport->connection,
200 DBUS_RESULT_DISCONNECTED);
204 _dbus_watch_sanitize_condition (watch, &condition);
206 (* transport->vtable->handle_watch) (transport, watch, condition);
210 * Sets the connection using this transport. Allows the transport
211 * to add watches to the connection, queue incoming messages,
212 * and pull outgoing messages.
214 * @param transport the transport.
215 * @param connection the connection.
218 _dbus_transport_set_connection (DBusTransport *transport,
219 DBusConnection *connection)
221 _dbus_assert (transport->vtable->connection_set != NULL);
222 _dbus_assert (transport->connection == NULL);
224 transport->connection = connection;
226 (* transport->vtable->connection_set) (transport);
230 * Notifies the transport when the outgoing message queue goes from
231 * empty to non-empty or vice versa. Typically causes the transport to
232 * add or remove its DBUS_WATCH_WRITABLE watch.
234 * @param transport the transport.
235 * @param queue_length the length of the outgoing message queue.
239 _dbus_transport_messages_pending (DBusTransport *transport,
242 _dbus_assert (transport->vtable->messages_pending != NULL);
244 if (transport->disconnected)
246 _dbus_connection_transport_error (transport->connection,
247 DBUS_RESULT_DISCONNECTED);
251 (* transport->vtable->messages_pending) (transport,
256 * Performs a single poll()/select() on the transport's file
257 * descriptors and then reads/writes data as appropriate,
258 * queueing incoming messages and sending outgoing messages.
259 * This is the backend for _dbus_connection_do_iteration().
260 * See _dbus_connection_do_iteration() for full details.
262 * @param transport the transport.
263 * @param flags indicates whether to read or write, and whether to block.
264 * @param timeout_milliseconds if blocking, timeout or -1 for no timeout.
267 _dbus_transport_do_iteration (DBusTransport *transport,
269 int timeout_milliseconds)
271 _dbus_assert (transport->vtable->do_iteration != NULL);
273 if ((flags & (DBUS_ITERATION_DO_WRITING |
274 DBUS_ITERATION_DO_READING)) == 0)
275 return; /* Nothing to do */
277 if (transport->disconnected)
279 _dbus_connection_transport_error (transport->connection,
280 DBUS_RESULT_DISCONNECTED);
284 (* transport->vtable->do_iteration) (transport, flags,
285 timeout_milliseconds);