#include <gio/gio.h>
#include <dbus/dbus.h>
-#include <dbus/dbus-glib-lowlevel.h>
+
+#include "test-utils.h"
typedef struct {
DBusError e;
+ TestMainContext *ctx;
DBusServer *server;
DBusConnection *server_conn;
g_assert (f->server_conn == NULL);
f->server_conn = dbus_connection_ref (server_conn);
- dbus_connection_setup_with_g_main (server_conn, NULL);
+ test_connection_setup (f->ctx, server_conn);
}
static void
setup (Fixture *f,
gconstpointer addr)
{
+ f->ctx = test_main_context_get ();
dbus_error_init (&f->e);
g_queue_init (&f->client_messages);
dbus_server_set_new_connection_function (f->server,
new_conn_cb, f, NULL);
- dbus_server_setup_with_g_main (f->server, NULL);
+ test_server_setup (f->ctx, f->server);
}
static void
dbus_server_get_address (f->server), &f->e);
assert_no_error (&f->e);
g_assert (f->client_conn != NULL);
- dbus_connection_setup_with_g_main (f->client_conn, NULL);
+ test_connection_setup (f->ctx, f->client_conn);
while (f->server_conn == NULL)
{
g_print (".");
- g_main_context_iteration (NULL, TRUE);
+ test_main_context_iterate (f->ctx, TRUE);
}
have_mem = dbus_connection_add_filter (f->client_conn,
while (g_queue_is_empty (&f->client_messages))
{
g_print (".");
- g_main_context_iteration (NULL, TRUE);
+ test_main_context_iterate (f->ctx, TRUE);
}
g_assert_cmpuint (g_queue_get_length (&f->client_messages), ==, 1);
dbus_message_unref (outgoing);
}
+static void
+send_n_bytes (GSocket *socket,
+ const gchar *blob,
+ gssize blob_len)
+{
+ gssize len, total_sent;
+ GError *gerror = NULL;
+
+ total_sent = 0;
+
+ while (total_sent < blob_len)
+ {
+ len = g_socket_send (socket,
+ blob + total_sent,
+ blob_len - total_sent,
+ NULL, &gerror);
+
+ /* this is NULL-safe: a NULL error does not match */
+ if (g_error_matches (gerror, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
+ {
+ /* we could wait for G_IO_OUT, but life's too short; just sleep */
+ g_clear_error (&gerror);
+ g_usleep (G_USEC_PER_SEC / 10);
+ continue;
+ }
+
+ g_assert_no_error (gerror);
+ g_assert (len >= 0);
+ total_sent += len;
+ }
+}
+
/* Enough bytes for it to be obvious that this connection is broken */
#define CORRUPT_LEN 1024
GSocket *socket;
GError *gerror = NULL;
int fd;
- gssize len, total_sent;
DBusMessage *incoming;
test_message (f, addr);
g_assert_no_error (gerror);
g_assert (socket != NULL);
- total_sent = 0;
-
- while (total_sent < CORRUPT_LEN)
- {
- len = g_socket_send_with_blocking (socket,
- not_a_dbus_message + total_sent, CORRUPT_LEN - total_sent,
- TRUE, NULL, &gerror);
- g_assert_no_error (gerror);
- g_assert (len >= 0);
- total_sent += len;
- }
+ send_n_bytes (socket, not_a_dbus_message, CORRUPT_LEN);
/* Now spin on the client connection: the server just sent it complete
* rubbish, so it should disconnect */
while (g_queue_is_empty (&f->client_messages))
{
g_print (".");
- g_main_context_iteration (NULL, TRUE);
+ test_main_context_iterate (f->ctx, TRUE);
}
incoming = g_queue_pop_head (&f->client_messages);
"/org/freedesktop/DBus/Local");
dbus_message_unref (incoming);
+
+ /* Free the DBusConnection before the GSocket, because GSocket is
+ * going to close our fd. GSocket tolerates closing an already-closed
+ * fd, whereas DBusLoop + DBusSocketSetEpoll doesn't. On Unix
+ * we could use dup() but that isn't portable to Windows :-(
+ */
+ dbus_connection_close (f->server_conn);
+ dbus_connection_unref (f->server_conn);
+ f->server_conn = NULL;
+
+ g_object_unref (socket);
}
static void
char *blob;
const gchar *arg = not_a_dbus_message;
const gchar * const *args = &arg;
- int blob_len, len, total_sent;
+ int blob_len;
DBusMessage *message;
dbus_bool_t mem;
g_assert_no_error (gerror);
g_assert (socket != NULL);
- total_sent = 0;
-
- while (total_sent < blob_len)
- {
- len = g_socket_send_with_blocking (socket, blob + total_sent,
- blob_len - total_sent, TRUE, NULL, &gerror);
- g_assert_no_error (gerror);
- g_assert (len >= 0);
- total_sent += len;
- }
+ send_n_bytes (socket, blob, blob_len);
dbus_free (blob);
while (g_queue_is_empty (&f->client_messages))
{
g_print (".");
- g_main_context_iteration (NULL, TRUE);
+ test_main_context_iterate (f->ctx, TRUE);
}
message = g_queue_pop_head (&f->client_messages);
"/org/freedesktop/DBus/Local");
dbus_message_unref (message);
+
+ /* Free the DBusConnection before the GSocket, as above. */
+ dbus_connection_close (f->server_conn);
+ dbus_connection_unref (f->server_conn);
+ f->server_conn = NULL;
+
+ g_object_unref (socket);
}
static void
dbus_server_unref (f->server);
f->server = NULL;
}
+
+ test_main_context_unref (f->ctx);
}
int