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"
27 #include "dbus-watch.h"
30 * @defgroup DBusTransport DBusTransport object
31 * @ingroup DBusInternals
32 * @brief "Backend" for a DBusConnection.
34 * Types and functions related to DBusTransport. A transport is an
35 * abstraction that can send and receive data via various kinds of
36 * network connections or other IPC mechanisms.
42 * @typedef DBusTransport
44 * Opaque object representing a way message stream.
45 * DBusTransport abstracts various kinds of actual
46 * transport mechanism, such as different network protocols,
47 * or encryption schemes.
51 * Initializes the base class members of DBusTransport.
52 * Chained up to by subclasses in their constructor.
54 * @param transport the transport being created.
55 * @param vtable the subclass vtable.
56 * @returns #TRUE on success.
59 _dbus_transport_init_base (DBusTransport *transport,
60 const DBusTransportVTable *vtable)
62 DBusMessageLoader *loader;
64 loader = _dbus_message_loader_new ();
68 transport->refcount = 1;
69 transport->vtable = vtable;
70 transport->loader = loader;
76 * Finalizes base class members of DBusTransport.
77 * Chained up to from subclass finalizers.
79 * @param transport the transport.
82 _dbus_transport_finalize_base (DBusTransport *transport)
84 if (!transport->disconnected)
85 _dbus_transport_disconnect (transport);
87 _dbus_message_loader_unref (transport->loader);
91 * Opens a new transport for the given address.
93 * @todo right now the address is just a Unix domain socket path.
95 * @param address the address.
96 * @param result location to store reason for failure.
97 * @returns new transport of #NULL on failure.
100 _dbus_transport_open (const char *address,
101 DBusResultCode *result)
103 DBusTransport *transport;
105 /* FIXME parse the address - whatever format
106 * we decide addresses are in - and find the
107 * appropriate transport.
110 /* Pretend it's just a unix domain socket name for now */
111 transport = _dbus_transport_new_for_domain_socket (address, result);
117 * Increments the reference count for the transport.
119 * @param transport the transport.
122 _dbus_transport_ref (DBusTransport *transport)
124 transport->refcount += 1;
128 * Decrements the reference count for the transport.
129 * Disconnects and finalizes the transport if
130 * the reference count reaches zero.
132 * @param transport the transport.
135 _dbus_transport_unref (DBusTransport *transport)
137 _dbus_assert (transport != NULL);
138 _dbus_assert (transport->refcount > 0);
140 transport->refcount -= 1;
141 if (transport->refcount == 0)
143 _dbus_assert (transport->vtable->finalize != NULL);
145 (* transport->vtable->finalize) (transport);
150 * Closes our end of the connection to a remote application. Further
151 * attempts to use this transport will fail. Only the first call to
152 * _dbus_transport_disconnect() will have an effect.
154 * @param transport the transport.
158 _dbus_transport_disconnect (DBusTransport *transport)
160 _dbus_assert (transport->vtable->disconnect != NULL);
162 if (transport->disconnected)
165 (* transport->vtable->disconnect) (transport);
167 transport->disconnected = TRUE;
171 * Returns #TRUE if the transport has not been disconnected.
172 * Disconnection can result from _dbus_transport_disconnect()
173 * or because the server drops its end of the connection.
175 * @param transport the transport.
178 _dbus_transport_get_is_connected (DBusTransport *transport)
180 return !transport->disconnected;
184 * Handles a watch by reading data, writing data, or disconnecting
185 * the transport, as appropriate for the given condition.
187 * @param transport the transport.
188 * @param watch the watch.
189 * @param condition the current state of the watched file descriptor.
192 _dbus_transport_handle_watch (DBusTransport *transport,
194 unsigned int condition)
196 _dbus_assert (transport->vtable->handle_watch != NULL);
198 if (transport->disconnected)
200 _dbus_connection_transport_error (transport->connection,
201 DBUS_RESULT_DISCONNECTED);
205 _dbus_watch_sanitize_condition (watch, &condition);
207 (* transport->vtable->handle_watch) (transport, watch, condition);
211 * Sets the connection using this transport. Allows the transport
212 * to add watches to the connection, queue incoming messages,
213 * and pull outgoing messages.
215 * @param transport the transport.
216 * @param connection the connection.
219 _dbus_transport_set_connection (DBusTransport *transport,
220 DBusConnection *connection)
222 _dbus_assert (transport->vtable->connection_set != NULL);
223 _dbus_assert (transport->connection == NULL);
225 transport->connection = connection;
227 (* transport->vtable->connection_set) (transport);
231 * Notifies the transport when the outgoing message queue goes from
232 * empty to non-empty or vice versa. Typically causes the transport to
233 * add or remove its DBUS_WATCH_WRITABLE watch.
235 * @param transport the transport.
236 * @param queue_length the length of the outgoing message queue.
240 _dbus_transport_messages_pending (DBusTransport *transport,
243 _dbus_assert (transport->vtable->messages_pending != NULL);
245 if (transport->disconnected)
247 _dbus_connection_transport_error (transport->connection,
248 DBUS_RESULT_DISCONNECTED);
252 (* transport->vtable->messages_pending) (transport,
257 * Performs a single poll()/select() on the transport's file
258 * descriptors and then reads/writes data as appropriate,
259 * queueing incoming messages and sending outgoing messages.
260 * This is the backend for _dbus_connection_do_iteration().
261 * See _dbus_connection_do_iteration() for full details.
263 * @param transport the transport.
264 * @param flags indicates whether to read or write, and whether to block.
265 * @param timeout_milliseconds if blocking, timeout or -1 for no timeout.
268 _dbus_transport_do_iteration (DBusTransport *transport,
270 int timeout_milliseconds)
272 _dbus_assert (transport->vtable->do_iteration != NULL);
274 if ((flags & (DBUS_ITERATION_DO_WRITING |
275 DBUS_ITERATION_DO_READING)) == 0)
276 return; /* Nothing to do */
278 if (transport->disconnected)
280 _dbus_connection_transport_error (transport->connection,
281 DBUS_RESULT_DISCONNECTED);
285 (* transport->vtable->do_iteration) (transport, flags,
286 timeout_milliseconds);